├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── ajax.php ├── class ├── class.bbstats.php ├── class.bugcrowd.php ├── class.cobalt.php ├── class.database.php ├── class.hackerone.php ├── class.platform.php ├── class.program.php ├── class.report.php ├── class.statistics.php ├── class.utils.php └── class.yogosha.php ├── config.php ├── css ├── awesome-bootstrap-checkbox.css ├── bootstrap-grid.min.css ├── bootstrap-reboot.min.css ├── bootstrap3.3.min.css ├── bootstrap4.0.min.css ├── custom.css ├── dataTables.bootstrap.min.css └── datatables.min.css ├── data-grabber.php ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.svg ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── graph ├── graph_bounties.php ├── graph_bounties_reports_reputation.php ├── graph_program_bounty.php ├── graph_program_evolution_rating.php ├── graph_program_evolution_severity.php ├── graph_program_times.php ├── graph_program_times2.php ├── graph_program_times_resolution.php ├── graph_program_times_triage.php ├── graph_reports_platforms_pie.php ├── graph_reports_programs_pie.php ├── graph_reports_ratings.php ├── graph_reports_ratings_pie.php ├── graph_reports_severity_pie.php ├── graph_reports_state_pie.php ├── graph_reports_tags_pie.php ├── graph_tags_evolution.php ├── top_program_best_hackers.php ├── top_program_best_spammers.php ├── top_programs.php └── top_tags.php ├── img ├── bountyfactory.png ├── bugcrowd.png ├── cc.png ├── cobalt.png ├── hackerone.png ├── sample-bounty.png ├── sample-evolution.png ├── sample-grabber.png ├── sample-listing.png ├── sample-program-repartition.png ├── sample-report-rating.png ├── stop.png ├── unknown.png └── yogosha.png ├── include ├── filters_form.php ├── hacker_infos.php ├── listing.php ├── popup_about.php ├── popup_more.php ├── popup_report_add.php ├── popup_report_edit.php ├── popup_tag_add.php ├── program_infos.php ├── program_listing.php └── program_reports.php ├── index.php ├── js ├── bootstrap.min.js ├── dataTables.bootstrap.min.js ├── highcharts.src.min.js ├── jquery.dataTables.min.js └── jquery.min.js ├── program.php ├── quh1.sh ├── quick-init.sh └── quick-update.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [gwen001] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | data/*db* 2 | data/*html* 3 | data/*json* 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Gwendal Le Coguic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

BBStats

2 | 3 |

A tool that display stats and graphs about your bug bounty activity.

4 | 5 |

6 | php badge 7 | MIT license badge 8 | twitter badge 9 |

10 | 11 | 16 | 17 | --- 18 | 19 | ## Requirements 20 | 21 | A web server with PHP installed and Curl extension enabled. 22 | 23 | Put the code at the root of your web server: 24 | ``` 25 | git clone https://github.com/gwen001/BBstats 26 | ``` 27 | 28 | ## Auth 29 | 30 | Set environment variable `HACKERONE_USERNAME` and `HACKERONE_PASSWORD` 31 | 32 | ## Recommended usage 33 | 34 | Grab the datas from your favorite platform for the first time: *quick-init.sh* 35 | ``` 36 | php data-grabber.php -p hackerone -a n -rr -tt -e 37 | ``` 38 | 39 | Or update your current database (once a week for example): *quick-update.sh* 40 | ``` 41 | php data-grabber.php -p hackerone -a u -r -t -e -n 50 42 | ``` 43 | 44 | Enjoy the stats! 45 | ``` 46 | firefox http://127.0.0.1/BBstats/ 47 | ``` 48 | 49 | ## Grabber 50 | 51 | 52 | ``` 53 | Usage: php data-grabber.php -p [OPTIONS] 54 | 55 | Options: 56 | -a action to perform (default=N) 57 | N: new, add new reports 58 | U: update, add new reports and update the existing ones (title, bounty, state) 59 | O: overwrite, add new reports and overwrite the existing ones 60 | R: rollback, got back the previous last version of the database (not platform dependant) 61 | -e grab reputation as well 62 | -f import from file 63 | -g import program datas 64 | -h print this help 65 | -n update/overwrite the last n reports (default=all, only recommended for the first init) 66 | -p platform to grab datas (available: hackerone) 67 | -r try to auto rate the reports but keep the current value if exists 68 | -rr try to auto rate the reports and overwrite the current value 69 | -t try to auto tag the reports but merge the current tags if exists 70 | -tt try to auto tag the reports and overwrite the current tags 71 | 72 | Examples: 73 | php data-grabber.php -p hackerone -a n 74 | php data-grabber.php -p hackerone -a u -n 50 75 | php data-grabber.php -p hackerone -a o -rr -tt -e 76 | php data-grabber.php -p hackerone -f bounties.csv -r -t 77 | php data-grabber.php -p hackerone -a r 78 | ``` 79 | 80 | 81 | ## Web 82 | You can choose which graph you want to display in `config.php`. 83 | You create your own autotag and autorate configuration in `config.php`. 84 | 85 | ## Todo 86 | 87 | __grabber__ 88 | - add more platform (Bugcrowd, YesWeHack, Intigriti, Synack...) 89 | 90 | __db__ 91 | - ? 92 | 93 | __web ui__ 94 | - search engine filter: with/without bounty 95 | - scrollbar fot both part, left and right 96 | - calendar plugin for dates 97 | 98 | __graph__ 99 | - graph: bounties per month per program 100 | - graph: bounties per month per type 101 | - graph: bounties per month per platform 102 | - graph: reports per month per program 103 | - graph: reports per month per type 104 | - graph: reports per month per platform 105 | - graph: reports per status 106 | 107 | __bugs__ 108 | - probably alot! 109 | 110 | --- 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 |
Grabber
Listing
BountiesEvolution
Reports ratingProgram repartition
129 | 130 | --- 131 | 132 | Feel free to [open an issue](/../../issues/) if you have any problem with the script. 133 | 134 | -------------------------------------------------------------------------------- /ajax.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 13 | exit( 'Cannot load database, you should run the grabber first!' ); 14 | } 15 | 16 | 17 | if( $_POST['_a'] == 'graph-reload' && isset($_POST['graph']) ) 18 | { 19 | $datas = null; 20 | 21 | switch( $_POST['graph'] ) { 22 | case 'bounties': 23 | $datas = Statistics::bounties( $db ); 24 | break; 25 | case 'bounties-reports': 26 | $datas = Statistics::bounties_reports_evolution( $db ); 27 | break; 28 | case 'reports-program-pie': 29 | $datas = Statistics::reports_program_pie( $db ); 30 | break; 31 | case 'reports-tag-pie': 32 | $datas = Statistics::reports_tags_pie( $db ); 33 | break; 34 | case 'reports-platform-pie': 35 | $datas = Statistics::reports_platform_pie( $db ); 36 | break; 37 | case 'reports-state-pie': 38 | $datas = Statistics::reports_state_pie( $db ); 39 | break; 40 | case 'reports-rating': 41 | $datas = Statistics::reports_rating( $db ); 42 | break; 43 | case 'reports-rating-pie': 44 | $datas = Statistics::reports_rating_pie( $db ); 45 | break; 46 | case 'top-programs': 47 | $datas = Statistics::top_program( $db ); 48 | break; 49 | case 'top-tags': 50 | $datas = Statistics::top_tags( $db ); 51 | break; 52 | case 'top-programs-html': 53 | $datas = json_encode( Statistics::top_program_html($db) ); 54 | break; 55 | case 'top-tags-html': 56 | $datas = json_encode( Statistics::top_tags_html($db) ); 57 | break; 58 | } 59 | 60 | if( !is_null($datas) ) { 61 | echo $datas; 62 | } 63 | exit(); 64 | 65 | } 66 | 67 | 68 | if( $_POST['_a'] == 'report-get' ) 69 | { 70 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 71 | exit(); 72 | } 73 | 74 | $report = $db->getReport( $key ); 75 | if( !$report ) { 76 | exit(); 77 | } 78 | 79 | $report->total_bounty = $report->getTotalBounty(); 80 | $report->str_tags = $report->getTags( true ); 81 | $report->setCreatedAt( date('Y/m/d',$report->getCreatedAt()) ); 82 | echo json_encode( $report ); 83 | exit(); 84 | } 85 | 86 | 87 | if( $_POST['_a'] == 'report-add' ) 88 | { 89 | $report = new Report(); 90 | $report->setManual( true ); 91 | 92 | if( isset($_POST['id']) ) { 93 | $report->setId( trim($_POST['id']) ); 94 | } else { 95 | $report->setId( uniqid() ); 96 | } 97 | if( isset($_POST['platform']) ) { 98 | $report->setPlatform( trim($_POST['platform']) ); 99 | } 100 | if( isset($_POST['rating']) ) { 101 | $report->setRating( trim($_POST['rating']) ); 102 | } 103 | if( isset($_POST['state']) && in_array($_POST['state'],Report::T_STATE) ) { 104 | $report->setState( $_POST['state'] ); 105 | } 106 | if( isset($_POST['title']) ) { 107 | $report->setTitle( trim($_POST['title']) ); 108 | } 109 | if( isset($_POST['program']) ) { 110 | $report->setProgram( trim($_POST['program']) ); 111 | } 112 | if( isset($_POST['created_at']) ) { 113 | $report->setCreatedAt( strtotime(trim($_POST['created_at'])) ); 114 | } 115 | if( isset($_POST['bounty']) ) { 116 | $report->setManualBounty( (int)$_POST['bounty'] ); 117 | } 118 | if( isset($_POST['tags']) ) { 119 | if( trim($_POST['tags']) == '' ) { 120 | $report->setTags( [] ); 121 | } else { 122 | $report->setTags( explode(',',trim($_POST['tags'],', ')) ); 123 | } 124 | } 125 | 126 | $key = Report::generateKey( $report->getPlatform(), $report->getProgram(), $report->getId() ); 127 | 128 | $db->addReport( $key, $report ); 129 | $db->save(); 130 | exit(); 131 | } 132 | 133 | 134 | if( $_POST['_a'] == 'report-edit' ) 135 | { 136 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 137 | exit(); 138 | } 139 | 140 | $report = $db->getReport( $key ); 141 | if( !$report ) { 142 | exit(); 143 | } 144 | 145 | if( isset($_POST['id']) && $report->getManual() ) { 146 | $report->setId( trim($_POST['id']) ); 147 | } 148 | if( isset($_POST['platform']) && $report->getManual() ) { 149 | $report->setPlatform( trim($_POST['platform']) ); 150 | } 151 | if( isset($_POST['rating']) ) { 152 | $report->setRating( trim($_POST['rating']) ); 153 | } 154 | if( isset($_POST['state']) && in_array($_POST['state'],Report::T_STATE) && $report->getManual() ) { 155 | $report->setState( $_POST['state'] ); 156 | } 157 | if( isset($_POST['title']) && $report->getManual() ) { 158 | $report->setTitle( trim($_POST['title']) ); 159 | } 160 | if( isset($_POST['program']) && $report->getManual() ) { 161 | $report->setProgram( trim($_POST['program']) ); 162 | } 163 | if( isset($_POST['bounty']) && $report->getManual() ) { 164 | $b = (int)$_POST['bounty']; 165 | if( $b != $report->getTotalBounty() ) { 166 | $report->setManualBounty( $b ); 167 | } 168 | } 169 | if( isset($_POST['tags']) ) { 170 | if( trim($_POST['tags']) == '' ) { 171 | $report->setTags( [] ); 172 | } else { 173 | $report->setTags( explode(',',trim($_POST['tags'],', ')) ); 174 | } 175 | } 176 | if( isset($_POST['created_at']) && $report->getManual() ) { 177 | $report->setCreatedAt( strtotime(trim($_POST['created_at'])) ); 178 | } 179 | 180 | $db->setReport( $key, $report ); 181 | $db->save(); 182 | exit(); 183 | } 184 | 185 | 186 | if( $_POST['_a'] == 'report-unignore' ) 187 | { 188 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 189 | exit(); 190 | } 191 | 192 | $report = $db->getReport( $key ); 193 | if( !$report ) { 194 | exit(); 195 | } 196 | 197 | $report->unignore(); 198 | 199 | $db->setReport( $key, $report ); 200 | $db->save(); 201 | exit(); 202 | } 203 | 204 | 205 | if( $_POST['_a'] == 'report-ignore' ) 206 | { 207 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 208 | exit(); 209 | } 210 | 211 | $report = $db->getReport( $key ); 212 | if( !$report ) { 213 | exit(); 214 | } 215 | 216 | $report->ignore(); 217 | //var_dump($report); 218 | 219 | $db->setReport( $key, $report ); 220 | $db->save(); 221 | exit(); 222 | } 223 | 224 | 225 | if( $_POST['_a'] == 'report-delete' ) 226 | { 227 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 228 | exit(); 229 | } 230 | 231 | $report = $db->getReport( $key ); 232 | if( !$report ) { 233 | exit(); 234 | } 235 | 236 | $db->deleteReport( $key ); 237 | $db->save(); 238 | exit(); 239 | } 240 | 241 | 242 | if( $_POST['_a'] == 'tag-add' ) 243 | { 244 | if( !isset($_POST['key']) || ($key=trim($_POST['key']))=='' ) { 245 | exit(); 246 | } 247 | 248 | $report = $db->getReport( $key ); 249 | if( !$report ) { 250 | exit(); 251 | } 252 | 253 | if( !isset($_POST['tag']) || ($tags=trim($_POST['tag']))=='' ) { 254 | exit(); 255 | } 256 | 257 | $report->setTags( explode(',',trim($_POST['tag'],', ')) ); 258 | 259 | $db->setReport( $key, $report ); 260 | $db->save(); 261 | exit(); 262 | } 263 | 264 | 265 | exit( '-1' ); 266 | -------------------------------------------------------------------------------- /class/class.bbstats.php: -------------------------------------------------------------------------------- 1 | database; 25 | } 26 | public function setDatabase( $v ) { 27 | $this->database = $v; 28 | return true; 29 | } 30 | 31 | 32 | private $platform = ''; 33 | 34 | public function getPlatform() { 35 | return $this->platform; 36 | } 37 | public function setPlatform( $v ) { 38 | $this->platform = trim( $v ); 39 | return true; 40 | } 41 | 42 | 43 | private $program = ''; 44 | 45 | public function getProgram() { 46 | return $this->program; 47 | } 48 | public function setProgram( $v ) { 49 | $this->program = trim( $v ); 50 | return true; 51 | } 52 | 53 | 54 | private $source_file = null; 55 | private $is_import = false; 56 | 57 | public function isImport() { 58 | return $this->is_import; 59 | } 60 | public function getSourceFile() { 61 | return $this->source_file; 62 | } 63 | public function setSourceFile( $v ) { 64 | $f = trim( $v ); 65 | if( !is_file($f) ) { 66 | return false; 67 | } 68 | $this->is_import = true; 69 | $this->source_file = $f; 70 | return true; 71 | } 72 | 73 | 74 | private $action = 'n'; // new 75 | 76 | public function getAction() { 77 | return $this->action; 78 | } 79 | public function setAction( $v ) 80 | { 81 | $action = strtolower( trim($v) ); 82 | switch( $action ) { 83 | case 'n': 84 | break; 85 | case 'o': 86 | break; 87 | case 'r': 88 | break; 89 | case 'u': 90 | $this->allowUpdate(); 91 | $this->disallowOverwrite(); 92 | break; 93 | default: 94 | return false; 95 | } 96 | $this->action = $v; 97 | return true; 98 | } 99 | 100 | 101 | private $allow_update = false; 102 | 103 | public function updateAllowed() { 104 | return $this->allow_update; 105 | } 106 | private function allowUpdate() { 107 | $this->allow_update = true; 108 | } 109 | 110 | private $allow_overwrite = true; 111 | 112 | public function overwriteAllowed() { 113 | return $this->allow_overwrite; 114 | } 115 | private function disallowOverwrite() { 116 | $this->allow_overwrite = false; 117 | } 118 | 119 | 120 | private $demo = false; 121 | 122 | public function isDemo() { 123 | return $this->demo; 124 | } 125 | public function enableDemoMode() { 126 | $this->demo = true; 127 | } 128 | 129 | 130 | private $quantity = 2147483647; 131 | 132 | public function getQuantity() { 133 | return $this->quantity; 134 | } 135 | public function setQuantity( $v ) { 136 | $v = (int)$v; 137 | if( $v > 0 ) { 138 | $this->quantity = $v; 139 | } 140 | return true; 141 | } 142 | 143 | 144 | private $autotag = 0; 145 | 146 | public function getAutoTagMode() { 147 | return $this->autotag; 148 | } 149 | public function setAutoTagMode( $v ) { 150 | $this->autotag = (int)$v; 151 | return true; 152 | } 153 | 154 | 155 | private $autorate = 0; 156 | 157 | public function getAutoRateMode() { 158 | return $this->autorate; 159 | } 160 | public function setAutoRateMode( $v ) { 161 | $this->autorate = (int)$v; 162 | return true; 163 | } 164 | 165 | 166 | private $reputation = false; 167 | 168 | public function isReputation() { 169 | return $this->reputation; 170 | } 171 | public function enableReputation() { 172 | $this->reputation = true; 173 | } 174 | 175 | } 176 | -------------------------------------------------------------------------------- /class/class.bugcrowd.php: -------------------------------------------------------------------------------- 1 | setName( 'bugcrowd' ); 8 | } 9 | 10 | 11 | public function login() 12 | { 13 | $this->username = getenv( 'BUGCROWD_USERNAME' ); 14 | $this->password = getenv( 'BUGCROWD_PASSWORD' ); 15 | 16 | if( !$this->username || !$this->password ) { 17 | Utils::printError( 'Credentials not found!' ); 18 | return false; 19 | } 20 | 21 | return true; 22 | } 23 | 24 | 25 | public function connect() 26 | { 27 | $this->cookie_file = tempnam( '/tmp', 'cook_' ); 28 | 29 | $c = curl_init(); 30 | curl_setopt( $c, CURLOPT_URL, 'https://bugcrowd.com/user/sign_in' ); 31 | curl_setopt( $c, CURLOPT_TIMEOUT, 15 ); 32 | curl_setopt( $c, CURLOPT_FOLLOWLOCATION, false ); 33 | curl_setopt( $c, CURLOPT_COOKIEJAR, $this->cookie_file ); 34 | curl_setopt( $c, CURLOPT_COOKIEFILE, $this->cookie_file ); 35 | curl_setopt( $c, CURLOPT_RETURNTRANSFER, true ); 36 | curl_setopt( $c, CURLOPT_HTTPHEADER, ['User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0'] ); 37 | $data = curl_exec($c ); 38 | $t_info = curl_getinfo( $c ); 39 | //echo $data; 40 | //var_dump( $t_info['http_code'] ); 41 | //$data = file_get_contents( 'data/bc_signin.html' ); 42 | 43 | if( !$data || $t_info['http_code']!=200 ) { 44 | return -1; 45 | } 46 | 47 | $m = preg_match( '##', $data, $t_match ); 48 | var_dump( $t_match ); 49 | if( !$m ) { 50 | return -2; 51 | } 52 | 53 | $this->csrf_token = $t_match[1]; 54 | 55 | $c = curl_init(); 56 | curl_setopt( $c, CURLOPT_URL, 'https://bugcrowd.com/user/sign_in' ); 57 | curl_setopt( $c, CURLOPT_TIMEOUT, 15 ); 58 | curl_setopt( $c, CURLOPT_FOLLOWLOCATION, true ); 59 | curl_setopt( $c, CURLOPT_COOKIEJAR, $this->cookie_file ); 60 | curl_setopt( $c, CURLOPT_COOKIEFILE, $this->cookie_file ); 61 | curl_setopt( $c, CURLOPT_RETURNTRANSFER, true ); 62 | curl_setopt( $c, CURLOPT_HTTPHEADER, ['User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0'] ); 63 | curl_setopt( $c, CURLOPT_POST, true ); 64 | curl_setopt( $c, CURLOPT_POSTFIELDS, 'utf8=%E2%9C%93&authenticity_token='.urlencode($this->csrf_token).'&user%5Bredirect_to%5D=&user%5Bemail%5D='.urlencode($this->username).'&user%5Bpassword%5D='.urlencode($this->password).'&commit=Log+in' ); 65 | $data = curl_exec($c ); 66 | $t_info = curl_getinfo( $c ); 67 | //echo $data; 68 | //var_dump( $t_info['http_code'] ); 69 | //$data = file_get_contents( 'data/bc_signin.html' ); 70 | 71 | if( !$data || $t_info['http_code']!=200 ) { 72 | return -3; 73 | } 74 | 75 | return true; 76 | } 77 | 78 | 79 | public function grabReportList( $quantity ) 80 | { 81 | $c = curl_init(); 82 | curl_setopt( $c, CURLOPT_URL, 'https://bugcrowd.com/submissions' ); 83 | curl_setopt( $c, CURLOPT_TIMEOUT, 15 ); 84 | curl_setopt( $c, CURLOPT_FOLLOWLOCATION, true ); 85 | curl_setopt( $c, CURLOPT_COOKIEJAR, $this->cookie_file ); 86 | curl_setopt( $c, CURLOPT_COOKIEFILE, $this->cookie_file ); 87 | curl_setopt( $c, CURLOPT_RETURNTRANSFER, true ); 88 | curl_setopt( $c, CURLOPT_HTTPHEADER, ['User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0'] ); 89 | $data = curl_exec($c ); 90 | $t_info = curl_getinfo( $c ); 91 | //echo $data; 92 | //var_dump( $t_info['http_code'] ); 93 | //file_put_contents( 'data/bc_submission.html', $data ); 94 | //$data = file_get_contents( 'data/bc_submission.html' ); 95 | 96 | if( !$data || $t_info['http_code']!=200 ) { 97 | return false; 98 | } 99 | 100 | $m = preg_match( '#
#', $data, $t_match ); 101 | //var_dump( $t_match ); 102 | $t_data = json_decode( html_entity_decode( urldecode( $t_match[1] ) ), true ); 103 | 104 | // deal with pages 105 | { 106 | $this->t_bugs = array_merge( $this->t_bugs, $t_data['submissions'] ); 107 | Utils::_print( '.', 'white' ); 108 | $n_page = 1; 109 | } 110 | 111 | return $n_page; 112 | } 113 | 114 | 115 | protected function grabReportListFromFile( $quantity ) 116 | { 117 | } 118 | 119 | 120 | public function grabReports( $quantity, $t_reputation ) 121 | { 122 | $bbstats = BBstats::getInstance(); 123 | $db = $bbstats->getDatabase(); 124 | 125 | for( $n=0 ; $n<$quantity && list($k,$bug)=each($this->t_bugs) ; $n++ ) 126 | { 127 | $report_id = $bug['reference_number']; 128 | $key = Report::generateKey( $this->getName(), $bug['program_name'], $report_id ); 129 | 130 | if( !$db->exists($key) || $bbstats->updateAllowed() || $bbstats->overwriteAllowed() ) 131 | { 132 | $report = array_merge( $bug, $this->grabReport($report_id) ); 133 | $this->t_reports[$key] = $report; 134 | } 135 | } 136 | 137 | echo "\n"; 138 | 139 | return count($this->t_reports); 140 | } 141 | 142 | 143 | public function grabReportsFromFile( $quantity, $t_reputation ) 144 | { 145 | } 146 | 147 | 148 | protected function grabReport( $report_id ) 149 | { 150 | $c = curl_init(); 151 | curl_setopt( $c, CURLOPT_URL, 'https://bugcrowd.com/submissions/'.$report_id ); 152 | curl_setopt( $c, CURLOPT_TIMEOUT, 15 ); 153 | curl_setopt( $c, CURLOPT_FOLLOWLOCATION, true ); 154 | curl_setopt( $c, CURLOPT_COOKIEJAR, $this->cookie_file ); 155 | curl_setopt( $c, CURLOPT_COOKIEFILE, $this->cookie_file ); 156 | curl_setopt( $c, CURLOPT_RETURNTRANSFER, true ); 157 | curl_setopt( $c, CURLOPT_HTTPHEADER, ['User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0'] ); 158 | $data = curl_exec($c ); 159 | $t_info = curl_getinfo( $c ); 160 | //echo $data; 161 | //var_dump( $t_info['http_code'] ); 162 | //file_put_contents( 'data/'.$report_id.'.html', $data ); 163 | //$data = file_get_contents( 'data/'.$report_id.'.html' ); 164 | 165 | if( !$data || $t_info['http_code']!=200 ) { 166 | Utils::_print( '.', 'dark_grey' ); 167 | return false; 168 | } 169 | 170 | Utils::_print( '.', 'white' ); 171 | 172 | $m = preg_match( '#
#', $data, $t_match ); 173 | //var_dump( $t_match ); 174 | $t_user = json_decode( html_entity_decode( urldecode( $t_match[1] ) ), true ); 175 | 176 | $m = preg_match( '#
#', $data, $t_match ); 177 | //var_dump( $t_match ); 178 | $t_data = json_decode( html_entity_decode( urldecode( $t_match[1] ) ), true ); 179 | 180 | return array_merge( $t_user, $t_data ); 181 | } 182 | 183 | 184 | protected function grabReportFromFile( $report_id ) 185 | { 186 | } 187 | 188 | 189 | public function extractReportDatas() 190 | { 191 | foreach( $this->t_reports as $key=>$report ) 192 | { 193 | $t = []; 194 | 195 | $r = new Report(); 196 | $r->setPlatform( $this->getName() ); 197 | $r->setId( $report['reference_number'] ); 198 | $r->setReporter( $report['username'] ); 199 | $r->setTitle( $report['caption'] ); 200 | $r->setCreatedAt( strtotime($report['created_at']) ); 201 | $r->setProgram( $report['program_name'] ); 202 | $r->setState( $report['substate'] ); 203 | $r->addReputation( strtotime($report['created_at']), (int)$report['points'] ); 204 | 205 | foreach( $report['activities'] as $activity ) 206 | { 207 | switch( $activity['key'] ) 208 | { 209 | /*case 'submission.created': 210 | $r->setCreatedAt( strtotime($activity['created_at']) ); 211 | break;*/ 212 | /*case 'point_reward.created': 213 | $r->addReputation( $activity['created_at'], (int)$activity['params']['amount'] ); 214 | break;*/ 215 | case 'submission.updated': 216 | case 'submission.vrt_updated': 217 | if( (int)$activity['params']['priority'] ) { 218 | $r->setRating( (int)$activity['params']['priority'] ); 219 | } 220 | break; 221 | case 'submission.reward_created': 222 | $bounty_amount = str_replace( '$', '', $activity['params']['amount'] ); 223 | $r->addBounty( strtotime($activity['created_at']), $bounty_amount ); 224 | if( !$r->getFirstBountyDate() ) { 225 | $r->setFirstBountyDate( strtotime($activity['created_at']) ); 226 | } 227 | break; 228 | case 'tester_message.created': 229 | if( $activity['actor']['name'] != $report['username'] ) { 230 | $r->setFirstResponseDate( strtotime($activity['created_at']) ); 231 | } 232 | break; 233 | case 'submission.transitioned': 234 | if( $activity['params']['substate'] == 'triaged' ) { 235 | $r->setTriageDate( strtotime($activity['created_at']) ); 236 | } 237 | break; 238 | case 'submission.transitioned': 239 | if( $activity['params']['substate'] == 'resolved' ) { 240 | $r->setResolutionDate( strtotime($activity['created_at']) ); 241 | } 242 | break; 243 | } 244 | } 245 | 246 | $this->t_reports_final[ $key ] = $r; 247 | } 248 | } 249 | 250 | 251 | public static function getReportLink( $report_id ) { 252 | return 'https://bugcrowd.com/submissions/'.$report_id; 253 | } 254 | 255 | 256 | public function grabReputation() 257 | { 258 | return true; 259 | } 260 | 261 | 262 | public function grabReputationFromFile() 263 | { 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /class/class.cobalt.php: -------------------------------------------------------------------------------- 1 | setName( 'cobalt' ); 7 | } 8 | 9 | 10 | public function login() 11 | { 12 | } 13 | 14 | 15 | public function connect() 16 | { 17 | } 18 | 19 | 20 | public function grabReportList( $quantity ) 21 | { 22 | } 23 | 24 | 25 | protected function grabReportListFromFile( $quantity ) 26 | { 27 | } 28 | 29 | 30 | public function grabReports( $quantity, $t_reputation ) 31 | { 32 | } 33 | 34 | 35 | public function grabReportsFromFile( $quantity, $t_reputation ) 36 | { 37 | } 38 | 39 | 40 | protected function grabReport( $report_id ) 41 | { 42 | } 43 | 44 | 45 | protected function grabReportFromFile( $report_id ) 46 | { 47 | } 48 | 49 | 50 | public function extractReportDatas() 51 | { 52 | } 53 | 54 | 55 | public static function getReportLink( $report_id ) { 56 | return 'https://app.cobalt.io/godaddy/godaddy-beta/reports/'.$report_id; 57 | } 58 | 59 | 60 | public function grabReputation() 61 | { 62 | } 63 | 64 | 65 | public function grabReputationFromFile() 66 | { 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /class/class.platform.php: -------------------------------------------------------------------------------- 1 | t_reports_final; 17 | } 18 | public function setReportsFinal( $t_reports ) { 19 | $this->t_reports_final = $t_reports; 20 | return true; 21 | } 22 | 23 | 24 | private $name = ''; 25 | 26 | public function getName() { 27 | return $this->name; 28 | } 29 | protected function setName( $v ) { 30 | $this->name = strtolower( trim($v) ); 31 | return true; 32 | } 33 | 34 | 35 | // ask for login/password/credentials 36 | abstract public function login(); 37 | 38 | // connect to the platform 39 | abstract public function connect(); 40 | 41 | // grab reports list from the concerned platform 42 | abstract public function grabReportList( $quantity ); 43 | 44 | // grab reports list from import file 45 | abstract protected function grabReportListFromFile( $quantity ); 46 | 47 | // grab reports from the concerned platform 48 | abstract public function grabReports( $quantity, $t_reputation ); 49 | 50 | // grab reports from import file 51 | abstract public function grabReportsFromFile( $quantity, $t_reputation ); 52 | 53 | // grab reports from the concerned platform 54 | abstract protected function grabReport( $report_id ); 55 | 56 | // grab reports from import file 57 | abstract protected function grabReportFromFile( $report_id ); 58 | 59 | // get reputation datas the concerned platform 60 | abstract public function grabReputation(); 61 | 62 | // get reputation datas from import file 63 | abstract public function grabReputationFromFile(); 64 | 65 | // extract datas form previously grabbed reports datas 66 | abstract public function extractReportDatas(); 67 | 68 | // return direct link to a report 69 | abstract public static function getReportLink( $report_id ); 70 | } 71 | -------------------------------------------------------------------------------- /class/class.program.php: -------------------------------------------------------------------------------- 1 | setId( $o_infos->id ); 25 | $this->setName( $o_infos->name ); 26 | $this->setHandle( $o_infos->handle ); 27 | $this->setUrl( $o_infos->url ); 28 | $this->setProfilePicture( $o_infos->profile_picture_urls->small ); 29 | 30 | return true; 31 | } 32 | 33 | 34 | private $platform = ''; 35 | 36 | public function getPlatform() { 37 | return $this->platform; 38 | } 39 | public function setPlatform( $v ) { 40 | $this->platform = trim( $v ); 41 | return true; 42 | } 43 | 44 | private $id = ''; 45 | 46 | public function getId() { 47 | return $this->id; 48 | } 49 | public function setId( $v ) { 50 | $this->id = $v; 51 | return true; 52 | } 53 | 54 | 55 | private $name = ''; 56 | 57 | public function getName() { 58 | return $this->name; 59 | } 60 | public function setName( $v ) { 61 | $this->name = trim( $v ); 62 | return true; 63 | } 64 | 65 | 66 | private $handle = ''; 67 | private $db_file = null; 68 | 69 | public function getHandle() { 70 | return $this->handle; 71 | } 72 | public function setHandle( $v ) { 73 | $this->handle = trim( $v ); 74 | $this->db_file = self::getBackupFile( $this->handle ); 75 | return true; 76 | } 77 | 78 | 79 | private $url = ''; 80 | 81 | public function getUrl() { 82 | return $this->url; 83 | } 84 | public function setUrl( $v ) { 85 | $this->url = trim( $v ); 86 | return true; 87 | } 88 | 89 | 90 | private $profile_picture = ''; 91 | 92 | public function getProfilePicture() { 93 | return $this->profile_picture; 94 | } 95 | public function setProfilePicture( $v ) { 96 | $this->profile_picture = trim( $v ); 97 | return true; 98 | } 99 | 100 | 101 | private $total_report = ''; 102 | 103 | public function getTotalReport() { 104 | return $this->total_report; 105 | } 106 | public function setTotalReport( $v ) { 107 | $this->total_report = (int)$v; 108 | return true; 109 | } 110 | 111 | 112 | private $total_bounty = ''; 113 | 114 | public function getTotalBounty() { 115 | return $this->total_bounty; 116 | } 117 | public function setTotalBounty( $v ) { 118 | $this->total_bounty = (int)$v; 119 | return true; 120 | } 121 | 122 | 123 | private $average_bounty = ''; 124 | 125 | public function getAverageBounty() { 126 | return $this->average_bounty; 127 | } 128 | public function setAverageBounty( $v ) { 129 | $this->average_bounty = $v; 130 | return true; 131 | } 132 | 133 | 134 | private $smallest_bounty_id = ''; 135 | 136 | public function getSmallestBountyId() { 137 | return $this->smallest_bounty_id; 138 | } 139 | public function setSmallestBountyId( $v ) { 140 | $this->smallest_bounty_id = $v; 141 | return true; 142 | } 143 | public function getSmallestBounty() { 144 | $id = $this->getSmallestBountyId(); 145 | if( !$id || !($r=$this->getReport($id)) ) { 146 | return false; 147 | } 148 | return $r->getTotalBounty(); 149 | } 150 | 151 | 152 | private $higher_bounty_id = ''; 153 | 154 | public function getHigherBountyId() { 155 | return $this->higher_bounty_id; 156 | } 157 | public function setHigherBountyId( $v ) { 158 | $this->higher_bounty_id = $v; 159 | return true; 160 | } 161 | public function getHigherBounty() { 162 | $id = $this->getHigherBountyId(); 163 | if( !$id || !($r=$this->getReport($id)) ) { 164 | return false; 165 | } 166 | return $r->getTotalBounty(); 167 | } 168 | 169 | 170 | private $bounty_range = null; 171 | 172 | public function getBountyRange() { 173 | return $this->bounty_range; 174 | } 175 | public function setBountyRange( $v ) { 176 | $this->bounty_range = $v; 177 | return true; 178 | } 179 | 180 | 181 | public function getBountiesByMonth( $month ) { 182 | $n = 0; 183 | foreach( $this->reports as $r ) { 184 | if( date('m/Y',$r->getCreatedAt()) == $month ) { 185 | $n += $r->getTotalBounty(); 186 | } 187 | } 188 | return $n; 189 | } 190 | 191 | 192 | private $first_report_id = ''; 193 | 194 | public function getFirstReportId() { 195 | return $this->first_report_id; 196 | } 197 | public function setFirstReportId( $v ) { 198 | $this->first_report_id = $v; 199 | return true; 200 | } 201 | public function getFirstReportDate() { 202 | $id = $this->getFirstReportId(); 203 | if( !$id || !($r=$this->getReport($id)) ) { 204 | return false; 205 | } 206 | return $r->getCreatedAt(); 207 | } 208 | 209 | 210 | private $last_report_id = ''; 211 | 212 | public function getLastReportId() { 213 | return $this->last_report_id; 214 | } 215 | public function setLastReportId( $v ) { 216 | $this->last_report_id = $v; 217 | return true; 218 | } 219 | public function getLastReportDate() { 220 | $id = $this->getLastReportId(); 221 | if( !$id || !($r=$this->getReport($id)) ) { 222 | return false; 223 | } 224 | return $r->getCreatedAt(); 225 | } 226 | 227 | 228 | public static function getBackupFile( $handle ) { 229 | return DATABASE_PATH.'/'.$handle.'.json'; 230 | } 231 | 232 | 233 | private $reports = null; 234 | 235 | public function getReport( $key ) { 236 | if( isset($this->reports[$key]) ) { 237 | return $this->reports[$key]; 238 | } 239 | return false; 240 | } 241 | public function getReports() { 242 | return $this->reports; 243 | } 244 | public function getReportsByMonth( $month ) { 245 | $n = 0; 246 | foreach( $this->reports as $r ) { 247 | if( date('m/Y',$r->getCreatedAt()) == $month ) { 248 | $n++; 249 | } 250 | } 251 | return $n; 252 | } 253 | public function setReports( $v ) { 254 | $this->reports = $v; 255 | return true; 256 | } 257 | 258 | 259 | private $hacktivity = null; 260 | 261 | public function getHacktivity() { 262 | return $this->hacktivity; 263 | } 264 | public function computeHacktivity( $t_reports ) 265 | { 266 | $t_hacktivity = []; 267 | 268 | foreach( $t_reports as $r ) 269 | { 270 | $id = is_numeric($r['id']) ? $r['id'] : md5(uniqid(true)); 271 | 272 | $tmp = new Report(); 273 | $tmp->setId( $id ); 274 | $tmp->setReporter( $r['reporter']['username'] ); 275 | $tmp->setPlatform( $this->platform ); 276 | $tmp->setTitle( isset($r['title']) ? $r['title'] : '' ); 277 | $ttt = explode( 'T', $r['latest_disclosable_activity_at'] ); 278 | $tmp->setCreatedAt( strtotime($ttt[0]) ); 279 | 280 | if( $r['bounty_disclosed'] && isset($r['total_awarded_bounty_amount']) ) { 281 | $r['total_awarded_bounty_amount'] = (int)$r['total_awarded_bounty_amount']; 282 | } else { 283 | $r['total_awarded_bounty_amount'] = 0; 284 | } 285 | $tmp->addBounty( $tmp->getCreatedAt(), $r['total_awarded_bounty_amount'] ) ; 286 | 287 | $t_hacktivity[ $id ] = $tmp; 288 | } 289 | 290 | $this->hacktivity = $t_hacktivity; 291 | 292 | return count($this->hacktivity); 293 | } 294 | 295 | 296 | 297 | public static function load( $handle ) 298 | { 299 | $handle = trim( $handle ); 300 | $db_file = self::getBackupFile( $handle ); 301 | if( is_null($db_file) || !is_file($db_file) ) { 302 | return false; 303 | } 304 | 305 | $datas = file_get_contents( $db_file ); 306 | if( $datas === false ) { 307 | return false; 308 | } 309 | 310 | if( strlen($datas) ) 311 | { 312 | $program = json_decode( $datas ); 313 | $program = Utils::array2object( $program, 'Program' ); 314 | $program->bounty_range = (array)$program->bounty_range; 315 | 316 | $program->hacktivity = (array)$program->hacktivity; 317 | foreach( $program->hacktivity as $k=>$v ) { 318 | $program->hacktivity[ $k ] = Utils::array2object( $v, 'Report' ); 319 | } 320 | 321 | $program->reports = (array)$program->reports; 322 | foreach( $program->reports as $k=>$v ) { 323 | $program->reports[ $k ] = Utils::array2object( $v, 'Report' ); 324 | } 325 | } 326 | 327 | return $program; 328 | } 329 | 330 | 331 | private function computeDatas() 332 | { 333 | $total_bounty = 0; 334 | $first_report = $first_report_id = 2147483647; 335 | $last_report = $last_report_id = 0; 336 | $smallest_bounty = $smallest_bounty_id = 2147483647; 337 | $higher_bounty = $higher_bounty_id = 0; 338 | 339 | foreach( $this->reports as $key=>$r ) 340 | { 341 | if( $r->getCreatedAt() < $first_report ) { 342 | $first_report_id = $key; 343 | $first_report = $r->getCreatedAt(); 344 | } 345 | if( $r->getCreatedAt() > $last_report ) { 346 | $last_report_id = $key; 347 | $last_report = $r->getCreatedAt(); 348 | } 349 | 350 | $total_bounty += $r->getTotalBounty(); 351 | 352 | if( $r->getTotalBounty() < $smallest_bounty && $r->getTotalBounty() != 0 ) { 353 | $smallest_bounty_id = $key; 354 | $smallest_bounty = $r->getTotalBounty(); 355 | } 356 | if( $r->getTotalBounty() > $higher_bounty ) { 357 | $higher_bounty_id = $key; 358 | $higher_bounty = $r->getTotalBounty(); 359 | } 360 | } 361 | 362 | $this->setTotalReport( count($this->reports) ); 363 | $this->setTotalBounty( $total_bounty ); 364 | $this->setFirstReportId( $first_report_id ); 365 | $this->setLastReportId( $last_report_id ); 366 | $this->setSmallestBountyId( $smallest_bounty_id ); 367 | $this->setHigherBountyId( $higher_bounty_id ); 368 | $this->setAverageBounty( (int)($total_bounty/$this->getTotalReport()) ); 369 | 370 | $range = $higher_bounty / 4; 371 | $average_bounty = $total_bounty / $this->getTotalReport(); 372 | $average_bounty2 = $average_bounty / 2; 373 | $average_bounty3 = $average_bounty / 3; 374 | 375 | $t_ranges = [ 376 | 'none' => 0, 377 | 'low' => 1, 378 | 'medium' => (int)($average_bounty - $average_bounty2), 379 | 'high' => (int)($average_bounty + $average_bounty2), 380 | 'critical' => (int)(($average_bounty + $average_bounty2) * 2), 381 | ]; 382 | //var_dump( $t_ranges ); 383 | 384 | foreach( $this->reports as $r ) 385 | { 386 | $bounty = $r->getTotalBounty(); 387 | 388 | foreach( $t_ranges as $k=>$v ) { 389 | if( $bounty < $v ) { 390 | break; 391 | } 392 | $severity = $k; 393 | } 394 | 395 | $r->setSeverity( $severity ); 396 | } 397 | 398 | $this->setBountyRange( $t_ranges ); 399 | } 400 | 401 | 402 | public function save() 403 | { 404 | $this->computeDatas(); 405 | $datas = json_encode( get_object_vars($this), JSON_PRETTY_PRINT ); 406 | 407 | $r = file_put_contents( $this->db_file, $datas ); 408 | if( $r === false ) { 409 | return false; 410 | } 411 | 412 | chmod( $this->db_file, 0777 ); 413 | return true; 414 | } 415 | } 416 | 417 | -------------------------------------------------------------------------------- /class/class.report.php: -------------------------------------------------------------------------------- 1 | id; 29 | } 30 | public function setId( $v ) { 31 | $this->id = $v; 32 | return true; 33 | } 34 | 35 | 36 | public function getIgnore() { 37 | return $this->ignore; 38 | } 39 | public function setIgnore( $v ) { 40 | $this->ignore = (int)$v; 41 | return true; 42 | } 43 | public function ignore() { 44 | $this->setIgnore( 1 ); 45 | return true; 46 | } 47 | public function unignore() { 48 | $this->setIgnore( 0 ); 49 | return true; 50 | } 51 | 52 | 53 | public function getManual() { 54 | return $this->manual; 55 | } 56 | public function setManual( $v ) { 57 | $this->manual = (int)$v; 58 | return true; 59 | } 60 | 61 | 62 | public function getPlatform() { 63 | return $this->platform; 64 | } 65 | public function setPlatform( $v ) { 66 | $this->platform = trim( $v ); 67 | return true; 68 | } 69 | 70 | 71 | public function getReporter() { 72 | return $this->reporter; 73 | } 74 | public function setReporter( $v ) { 75 | $this->reporter = trim( $v ); 76 | return true; 77 | } 78 | 79 | 80 | public function getCreatedAt() { 81 | return $this->created_at; 82 | } 83 | public function setCreatedAt( $v ) { 84 | $this->created_at = $v; 85 | return true; 86 | } 87 | 88 | 89 | public function getTitle() { 90 | return $this->title; 91 | } 92 | public function setTitle( $v ) { 93 | $this->title = trim( $v ); 94 | return true; 95 | } 96 | 97 | 98 | public function getProgram() { 99 | return $this->program; 100 | } 101 | public function setProgram( $v ) { 102 | $this->program = trim( $v ); 103 | return true; 104 | } 105 | 106 | 107 | public function getSeverity() { 108 | return $this->severity; 109 | } 110 | public function setSeverity( $v ) { 111 | $this->severity = trim( $v ); 112 | return true; 113 | } 114 | 115 | 116 | public function addReputation( $created_at, $points ) { 117 | $reputation = new stdClass(); 118 | $reputation->created_at = $created_at; 119 | $reputation->points = $points; 120 | return $this->reputations[] = $reputation; 121 | } 122 | public function getReputations() { 123 | return $this->reputations; 124 | } 125 | public function setReputations( $v ) { 126 | $this->reputations = $v; 127 | return true; 128 | } 129 | public function resetReputation() { 130 | $this->reputations = []; 131 | return true; 132 | } 133 | 134 | public function getTotalReputation() { 135 | $total = 0; 136 | foreach( $this->reputations as $r ) { 137 | $total += $r->points; 138 | } 139 | return $total; 140 | } 141 | 142 | 143 | public function addBounty( $created_at, $amount ) { 144 | $bounty = new stdClass(); 145 | $bounty->created_at = $created_at; 146 | $bounty->amount = $amount; 147 | return $this->bounties[] = $bounty; 148 | } 149 | public function getBounties() { 150 | return $this->bounties; 151 | } 152 | public function setBounties( $v ) { 153 | $this->bounties = $v; 154 | return true; 155 | } 156 | 157 | 158 | public function getTotalBounty() { 159 | $total = 0; 160 | foreach( $this->bounties as $b ) { 161 | $total += $b->amount; 162 | } 163 | return $total; 164 | } 165 | public function setManualBounty( $v ) { 166 | $bounty = new stdClass(); 167 | $bounty->created_at = $this->getCreatedAt(); 168 | $bounty->amount = $v; 169 | $this->setBounties( [$bounty] ); 170 | return true; 171 | } 172 | 173 | 174 | public function getState() { 175 | return $this->state; 176 | } 177 | public function setState( $v ) { 178 | $this->state = trim( $v ); 179 | return true; 180 | } 181 | 182 | 183 | public function getRating() { 184 | return $this->rating; 185 | } 186 | public function setRating( $v ) { 187 | $this->rating = (int)$v; 188 | return true; 189 | } 190 | 191 | 192 | public function getImpact() { 193 | $i = ($this->rating) ? (6-$this->rating) : 0; 194 | return $i; 195 | } 196 | 197 | 198 | public function getTags( $str=false ) { 199 | if( $str ) { 200 | return implode(', ',$this->tags); 201 | } else { 202 | return $this->tags; 203 | } 204 | } 205 | public function setTags( $v ) { 206 | $this->tags = array_unique( array_map('trim',$v), SORT_STRING ); 207 | sort( $this->tags ); 208 | return true; 209 | } 210 | public function addTag( $v ) { 211 | $v = trim( $v ); 212 | if( $v == '' ) { 213 | return false; 214 | } 215 | $t_tags = $this->getTags(); 216 | if( !in_array($v,$t_tags) ) { 217 | $t_tags[] = $v; 218 | $this->setTags( $t_tags ); 219 | } 220 | return true; 221 | } 222 | 223 | 224 | public function getLink() { 225 | $class = $this->getPlatform(); 226 | if( is_callable([$class,'getReportLink']) ) { 227 | return $class::getReportLink( $this->id ); 228 | } else { 229 | return false; 230 | } 231 | } 232 | 233 | 234 | public function getFirstResponseDate() { 235 | return $this->first_response_date; 236 | } 237 | public function setFirstResponseDate( $v ) { 238 | $this->first_response_date = $v; 239 | return true; 240 | } 241 | public function getFirstResponseTime() { 242 | $scd = Utils::datetimeDiff( $this->getCreatedAt(), $this->getFirstResponseDate() )->total_sec / 3600 / 24; 243 | return $scd; 244 | } 245 | 246 | 247 | public function getFirstBountyDate() { 248 | return $this->first_bounty_date; 249 | } 250 | public function setFirstBountyDate( $v ) { 251 | $this->first_bounty_date = $v; 252 | return true; 253 | } 254 | public function getFirstBountyTime() { 255 | $scd = Utils::datetimeDiff( $this->getCreatedAt(), $this->getFirstBountyDate() )->total_sec / 3600 / 24; 256 | return $scd; 257 | } 258 | 259 | 260 | public function getTriageDate() { 261 | return $this->triage_date; 262 | } 263 | public function setTriageDate( $v ) { 264 | $this->triage_date = $v; 265 | return true; 266 | } 267 | public function getTriageTime() { 268 | $scd = Utils::datetimeDiff( $this->getCreatedAt(), $this->getTriageDate() )->total_sec / 3600 / 24; 269 | return $scd; 270 | } 271 | 272 | 273 | public function getResolutionDate() { 274 | return $this->resolution_date; 275 | } 276 | public function setResolutionDate( $v ) { 277 | $this->resolution_date = $v; 278 | return true; 279 | } 280 | public function getResolutionTime() { 281 | $scd = Utils::datetimeDiff( $this->getCreatedAt(), $this->getResolutionDate() )->total_sec / 3600 / 24; 282 | return $scd; 283 | } 284 | 285 | 286 | public static function generateKey( $platform, $program, $report_id ) 287 | { 288 | return md5( $platform.'.'.$program.'.'.$report_id ); 289 | } 290 | 291 | 292 | public static function massAutoTag( $t_reports ) 293 | { 294 | foreach( $t_reports as $key=>$report ) { 295 | $report->autoTag(); 296 | } 297 | 298 | return $t_reports; 299 | } 300 | 301 | 302 | public function autoTag() 303 | { 304 | $t_tags = self::guessTag( $this->getTitle() ); 305 | $this->setTags( $t_tags ); 306 | 307 | return count($t_tags); 308 | } 309 | 310 | 311 | public static function guessTag( $title ) 312 | { 313 | $t_guess = []; 314 | 315 | foreach( AUTO_RATE_TAG as $rating=>$t_tags ) { 316 | foreach( $t_tags as $tag=>$t_terms ) { 317 | foreach( $t_terms['tag_terms'] as $tterm ) { 318 | if( preg_match('#'.$tterm.'#i',$title) ) { 319 | $t_guess[] = $tag; 320 | break; 321 | } 322 | } 323 | } 324 | } 325 | 326 | $t_guess = array_unique($t_guess,SORT_STRING); 327 | sort( $t_guess ); 328 | 329 | return $t_guess; 330 | } 331 | 332 | 333 | public static function massAutoRate( $t_reports ) 334 | { 335 | foreach( $t_reports as $key=>$report ) { 336 | $report->autoRate(); 337 | } 338 | 339 | return $t_reports; 340 | } 341 | 342 | 343 | public function autoRate() 344 | { 345 | $rating = self::guessRate( $this->getTitle() ); 346 | $this->setRating( $rating ); 347 | 348 | return $rating; 349 | } 350 | 351 | 352 | public static function guessRate( $title ) 353 | { 354 | foreach( AUTO_RATE_TAG as $rating=>$t_tags ) { 355 | foreach( $t_tags as $tag=>$t_terms ) { 356 | foreach( $t_terms['tag_terms'] as $tterm ) { 357 | if( preg_match('#'.$tterm.'#i',$title) ) { 358 | $guess = $rating; 359 | if( isset($t_terms['rate_terms']) ) { 360 | foreach( $t_terms['rate_terms'] as $rterm=>$point ) { 361 | if( preg_match('#'.$rterm.'#i',$title) ) { 362 | $guess += $point; 363 | } 364 | } 365 | } 366 | return $guess; 367 | } 368 | } 369 | } 370 | } 371 | 372 | return 0; 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /class/class.utils.php: -------------------------------------------------------------------------------- 1 | '0', 8 | 'black' => '0;30', 9 | 'red' => '0;31', 10 | 'green' => '0;32', 11 | 'orange' => '0;33', 12 | 'blue' => '0;34', 13 | 'purple' => '0;35', 14 | 'cyan' => '0;36', 15 | 'light_grey' => '0;37', 16 | 'dark_grey' => '1;30', 17 | 'light_red' => '1;31', 18 | 'light_green' => '1;32', 19 | 'yellow' => '1;33', 20 | 'light_blue' => '1;34', 21 | 'light_purple' => '1;35', 22 | 'light_cyan' => '1;36', 23 | 'white' => '1;37', 24 | ); 25 | 26 | 27 | public static function help( $error='' ) 28 | { 29 | $help = self::fromReadme( 'help' ); 30 | echo $help."\n"; 31 | 32 | if( $error ) { 33 | echo "\nError: ".$error."!\n"; 34 | } 35 | 36 | exit(); 37 | } 38 | 39 | 40 | public static function fromReadme( $tag ) 41 | { 42 | $readme = APP_PATH.'/README.md'; 43 | $content = file_get_contents( $readme ); 44 | $open_tag = ''; 45 | $close_tag = ''; 46 | $r = '#'.$open_tag.'(.*)'.$close_tag.'#s'; 47 | $m = preg_match_all( $r, $content, $match ); 48 | 49 | if( $m ) { 50 | return trim($match[1][0]); 51 | } else { 52 | return "Nothing found!\n"; 53 | } 54 | } 55 | 56 | 57 | public static function isIp( $str ) { 58 | return filter_var( $str, FILTER_VALIDATE_IP ); 59 | } 60 | 61 | 62 | public static function isEmail( $str ) 63 | { 64 | return filter_var( $str, FILTER_VALIDATE_EMAIL ); 65 | } 66 | 67 | 68 | public static function _print( $str, $color ) 69 | { 70 | echo "\033[".self::T_SHELL_COLORS[$color]."m".$str."\033[0m"; 71 | } 72 | public static function _println( $str, $color ) 73 | { 74 | self::_print( $str, $color ); 75 | echo "\n"; 76 | } 77 | 78 | 79 | public static function _array_search( $array, $search, $ignore_case=true ) 80 | { 81 | if( $ignore_case ) { 82 | $f = 'stristr'; 83 | } else { 84 | $f = 'strstr'; 85 | } 86 | 87 | if( !is_array($search) ) { 88 | $search = array( $search ); 89 | } 90 | 91 | foreach( $array as $k=>$v ) { 92 | foreach( $search as $str ) { 93 | if( $f($v, $str) ) { 94 | return $k; 95 | } 96 | } 97 | } 98 | 99 | return false; 100 | } 101 | 102 | 103 | public static function isDomain( $str ) 104 | { 105 | $str = strtolower( $str ); 106 | 107 | if( preg_match('/[^0-9a-z_\-\.]/',$str) || preg_match('/[^0-9a-z]/',$str[0]) || preg_match('/[^a-z]/',$str[strlen($str)-1]) || substr_count($str,'.')>2 || substr_count($str,'.')<=0 ) { 108 | return false; 109 | } else { 110 | return true; 111 | } 112 | } 113 | 114 | 115 | public static function isSubdomain( $str ) 116 | { 117 | $str = strtolower( $str ); 118 | 119 | if( preg_match('/[^0-9a-z_\-\.]/',$str) || preg_match('/[^0-9a-z]/',$str[0]) || preg_match('/[^a-z]/',$str[strlen($str)-1]) || substr_count($str,'.')<2 ) { 120 | return false; 121 | } else { 122 | return true; 123 | } 124 | } 125 | 126 | 127 | public static function extractDomain( $host ) 128 | { 129 | $tmp = explode( '.', $host ); 130 | $cnt = count( $tmp ); 131 | 132 | $domain = $tmp[$cnt-1]; 133 | 134 | for( $i=$cnt-2 ; $i>=0 ; $i-- ) { 135 | $domain = $tmp[$i].'.'.$domain; 136 | if( strlen($tmp[$i]) > 3 ) { 137 | break; 138 | } 139 | } 140 | 141 | return $domain; 142 | } 143 | 144 | 145 | public static function cleanOutput( $str ) 146 | { 147 | $str = preg_replace( '#\[[0-9;]{1,4}m#', '', $str ); 148 | 149 | return $str; 150 | } 151 | 152 | 153 | public static function _exec( $cmd ) 154 | { 155 | $output = ''; 156 | 157 | while( @ob_end_flush() ); 158 | 159 | $proc = popen( $cmd, 'r' ); 160 | while( !feof($proc) ) { 161 | $line = fread( $proc, 4096 ); 162 | echo $line; 163 | $output .= $line; 164 | @flush(); 165 | } 166 | 167 | return $output; 168 | } 169 | 170 | 171 | public function printDebug( $txt ) { 172 | self::_println( '[*] '.$txt, 'white' ); 173 | } 174 | public function printInfo( $txt ) { 175 | self::_println( '[*] '.$txt, 'white' ); 176 | } 177 | public function printSuccess( $txt ) { 178 | self::_println( '[+] '.$txt, 'green' ); 179 | } 180 | public function printError( $txt ) { 181 | self::_println( '[-] '.$txt, 'red' ); 182 | } 183 | 184 | 185 | public static function array2object( $array, $class ) 186 | { 187 | $object = new $class(); 188 | 189 | foreach( $array as $k=>$v ) { 190 | $k = self::camelize( $k ); 191 | $method = 'set'.$k; 192 | if( is_callable([$object,$method]) ) { 193 | $object->$method( $v ); 194 | } 195 | } 196 | 197 | return $object; 198 | } 199 | 200 | 201 | public static function camelize( $str ) 202 | { 203 | $str = strtolower( $str ); 204 | $tmp = explode( '_', $str ); 205 | $tmp = array_map( 'ucfirst', $tmp ); 206 | $str = implode( '', $tmp ); 207 | 208 | return $str; 209 | } 210 | 211 | 212 | public static function datetimeDiff( $ts1, $ts2 ) 213 | { 214 | $dtd = new stdClass(); 215 | $dtd->interval = $ts2 - $ts1; 216 | $dtd->total_sec = abs($ts2-$ts1); 217 | $dtd->total_min = floor($dtd->total_sec/60); 218 | $dtd->total_hour = floor($dtd->total_min/60); 219 | $dtd->total_day = floor($dtd->total_hour/24); 220 | 221 | $dtd->day = $dtd->total_day; 222 | $dtd->hour = $dtd->total_hour -($dtd->total_day*24); 223 | $dtd->min = $dtd->total_min -($dtd->total_hour*60); 224 | $dtd->sec = $dtd->total_sec -($dtd->total_min*60); 225 | 226 | return $dtd; 227 | } 228 | 229 | public static function demonize( $t_reports ) 230 | { 231 | $t_random_program = [ 'google', 'facebook', 'yahoo', 'salesforce', 'uber', 'pornhub', 'yelp', 'imgur', 'github' ]; 232 | $n_random_program = count($t_random_program) - 1; 233 | 234 | foreach( $t_reports as $r ) 235 | { 236 | if( rand(0,100) <= 70 ) { 237 | $r->setPlatform( 'hackerone' ); 238 | } else { 239 | $r->setPlatform( 'bugcrowd' ); 240 | } 241 | 242 | $program = $r->getProgram(); 243 | $r->setProgram( $t_random_program[rand(0,$n_random_program)] ); 244 | 245 | $title = $r->getTitle(); 246 | $title = preg_replace( '#'.$program.'#i', $r->getProgram(), $title ); 247 | $title = preg_replace( '#[^\s]+\.com#i', $r->getProgram().'.com', $title ); 248 | $title = preg_replace( '#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#', '192.168.'.rand(0,10).'.'.rand(1,253), $title ); 249 | $r->setTitle( $title ); 250 | 251 | $t_bounties = $r->getBounties(); 252 | foreach( $t_bounties as $b ) { 253 | $rating = $r->getRating() ? $r->getRating() : 6; 254 | $b->amount = rand( (6-$rating)*50, (6-$rating)*700 ); 255 | } 256 | $r->setBounties( $t_bounties ); 257 | } 258 | 259 | return $t_reports; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /class/class.yogosha.php: -------------------------------------------------------------------------------- 1 | setName( 'yogosha' ); 7 | } 8 | 9 | 10 | public function login() 11 | { 12 | } 13 | 14 | 15 | public function connect() 16 | { 17 | } 18 | 19 | 20 | public function grabReportList( $quantity ) 21 | { 22 | } 23 | 24 | 25 | protected function grabReportListFromFile( $quantity ) 26 | { 27 | } 28 | 29 | 30 | public function grabReports( $quantity, $t_reputation ) 31 | { 32 | } 33 | 34 | 35 | public function grabReportsFromFile( $quantity, $t_reputation ) 36 | { 37 | } 38 | 39 | 40 | protected function grabReport( $report_id ) 41 | { 42 | } 43 | 44 | 45 | protected function grabReportFromFile( $report_id ) 46 | { 47 | } 48 | 49 | 50 | public function extractReportDatas() 51 | { 52 | } 53 | 54 | 55 | public static function getReportLink( $report_id ) { 56 | return 'https://app.yogosha.com/reports/'.$report_id.'/'; 57 | } 58 | 59 | 60 | public function grabReputation() 61 | { 62 | } 63 | 64 | 65 | public function grabReputationFromFile() 66 | { 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | 5) => [ 50 | 'tag_name' => [ 51 | 'tag_terms' => [ // regexp used to tag the report 52 | 'term1', 53 | 'term2', 54 | 'term3', 55 | '...', 56 | ], 57 | 'rate_terms => [ // regexp used to rate the report, added to the initial_rate_value 58 | 'term1' => 0, 59 | 'term2' => +1, 60 | 'term3' => -2, 61 | '...', 62 | ] 63 | ] 64 | ] 65 | */ 66 | 67 | define( 'AUTO_RATE_TAG', [ 68 | 1 => [ 69 | 'rce' => [ 70 | 'tag_terms' => [ 71 | '\s+rce\s+', 72 | '^rce\s+', 73 | 'remote command execution', 74 | 'remote command injection', 75 | ], 76 | ], 77 | ], 78 | 2 => [ 79 | 'sqli' => [ 80 | 'tag_terms' => [ 81 | 'sql', 82 | 'sqli', 83 | 'sql injection', 84 | ], 85 | 'rate_terms' => [ 86 | 'read' => 0, 87 | 'write' => -1, 88 | 'possible' => +1, 89 | ], 90 | ], 91 | 'ssrf' => [ 92 | 'tag_terms' => [ 93 | 'ssrf', 94 | 'server side request forgery', 95 | ], 96 | 'rate_terms' => [ 97 | ], 98 | ], 99 | 'lfd' => [ 100 | 'tag_terms' => [ 101 | 'lfd', 102 | 'local file disclosure', 103 | ], 104 | ], 105 | 'lfi' => [ 106 | 'tag_terms' => [ 107 | 'lfi', 108 | 'local file inclusion', 109 | ], 110 | ], 111 | 'rfi' => [ 112 | 'tag_terms' => [ 113 | 'rfi', 114 | 'remote file inclusion', 115 | ], 116 | ], 117 | ], 118 | 3 => [ 119 | 'xss' => [ 120 | 'tag_terms' => [ 121 | 'xss', 122 | 'cross site scripting', 123 | 'Cross-Site Scripting', 124 | ], 125 | ], 126 | 'csrf' => [ 127 | 'tag_terms' => [ 128 | 'csrf', 129 | 'cross site request forgery', 130 | ], 131 | ], 132 | 'idor' => [ 133 | 'tag_terms' => [ 134 | 'idor', 135 | 'insecure direct object reference', 136 | ], 137 | ], 138 | 'bucket' => [ 139 | 'tag_terms' => [ 140 | 'bucket', 141 | ], 142 | ], 143 | 'cors' => [ 144 | 'tag_terms' => [ 145 | 'cors', 146 | 'cross origin', 147 | ], 148 | ], 149 | ], 150 | 4 => [ 151 | 'ratel' => [ 152 | 'tag_terms' => [ 153 | 'rate limit', 154 | 'ratelimit', 155 | 'brute force', 156 | 'bruteforce', 157 | ], 158 | ], 159 | 'subto' => [ 160 | 'tag_terms' => [ 161 | 'subdomain takeover', 162 | 'subdomain take over', 163 | ], 164 | ], 165 | 'openr' => [ 166 | 'tag_terms' => [ 167 | 'open redirect', 168 | ], 169 | ], 170 | ], 171 | 5 => [ 172 | 'infod' => [ 173 | 'tag_terms' => [ 174 | 'phpinfo', 175 | 'server-?status', 176 | 'server-?info', 177 | 'directory listing', 178 | 'information disclosure', 179 | 'htaccess', 180 | ], 181 | ], 182 | 'fpd' => [ 183 | 'tag_terms' => [ 184 | 'full path disclosure', 185 | ], 186 | ], 187 | ], 188 | ] ); 189 | -------------------------------------------------------------------------------- /css/awesome-bootstrap-checkbox.css: -------------------------------------------------------------------------------- 1 | .checkbox{padding-left:20px}.checkbox label{display:inline-block;vertical-align:middle;position:relative;padding-left:5px}.checkbox label::before{content:"";display:inline-block;position:absolute;width:17px;height:17px;left:0;margin-left:-20px;border:1px solid #ccc;border-radius:3px;background-color:#fff;-webkit-transition:border .15s ease-in-out,color .15s ease-in-out;-o-transition:border .15s ease-in-out,color .15s ease-in-out;transition:border .15s ease-in-out,color .15s ease-in-out}.checkbox label::after{display:inline-block;position:absolute;width:16px;height:16px;left:0;top:0;margin-left:-20px;padding-left:3px;padding-top:1px;font-size:11px;color:#555}.checkbox input[type="checkbox"],.checkbox input[type="radio"]{opacity:0;z-index:1}.checkbox input[type="checkbox"]:focus + label::before,.checkbox input[type="radio"]:focus + label::before{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.checkbox input[type="checkbox"]:checked + label::after,.checkbox input[type="radio"]:checked + label::after{font-family:"FontAwesome";content:"\f00c"}.checkbox input[type="checkbox"]:disabled + label,.checkbox input[type="radio"]:disabled + label{opacity:.65}.checkbox input[type="checkbox"]:disabled + label::before,.checkbox input[type="radio"]:disabled + label::before{background-color:#eee;cursor:not-allowed}.checkbox.checkbox-circle label::before{border-radius:50%}.checkbox.checkbox-inline{margin-top:0}.checkbox-primary input[type="checkbox"]:checked + label::before,.checkbox-primary input[type="radio"]:checked + label::before{background-color:#337ab7;border-color:#337ab7}.checkbox-primary input[type="checkbox"]:checked + label::after,.checkbox-primary input[type="radio"]:checked + label::after{color:#fff}.checkbox-danger input[type="checkbox"]:checked + label::before,.checkbox-danger input[type="radio"]:checked + label::before{background-color:#d9534f;border-color:#d9534f}.checkbox-danger input[type="checkbox"]:checked + label::after,.checkbox-danger input[type="radio"]:checked + label::after{color:#fff}.checkbox-info input[type="checkbox"]:checked + label::before,.checkbox-info input[type="radio"]:checked + label::before{background-color:#5bc0de;border-color:#5bc0de}.checkbox-info input[type="checkbox"]:checked + label::after,.checkbox-info input[type="radio"]:checked + label::after{color:#fff}.checkbox-warning input[type="checkbox"]:checked + label::before,.checkbox-warning input[type="radio"]:checked + label::before{background-color:#f0ad4e;border-color:#f0ad4e}.checkbox-warning input[type="checkbox"]:checked + label::after,.checkbox-warning input[type="radio"]:checked + label::after{color:#fff}.checkbox-success input[type="checkbox"]:checked + label::before,.checkbox-success input[type="radio"]:checked + label::before{background-color:#5cb85c;border-color:#5cb85c}.checkbox-success input[type="checkbox"]:checked + label::after,.checkbox-success input[type="radio"]:checked + label::after{color:#fff}.radio{padding-left:20px}.radio label{display:inline-block;vertical-align:middle;position:relative;padding-left:5px}.radio label::before{content:"";display:inline-block;position:absolute;width:17px;height:17px;left:0;margin-left:-20px;border:1px solid #ccc;border-radius:50%;background-color:#fff;-webkit-transition:border .15s ease-in-out;-o-transition:border .15s ease-in-out;transition:border .15s ease-in-out}.radio label::after{display:inline-block;position:absolute;content:" ";width:11px;height:11px;left:3px;top:3px;margin-left:-20px;border-radius:50%;background-color:#555;-webkit-transform:scale(0,0);-ms-transform:scale(0,0);-o-transform:scale(0,0);transform:scale(0,0);-webkit-transition:-webkit-transform .1s cubic-bezier(0.8,-0.33,0.2,1.33);-moz-transition:-moz-transform .1s cubic-bezier(0.8,-0.33,0.2,1.33);-o-transition:-o-transform .1s cubic-bezier(0.8,-0.33,0.2,1.33);transition:transform .1s cubic-bezier(0.8,-0.33,0.2,1.33)}.radio input[type="radio"]{opacity:0;z-index:1}.radio input[type="radio"]:focus + label::before{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.radio input[type="radio"]:checked + label::after{-webkit-transform:scale(1,1);-ms-transform:scale(1,1);-o-transform:scale(1,1);transform:scale(1,1)}.radio input[type="radio"]:disabled + label{opacity:.65}.radio input[type="radio"]:disabled + label::before{cursor:not-allowed}.radio.radio-inline{margin-top:0}.radio-primary input[type="radio"] + label::after{background-color:#337ab7}.radio-primary input[type="radio"]:checked + label::before{border-color:#337ab7}.radio-primary input[type="radio"]:checked + label::after{background-color:#337ab7}.radio-danger input[type="radio"] + label::after{background-color:#d9534f}.radio-danger input[type="radio"]:checked + label::before{border-color:#d9534f}.radio-danger input[type="radio"]:checked + label::after{background-color:#d9534f}.radio-info input[type="radio"] + label::after{background-color:#5bc0de}.radio-info input[type="radio"]:checked + label::before{border-color:#5bc0de}.radio-info input[type="radio"]:checked + label::after{background-color:#5bc0de}.radio-warning input[type="radio"] + label::after{background-color:#f0ad4e}.radio-warning input[type="radio"]:checked + label::before{border-color:#f0ad4e}.radio-warning input[type="radio"]:checked + label::after{background-color:#f0ad4e}.radio-success input[type="radio"] + label::after{background-color:#5cb85c}.radio-success input[type="radio"]:checked + label::before{border-color:#5cb85c}.radio-success input[type="radio"]:checked + label::after{background-color:#5cb85c}input[type="checkbox"].styled:checked + label:after,input[type="radio"].styled:checked + label:after{font-family:'FontAwesome';content:"\f00c"}input[type="checkbox"] .styled:checked + label::before,input[type="radio"] .styled:checked + label::before{color:#fff}input[type="checkbox"] .styled:checked + label::after,input[type="radio"] .styled:checked + label::after{color:#fff} -------------------------------------------------------------------------------- /css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}html{-webkit-box-sizing:border-box;box-sizing:border-box}*,::after,::before{-webkit-box-sizing:inherit;box-sizing:inherit}@-ms-viewport{width:device-width}html{-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}body{font-family:-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#292b2c;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{cursor:help}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}a{color:#0275d8;text-decoration:none}a:focus,a:hover{color:#014c8c;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle}[role=button]{cursor:pointer}[role=button],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse;background-color:transparent}caption{padding-top:.75rem;padding-bottom:.75rem;color:#636c72;text-align:left;caption-side:bottom}th{text-align:left}label{display:inline-block;margin-bottom:.5rem}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,select,textarea{line-height:inherit}input[type=checkbox]:disabled,input[type=radio]:disabled{cursor:not-allowed}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{-webkit-appearance:listbox}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit}input[type=search]{-webkit-appearance:none}output{display:inline-block}[hidden]{display:none!important}/*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /css/custom.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-size: 12px; 3 | padding-top: 10px; 4 | } 5 | #menubar { 6 | right: 15px; 7 | position: absolute; 8 | text-align: right; 9 | top: 0px; 10 | width: 100%; 11 | z-index: 1; 12 | } 13 | #menubar button { 14 | border-top-left-radius: 0px; 15 | border-top-right-radius: 0px; 16 | font-weight: bold; 17 | } 18 | input { 19 | font-size: 12px !important; 20 | } 21 | .input-group-addon { 22 | font-size: 12px !important; 23 | padding: 10px 16px; 24 | } 25 | .container { 26 | } 27 | .control-label { 28 | padding-top: 8px !important; 29 | text-align: left !important; 30 | } 31 | .form-control { 32 | height: 35px; 33 | padding: 6px 8px !important; 34 | } 35 | select.form-control, select.form-control option { 36 | font-size: 12px !important; 37 | } 38 | .btn { 39 | line-height: 11px; 40 | } 41 | .report-reputation { 42 | border: 1px solid; 43 | border-radius: 3px; 44 | float: right; 45 | font-size: 10px; 46 | padding: 1px 3px 0px 3px; 47 | } 48 | .reputation-zero { 49 | border-color: #aaa; 50 | color: #000; 51 | } 52 | .reputation-positive { 53 | border-color: #72BC42; 54 | color: #72BC42; 55 | } 56 | .reputation-negative { 57 | border-color: #CD3A3A; 58 | color: #CD3A3A; 59 | } 60 | .report-state { 61 | border-left: 4px solid !important; 62 | } 63 | .report-platform { 64 | display: none; 65 | } 66 | .report-rrating { 67 | display: none; 68 | } 69 | .report-rrating { 70 | display: none; 71 | } 72 | .report-sstate { 73 | display: none; 74 | } 75 | .report-untaged { 76 | display: none; 77 | } 78 | .state_ { 79 | border-left: 0px solid !important; 80 | } 81 | .state_more_info { 82 | border-left-color: #559cf5 !important; 83 | } 84 | .state_open { 85 | border-left-color: #f5ca61 !important; 86 | } 87 | .state_new { 88 | border-left-color: #8e44ad !important; 89 | } 90 | .state_triaged { 91 | border-left-color: #e67e22 !important; 92 | } 93 | .state_duplicate { 94 | border-left-color: #a78260 !important; 95 | } 96 | .state_informative { 97 | border-left-color: #ccc !important; 98 | } 99 | .state_not-applicable { 100 | border-left-color: #ce3f4b !important; 101 | } 102 | .state_resolved { 103 | border-left-color: #609828 !important; 104 | } 105 | .state_spam { 106 | border-left-color: #555 !important; 107 | } 108 | /* bugcrowd */ 109 | .state_not_applicable { 110 | border-left-color: #ce3f4b !important; 111 | } 112 | .state_wont_fix { 113 | border-left-color: #ccc !important; 114 | } 115 | .state_unresolved { 116 | border-left-color: #e67e22 !important; 117 | } 118 | /* the rabbit is not here */ 119 | a.rating_0, a.rating_0:hover, a.rating_0:visited, a.rating_0:active { 120 | color: #000; 121 | } 122 | .rating_1, a.rating_1:hover, a.rating_1:visited, a.rating_1:active { 123 | color: #d13535; 124 | } 125 | .radio-1 input[type="radio"] + label::after { 126 | background-color: #d13535; 127 | } 128 | .rating_2, a.rating_2:hover, a.rating_2:visited, a.rating_2:active { 129 | color: #ff6900; 130 | } 131 | .radio-2 input[type="radio"] + label::after { 132 | background-color: #ff6900; 133 | } 134 | .rating_3, a.rating_3:hover, a.rating_3:visited, a.rating_3:active { 135 | color: #f0ad4e; 136 | } 137 | .radio-3 input[type="radio"] + label::after { 138 | background-color: #f0ad4e; 139 | } 140 | .rating_4, a.rating_4:hover, a.rating_4:visited, a.rating_4:active { 141 | color: #5eae00; 142 | } 143 | .radio-4 input[type="radio"] + label::after { 144 | background-color: #5eae00; 145 | } 146 | .rating_5, a.rating_5:hover, a.rating_5:visited, a.rating_5:active { 147 | color: #0278b8; 148 | } 149 | .radio-5 input[type="radio"] + label::after { 150 | background-color: #0278b8; 151 | } 152 | a.rating_none, a.rating_none:hover, a.rating_none:visited, a.rating_none:active { 153 | color: #0278b8; 154 | } 155 | a.rating_low, a.rating_low:hover, a.rating_low:visited, a.rating_low:active { 156 | color: #5eae00; 157 | } 158 | .rating_medium, a.rating_medium:hover, a.rating_medium:visited, a.rating_medium:active { 159 | color: #f0ad4e; 160 | } 161 | .rating_high, a.rating_high:hover, a.rating_high:visited, a.rating_high:active { 162 | color: #ff6900; 163 | } 164 | .rating_critical, a.rating_critical:hover, a.rating_critical:visited, a.rating_critical:active { 165 | color: #d13535; 166 | } 167 | #modalReportAdd .radio, #modalReportEdit .radio { 168 | margin-right: 30px; 169 | padding-top: 8px; 170 | } 171 | .highcharts-container { 172 | border-bottom: 1px solid #000; 173 | margin-bottom: 50px; 174 | } 175 | 176 | table.table-bordered.dataTable { 177 | border-collapse: collapse !important; 178 | } 179 | .dataTable tbody tr:hover { 180 | background-color: #f0f0f0; 181 | } 182 | .dataTables_length { 183 | display: none; 184 | } 185 | .dataTables_filter input { 186 | height: 30px; 187 | padding: 6px 8px !important; 188 | } 189 | .dataTables_paginate .pagination > li > a { 190 | } 191 | .pagination > li > a, .pagination > li > span { 192 | padding: 8px 14px !important; 193 | } 194 | 195 | #listing { 196 | margin-top: 40px; 197 | } 198 | #listing .new-month { 199 | border-bottom: 2px solid #aaa !important; 200 | } 201 | #listing .ignored { 202 | opacity: 0.3; 203 | filter: alpha(opacity=30); 204 | } 205 | #listing .report-tag { 206 | background-color: #777; 207 | border-radius: 2px; 208 | color: #fff; 209 | padding: 1px 3px; 210 | } 211 | #listing .report-zzzz::after { 212 | border-left: 1px solid #555; 213 | content: ' x'; 214 | cursor: pointer; 215 | padding-left: 0px; 216 | text-align: center; 217 | width: 40px; 218 | } 219 | /* 220 | #listing_wrapper .row { 221 | position: relative; 222 | } 223 | #listing_wrapper .row.top .col-md-4 { 224 | bottom: 0px; 225 | position: absolute; 226 | 227 | } 228 | #listing_wrapper .row.top .col-md-4:nth-child(1) { 229 | bottom: 5px; 230 | left: 0px; 231 | } 232 | #listing_wrapper .row.top .col-md-4:nth-child(2) { 233 | right: 40%; 234 | } 235 | #listing_wrapper .row.top .col-md-4:nth-child(3) { 236 | right: 0px; 237 | } 238 | */ 239 | #listing_wrapper div.top { 240 | margin-bottom: -4px; 241 | } 242 | .dataTables_filter label, .listing_filter label { 243 | margin-bottom: 0px; 244 | } 245 | #listing_wrapper .pagination { 246 | margin: 0px; 247 | } 248 | #listing_wrapper div.dataTables_info { 249 | padding-top: 5px; 250 | } 251 | 252 | ul.pagination { 253 | margin: 0px; 254 | } 255 | 256 | h4 { 257 | margin-bottom: 20px; 258 | text-align: center; 259 | } 260 | div.spacer { 261 | border-bottom: 1px solid #000; 262 | margin-bottom: 40px; 263 | } 264 | div.datop > .table > thead > tr > th, div.datop > .table > tbody > tr > th, div.datop > .table > tfoot > tr > th, div.datop > .table > thead > tr > td, div.datop > .table > tbody > tr > td, div.datop > .table > tfoot > tr > td { 265 | border: 0px; 266 | } 267 | div.datop > .table tr { 268 | border-left: 1px solid #aaa !important; 269 | border-right: 1px solid #aaa !important; 270 | } 271 | div.datop > .table > thead > tr > th { 272 | background-color: #eceeef; 273 | border-bottom: 1px solid #aaa !important; 274 | font-weight: normal; 275 | text-align: center; 276 | } 277 | div.datop > .table > tbody > tr { 278 | border-bottom: 1px solid #eceeef; 279 | } 280 | div.datop > .table > tbody > tr.top_1 { 281 | color: #d13535; 282 | } 283 | div.datop > .table > tbody > tr.top_2 { 284 | color: #ff6900; 285 | } 286 | div.datop > .table > tbody > tr.top_3 { 287 | color: #f0ad4e; 288 | } 289 | div.datop > .table > tbody > tr.top_4 { 290 | color: #5eae00; 291 | } 292 | div.datop > .table > tbody > tr.top_5 { 293 | color: #0278b8; 294 | } 295 | div.datop > .table > tbody > tr:last-child { 296 | border: 0; 297 | } 298 | .search-term { 299 | cursor: pointer !important; 300 | } 301 | #filter-reset { 302 | margin-left: 5px; 303 | } 304 | 305 | 306 | #hacker-container #hacker-infos { 307 | border-bottom: 1px solid #000; 308 | display: table; 309 | font-size: 1.2em; 310 | margin-left: 25px; 311 | margin-bottom: 50px; 312 | padding-bottom: 50px; 313 | width: 100%; 314 | } 315 | #hacker-container #hacker-infos h3 { 316 | margin: 0px; 317 | padding: 0px; 318 | text-align: left; 319 | } 320 | #hacker-container #hacker-infos a { 321 | color: #000 ; 322 | } 323 | #hacker-container #hacker-infos a:hover { 324 | text-decoration: none; 325 | } 326 | #hacker-container #hacker-infos .hacker-logo { 327 | width: 100px; 328 | } 329 | #hacker-container #hacker-infos [class*="col-"] { 330 | display: table-cell; 331 | } 332 | #hacker-container #hacker-profile-picture { 333 | border: 1px solid #000; 334 | border-radius: 3px; 335 | } 336 | 337 | #hacker-container .p_positive { 338 | color: #5eae00; 339 | font-weight: bold; 340 | } 341 | #hacker-container .p_negative { 342 | color: #d13535; 343 | font-weight: bold; 344 | } 345 | #hacker-container .p_null { 346 | color: #AAA; 347 | font-weight: bold; 348 | } 349 | 350 | 351 | #program-container #severity-legend { 352 | background-color: rgba(245, 245, 245, 0.8); 353 | border: 1px solid rgb(212, 24, 24); 354 | border-radius: 2px; 355 | box-shadow: 2px 2px 2px #AAA; 356 | left: 170px; 357 | padding: 8px; 358 | position: absolute; 359 | top: 20px; 360 | } 361 | #program-container .severity-none { 362 | color: #0278b8; 363 | } 364 | #program-container .severity-low { 365 | color: #5eae00; 366 | } 367 | #program-container .severity-medium { 368 | color: #f0ad4e; 369 | } 370 | #program-container .severity-high { 371 | color: #ff6900; 372 | } 373 | #program-container .severity-critical { 374 | color: #d13535; 375 | } 376 | #program-container #program-infos { 377 | border-bottom: 1px solid #000; 378 | display: table; 379 | font-size: 1.2em; 380 | margin-left: 25px; 381 | margin-bottom: 50px; 382 | padding-bottom: 50px; 383 | width: 100%; 384 | } 385 | #program-container #program-infos h3 { 386 | margin: 0px; 387 | padding: 0px; 388 | text-align: left; 389 | } 390 | #program-container #program-infos a { 391 | color: #000 ; 392 | } 393 | #program-container #program-infos a:hover { 394 | text-decoration: none; 395 | } 396 | #program-container #program-infos .program-logo { 397 | width: 100px; 398 | } 399 | #program-container #program-infos [class*="col-"] { 400 | display: table-cell; 401 | } 402 | #program-container #program-profile-picture { 403 | border: 1px solid #000; 404 | border-radius: 3px; 405 | } 406 | 407 | #program-container .p_positive { 408 | color: #5eae00; 409 | font-weight: bold; 410 | } 411 | #program-container .p_negative { 412 | color: #d13535; 413 | font-weight: bold; 414 | } 415 | #program-container .p_null { 416 | color: #AAA; 417 | font-weight: bold; 418 | } 419 | -------------------------------------------------------------------------------- /css/dataTables.bootstrap.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable{border-collapse:separate !important}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0} 2 | -------------------------------------------------------------------------------- /data-grabber.php: -------------------------------------------------------------------------------- 1 | enableDemoMode(); 22 | } 23 | 24 | if( isset($t_options['g']) ) { 25 | $bbstats->setProgram( $t_options['g'] ); 26 | } 27 | 28 | if( isset($t_options['p']) ) { 29 | $p = $t_options['p']; 30 | $class = CLASS_PATH.'/class.'.$p.'.php'; 31 | if( !is_file($class) ) { 32 | Utils::help( '"'.$p.'" platform not found!' ); 33 | } 34 | $bbstats->setPlatform( $p ); 35 | } 36 | 37 | if( isset($t_options['f']) ) { 38 | if( !$bbstats->setSourceFile($t_options['f']) ) { 39 | Utils::help( '"'.$t_options['f'].'" source file not found!' ); 40 | } 41 | } 42 | 43 | if( isset($t_options['a']) ) { 44 | if( !$bbstats->setAction($t_options['a']) ) { 45 | Utils::help( 'Unknown action!' ); 46 | } 47 | } 48 | 49 | if( isset($t_options['n']) ) { 50 | $bbstats->setQuantity( (int)$t_options['n'] ); 51 | } 52 | 53 | if( isset($t_options['r']) ) { 54 | $bbstats->setAutoRateMode( is_array($t_options['r']) ? 2 : 1 ); 55 | } 56 | 57 | if( isset($t_options['t']) ) { 58 | $bbstats->setAutoTagMode( is_array($t_options['t']) ? 2 : 1 ); 59 | } 60 | 61 | if( isset($t_options['e']) ) { 62 | $bbstats->enableReputation(); 63 | } 64 | } 65 | // --- 66 | 67 | 68 | // program import mode 69 | if( $bbstats->getProgram() ) 70 | { 71 | $p = $bbstats->getPlatform(); 72 | $grabber = new $p(); 73 | 74 | $grabber->login(); 75 | //echo "\n"; 76 | 77 | Utils::printInfo( 'Trying to connect.' ); 78 | if( ($c=$grabber->connect()) <= 0 ) { 79 | Utils::printError( 'Cannot connect to '.$grabber->getName().'! ('.$c.')' ); 80 | exit(); 81 | } 82 | Utils::printSuccess( 'Connected to '.$grabber->getName().'.' ); 83 | 84 | Utils::printInfo( 'Grabbing program infos.' ); 85 | $infos = $grabber->getProgramInfos( $bbstats->getProgram() ); 86 | if( !$infos ) { 87 | Utils::printError( 'Cannot find the program "'.$bbstats->getProgram().'" on '.$grabber->getName().'!' ); 88 | exit(); 89 | } 90 | Utils::printSuccess( 'Program found.' ); 91 | 92 | $program = new Program(); 93 | $program->setPlatform( $grabber->getName() ); 94 | $program->setInfos( $infos ); 95 | 96 | Utils::printInfo( 'Grabbing hacktivity.' ); 97 | $h = $grabber->grabProgramHacktivity( $bbstats->getProgram(), $t_reports ); 98 | if( !$h ) { 99 | Utils::printError( 'Cannot grab hacktivity !' ); 100 | exit(); 101 | } 102 | echo "\n"; 103 | Utils::printSuccess( 'Hacktivity grabbed.' ); 104 | 105 | $cnt = $program->computeHacktivity( $t_reports ); 106 | Utils::printSuccess( $cnt.' reports found.' ); 107 | 108 | Utils::printInfo( 'Grabbing disclosed reports.' ); 109 | $n_bugs = $grabber->grabProgramReports(); 110 | if( !$n_bugs ) { 111 | Utils::printError( 'Cannot retrieve reports!' ); 112 | exit(); 113 | } 114 | Utils::printSuccess( $n_bugs.' reports imported.' ); 115 | 116 | $grabber->extractReportDatas(); 117 | Utils::printSuccess( 'Datas extracted.' ); 118 | 119 | if( $bbstats->getAutoTagMode() ) { 120 | Utils::printInfo( 'Trying to guess tags.' ); 121 | Report::massAutoTag( $grabber->getReportsFinal() ); 122 | Utils::printSuccess( 'Autotag finished.' ); 123 | } 124 | 125 | if( $bbstats->getAutoRateMode() ) { 126 | Utils::printInfo( 'Trying to guess rating.' ); 127 | Report::massAutoRate( $grabber->getReportsFinal() ); 128 | Utils::printSuccess( 'Autorate finished.' ); 129 | } 130 | 131 | Utils::printInfo( 'Adding new reports.' ); 132 | $program->setReports( $grabber->getReportsFinal() ); 133 | 134 | Utils::printInfo( 'Saving programs datas.' ); 135 | if( !$program->save() ) { 136 | Utils::printError( 'Cannot save program!' ); 137 | exit(); 138 | } 139 | Utils::printSuccess( 'Program saved.' ); 140 | 141 | Utils::printInfo( 'Exiting.' ); 142 | exit(); 143 | } 144 | // end of program import 145 | 146 | 147 | // user import mode 148 | { 149 | //load current database 150 | { 151 | Utils::printInfo( 'Loading current database.' ); 152 | $db = Database::getInstance(); 153 | if( !$db->load(DATABASE_FILE) ) { 154 | Utils::printError( 'Cannot load database!' ); 155 | exit(); 156 | } 157 | Utils::printSuccess( 'Database loaded.' ); 158 | $bbstats->setDatabase( $db ); 159 | 160 | echo "\n"; 161 | } 162 | // --- 163 | 164 | 165 | // someone ordered a rollback here! 166 | { 167 | if( $bbstats->getAction() == 'r' ) 168 | { 169 | $t_backups = glob( DATABASE_PATH.'/db.json.*' ); 170 | rsort( $t_backups ); 171 | 172 | if( !count($t_backups) ) { 173 | Utils::printError( 'No history found!' ); 174 | exit(); 175 | } 176 | 177 | $restore = basename( $t_backups['0'] ); 178 | $r = rename( DATABASE_PATH.'/'.$restore, DATABASE_FILE ); 179 | if( !$r ) { 180 | Utils::printError( 'Cannot restore database!' ); 181 | exit(); 182 | } 183 | 184 | Utils::printSuccess( 'Backup "'.$restore.'" restored.' ); 185 | exit(); 186 | } 187 | } 188 | 189 | 190 | // process 191 | { 192 | $p = $bbstats->getPlatform(); 193 | $grabber = new $p(); 194 | 195 | if( !$bbstats->isImport() ) 196 | { 197 | $grabber->login(); 198 | //echo "\n"; 199 | 200 | Utils::printInfo( 'Trying to connect.' ); 201 | if( ($c=$grabber->connect()) <= 0 ) { 202 | Utils::printError( 'Cannot connect to '.$grabber->getName().'! ('.$c.')' ); 203 | exit(); 204 | } 205 | Utils::printSuccess( 'Connected to '.$grabber->getName().'.' ); 206 | } 207 | 208 | Utils::printInfo( 'Grabbing user infos.' ); 209 | $t_user_infos = $grabber->getUserInfos(); 210 | if( $t_user_infos == null ) { 211 | Utils::printError( 'Cannot grab user infos!' ); 212 | exit(); 213 | } else { 214 | Utils::printSuccess( 'Got user infos.' ); 215 | $db->setUserInfos( $t_user_infos ); 216 | } 217 | 218 | if( $bbstats->isReputation() ) { 219 | Utils::printInfo( 'Grabbing reputation.' ); 220 | $t_reputation = $grabber->grabReputation(); 221 | if( $t_reputation == null ) { 222 | Utils::printError( 'Cannot grab reputation!' ); 223 | $t_reputation = null; 224 | } else { 225 | Utils::printSuccess( 'Got reputation points.' ); 226 | } 227 | } else { 228 | $t_reputation = null; 229 | } 230 | 231 | Utils::printInfo( 'Retrieving report list.' ); 232 | $n_page = $grabber->grabReportList( $bbstats->getQuantity() ); 233 | echo "\n"; 234 | if( !$n_page ) { 235 | Utils::printError( 'Cannot retrieve report list!' ); 236 | exit(); 237 | } 238 | Utils::printSuccess( $n_page.' pages imported.' ); 239 | 240 | Utils::printInfo( 'Grabbing reports.' ); 241 | $n_bugs = $grabber->grabReports( $bbstats->getQuantity(), $t_reputation ); 242 | if( !$n_bugs ) { 243 | Utils::printError( 'Cannot retrieve reports!' ); 244 | exit(); 245 | } 246 | Utils::printSuccess( $n_bugs.' reports imported.' ); 247 | 248 | $grabber->extractReportDatas(); 249 | Utils::printSuccess( 'Datas extracted.' ); 250 | 251 | if( $bbstats->getAutoTagMode() ) { 252 | Utils::printInfo( 'Trying to guess tags.' ); 253 | Report::massAutoTag( $grabber->getReportsFinal() ); 254 | Utils::printSuccess( 'Autotag finished.' ); 255 | } 256 | 257 | if( $bbstats->getAutoRateMode() ) { 258 | Utils::printInfo( 'Trying to guess rating.' ); 259 | Report::massAutoRate( $grabber->getReportsFinal() ); 260 | Utils::printSuccess( 'Autorate finished.' ); 261 | } 262 | 263 | if( $bbstats->isDemo() ) { 264 | $grabber->setReportsFinal( Utils::demonize($grabber->getReportsFinal()) ); 265 | } 266 | 267 | Utils::printInfo( 'Adding new reports.' ); 268 | list($n_new,$n_update) = $db->add( $grabber->getReportsFinal() ); 269 | if( !$n_new && !$n_update ) { 270 | Utils::printError( 'Nothing new!' ); 271 | exit(); 272 | } 273 | Utils::printSuccess( $n_new.' new reports added, '.$n_update.' reports updated.' ); 274 | } 275 | // --- 276 | 277 | 278 | // save datas 279 | { 280 | Utils::printInfo( 'Backuping the database.' ); 281 | $bak = $db->backup(); 282 | if( !$bak ) { 283 | Utils::printError( 'Cannot create backup!' ); 284 | exit(); 285 | } 286 | Utils::printSuccess( 'Backup created -> '.$bak ); 287 | 288 | Utils::printInfo( 'Saving new database.' ); 289 | if( !$db->save() ) { 290 | Utils::printError( 'Cannot save database!' ); 291 | exit(); 292 | } 293 | Utils::printSuccess( 'Database saved -> '.$db->getDbFile() ); 294 | } 295 | // --- 296 | 297 | Utils::printInfo( 'Exiting.' ); 298 | exit(); 299 | } // end of user import 300 | 301 | -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /graph/graph_bounties.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 |
14 |
15 | 16 | 112 | -------------------------------------------------------------------------------- /graph/graph_bounties_reports_reputation.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 |
14 |
15 | 16 | 95 | -------------------------------------------------------------------------------- /graph/graph_program_bounty.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |
18 | 19 | 20 | 111 | -------------------------------------------------------------------------------- /graph/graph_program_evolution_rating.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |
18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
None:0$
Low:1$ - getBountyRange()['medium']-1; ?>$
Medium:getBountyRange()['medium']; ?>$ - getBountyRange()['high']-1; ?>$
High:getBountyRange()['high']; ?>$ - getBountyRange()['critical']-1; ?>$
Critical:getBountyRange()['critical']; ?>$ - ∞
45 |
46 |
47 | 48 | 49 | 209 | -------------------------------------------------------------------------------- /graph/graph_program_evolution_severity.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |
18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
None:0$
Low:1$ - getBountyRange()['medium']-1; ?>$
Medium:getBountyRange()['medium']; ?>$ - getBountyRange()['high']-1; ?>$
High:getBountyRange()['high']; ?>$ - getBountyRange()['critical']-1; ?>$
Critical:getBountyRange()['critical']; ?>$ - ∞
45 |
46 |
47 | 48 | 49 | 184 | -------------------------------------------------------------------------------- /graph/graph_program_times.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |
18 | 19 | 20 | 94 | -------------------------------------------------------------------------------- /graph/graph_program_times2.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 |
17 |
18 | 19 | 20 | 94 | -------------------------------------------------------------------------------- /graph/graph_program_times_resolution.php: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 |
19 |
20 | 21 | 76 | -------------------------------------------------------------------------------- /graph/graph_program_times_triage.php: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 |
19 |
20 | 21 | 82 | -------------------------------------------------------------------------------- /graph/graph_reports_platforms_pie.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 | 14 | 105 | -------------------------------------------------------------------------------- /graph/graph_reports_programs_pie.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 | 14 | 105 | -------------------------------------------------------------------------------- /graph/graph_reports_ratings.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 |
14 |
15 | 16 | 153 | -------------------------------------------------------------------------------- /graph/graph_reports_ratings_pie.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 | 14 | 104 | -------------------------------------------------------------------------------- /graph/graph_reports_severity_pie.php: -------------------------------------------------------------------------------- 1 | 14 | 15 |
16 | 17 | 102 | -------------------------------------------------------------------------------- /graph/graph_reports_state_pie.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 12 | exit( 'Cannot load database, you should run the grabber first!' ); 13 | } 14 | } 15 | 16 | ?> 17 | 18 |
19 | 20 | 115 | -------------------------------------------------------------------------------- /graph/graph_reports_tags_pie.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 12 | exit( 'Cannot load database, you should run the grabber first!' ); 13 | } 14 | } 15 | 16 | ?> 17 | 18 |
19 | 20 | 117 | -------------------------------------------------------------------------------- /graph/graph_tags_evolution.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | ?> 11 | 12 |
13 |
14 |
15 | 16 | 80 | -------------------------------------------------------------------------------- /graph/top_program_best_hackers.php: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |
20 |

Top hackers

21 |
22 |
23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 | -------------------------------------------------------------------------------- /graph/top_program_best_spammers.php: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |
20 |

Top spammers

21 |
22 |
23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 | 35 |
36 | -------------------------------------------------------------------------------- /graph/top_programs.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | $t_top = Statistics::top_program_html( $db ); 11 | //var_dump( $t_top ); 12 | 13 | ?> 14 | 15 |
16 |
17 |

Top programs

18 |
19 |
20 |
21 |
22 | 23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 | -------------------------------------------------------------------------------- /graph/top_tags.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | $t_top = Statistics::top_tags_html( $db ); 11 | //var_dump( $t_top ); 12 | 13 | ?> 14 | 15 |
16 |
17 |

Top tags

18 |
19 |
20 |
21 |
22 | 23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 | -------------------------------------------------------------------------------- /img/bountyfactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/bountyfactory.png -------------------------------------------------------------------------------- /img/bugcrowd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/bugcrowd.png -------------------------------------------------------------------------------- /img/cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/cc.png -------------------------------------------------------------------------------- /img/cobalt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/cobalt.png -------------------------------------------------------------------------------- /img/hackerone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/hackerone.png -------------------------------------------------------------------------------- /img/sample-bounty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-bounty.png -------------------------------------------------------------------------------- /img/sample-evolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-evolution.png -------------------------------------------------------------------------------- /img/sample-grabber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-grabber.png -------------------------------------------------------------------------------- /img/sample-listing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-listing.png -------------------------------------------------------------------------------- /img/sample-program-repartition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-program-repartition.png -------------------------------------------------------------------------------- /img/sample-report-rating.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/sample-report-rating.png -------------------------------------------------------------------------------- /img/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/stop.png -------------------------------------------------------------------------------- /img/unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/unknown.png -------------------------------------------------------------------------------- /img/yogosha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gwen001/BBstats/35288e9dcaaf143e92c66a4e444edc521acba652/img/yogosha.png -------------------------------------------------------------------------------- /include/filters_form.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 | 7 | 8 |
9 |
10 |
11 |
12 |
13 | 14 |
15 | 16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 | 25 | 30 | -------------------------------------------------------------------------------- /include/hacker_infos.php: -------------------------------------------------------------------------------- 1 | 4 |
5 |

getName(); ?>

6 |
7 |
8 | Reputation: getTotalReputation(); ?>
9 | Signal: getSignal() ); ?>
10 | Impact: getImpact() ); ?>
11 |
12 |
13 | Report count: getTotalReport(); ?>
14 | First report: getFirstReportDate()); ?>
15 | Last report: getLastReportDate()); ?>
16 |
17 |
18 | Lowest bounty: getSmallestBounty(); ?>$
19 | Highest bounty: getHigherBounty(); ?>$
20 | Average bounty: getAverageBounty(); ?>$
21 |
22 |
23 | n - 1
24 | getReportsByMonth( date('m/Y',mktime(0,0,0,date('m')-1,date('d'),date('Y'))) ); 26 | $n0 = $db->getReportsByMonth( date('m/Y') ); 27 | $nd = $n0 - $n1; 28 | if( $nd < 0 ) { 29 | $c = 'p_negative'; 30 | $n = $nd; 31 | } elseif( $nd > 0 ) { 32 | $c = 'p_positive'; 33 | $n = '+'.$nd; 34 | } else { 35 | $c = 'p_null'; 36 | $n = '-'; 37 | } 38 | ?> 39 | Reports:
40 | getBountiesByMonth( date('m/Y',mktime(0,0,0,date('m')-1,date('d'),date('Y'))) ); 42 | $n0 = $db->getBountiesByMonth( date('m/Y') ); 43 | $nd = $n0 - $n1; 44 | if( $nd < 0 ) { 45 | $c = 'p_negative'; 46 | $n = $nd.'$'; 47 | } elseif( $nd > 0 ) { 48 | $c = 'p_positive'; 49 | $n = '+'.$nd.'$'; 50 | } else { 51 | $c = 'p_null'; 52 | $n = '-'; 53 | } 54 | ?> 55 | Bounties:
56 |
57 | -------------------------------------------------------------------------------- /include/listing.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | $r ) { 17 | $m = date( 'n', $r->getCreatedAt() ); 18 | $reput = $r->getTotalReputation(); 19 | //if( $m != $cm ) { $tr_class='new-month';$cm=$m; } else { $tr_class=''; } 20 | if( $r->getIgnore() ) { $tr_class='ignored'; } else { $tr_class=''; } 21 | ?> 22 | 23 | 36 | 48 | 51 | 54 | 63 | 66 | 67 | 69 | 70 |
TitleProgramBountyTagsCreatedAt
24 | getPlatform(); ?> 25 | getLink(); $p_icon='img/'.$r->getPlatform().'.png'; if( !is_file($p_icon) ) { $p_icon='img/unknown.png'; } ?> 26 | 27 | 28 | 29 | 30 | <?php echo $r->getPlatform().' - #'.$r->getId(); ?> 31 | 32 | 33 | 34 | 35 | 37 | s:getState(); ?> 38 | r:pgetRating(); ?> 39 | getTitle(); ?> 40 | 0 ) { ?> 41 | 42 | 43 | 44 | 45 | 0 46 | 47 | 49 | getProgram()); ?> 50 | 52 | getTotalBounty(); ?> $ 53 | 55 | getTags()) ) { 56 | foreach( $r->getTags() as $t ) { ?> 57 | 58 | 60 | untaged 61 | 62 | 64 | getCreatedAt()); ?> 65 |
71 |
-------------------------------------------------------------------------------- /include/popup_about.php: -------------------------------------------------------------------------------- 1 | 33 | 34 | 42 | -------------------------------------------------------------------------------- /include/popup_more.php: -------------------------------------------------------------------------------- 1 | 22 | 23 | 31 | -------------------------------------------------------------------------------- /include/popup_report_add.php: -------------------------------------------------------------------------------- 1 | 127 | 128 | 152 | -------------------------------------------------------------------------------- /include/popup_report_edit.php: -------------------------------------------------------------------------------- 1 | 133 | 134 | 266 | -------------------------------------------------------------------------------- /include/popup_tag_add.php: -------------------------------------------------------------------------------- 1 | 37 | 38 | 69 | -------------------------------------------------------------------------------- /include/program_infos.php: -------------------------------------------------------------------------------- 1 | 4 |
5 |

getName(); ?>

6 |
7 |
8 | Report count: getTotalReport(); ?>
9 | First report: getFirstReportDate()); ?>
10 | Last report: getLastReportDate()); ?>
11 |
12 |
13 | Lowest bounty: getSmallestBounty(); ?>$
14 | Highest bounty: getHigherBounty(); ?>$
15 | Average bounty: getAverageBounty(); ?>$
16 |
17 |
18 | n - 1
19 | getReportsByMonth( date('m/Y',mktime(0,0,0,date('m')-1,date('d'),date('Y'))) ); 21 | $n0 = $db->getReportsByMonth( date('m/Y') ); 22 | $nd = $n0 - $n1; 23 | if( $nd < 0 ) { 24 | $c = 'p_positive'; 25 | $n = $nd; 26 | } elseif( $nd > 0 ) { 27 | $c = 'p_negative'; 28 | $n = '+'.$nd; 29 | } else { 30 | $c = 'p_null'; 31 | $n = '-'; 32 | } 33 | ?> 34 | Reports:
35 | getBountiesByMonth( date('m/Y',mktime(0,0,0,date('m')-1,date('d'),date('Y'))) ); 37 | $n0 = $db->getBountiesByMonth( date('m/Y') ); 38 | $nd = $n0 - $n1; 39 | if( $nd < 0 ) { 40 | $c = 'p_positive'; 41 | $n = $nd.'$'; 42 | } elseif( $nd > 0 ) { 43 | $c = 'p_negative'; 44 | $n = '+'.$nd.'$'; 45 | } else { 46 | $c = 'p_null'; 47 | $n = '-'; 48 | } 49 | ?> 50 | Bounties:
51 |
52 | -------------------------------------------------------------------------------- /include/program_listing.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | $r ) { 16 | if( $r->getIgnore() ) { $tr_class='ignored'; } else { $tr_class=''; } 17 | ?> 18 | 19 | 24 | 27 | 30 | 39 | 42 | 43 | 45 | 46 |
TitleHackerBountyTagsCreatedAt
20 | s:getState(); ?> 21 | r:getSeverity(); ?> 22 | getTitle(); ?> 23 | 25 | getReporter()); ?> 26 | 28 | getTotalBounty(); ?> $ 29 | 31 | getTags()) ) { 32 | foreach( $r->getTags() as $t ) { ?> 33 | 34 | 36 | untaged 37 | 38 | 40 | getCreatedAt()); ?> 41 |
47 |
-------------------------------------------------------------------------------- /include/program_reports.php: -------------------------------------------------------------------------------- 1 |

Reports you can read ()

2 | 3 | 4 | hacktivity as $r ) { 5 | if( $r->title ) { ?> 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 |
getCreatedAt()); ?>getTitle(); ?>getTotalBounty(); ?>$
15 | 16 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | load(DATABASE_FILE) ) { 7 | exit( 'Cannot load database, you should run the grabber first!' ); 8 | } 9 | 10 | $t_reports = $db->getReports(); 11 | //$start_date = date( 'd/m/Y', $db->getFirstReportDate() ); 12 | //$end_date = date( 'd/m/Y' ); 13 | 14 | ?> 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Your bug bounty stats 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | 49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 |
66 | 67 |
68 | 69 |
70 | 71 | 72 |
73 | 74 |
75 | 76 | 77 |
78 | 79 |
80 | 81 |
82 | 83 |
84 | 85 |
86 | 87 | 88 |
89 | 90 |
91 | 92 | 93 |
94 | 95 |
96 | 97 | 98 |
99 | 100 |
101 | 102 | 103 |
104 | 105 |
106 | 107 |
108 | 109 | 110 | 111 |
112 | 113 |
114 |
115 | 116 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /js/dataTables.bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 3 integration 3 | ©2011-2015 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes, 6 | {sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,m,j,n){var o=new f.Api(a),s=a.oClasses,k=a.oLanguage.oPaginate,t=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")}; 7 | l=0;for(h=f.length;l",{"class":s.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#", 8 | "aria-controls":a.sTableId,"aria-label":t[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(u){}q(b(h).empty().html('