├── .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 |
7 |
8 |
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 |
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 |
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 |
15 |
16 |
95 |
--------------------------------------------------------------------------------
/graph/graph_program_bounty.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
18 |
19 |
20 |
111 |
--------------------------------------------------------------------------------
/graph/graph_program_evolution_rating.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 | None:
25 | 0$
26 |
27 |
28 | Low:
29 | 1$ - getBountyRange()['medium']-1; ?>$
30 |
31 |
32 | Medium:
33 | getBountyRange()['medium']; ?>$ - getBountyRange()['high']-1; ?>$
34 |
35 |
36 | High:
37 | getBountyRange()['high']; ?>$ - getBountyRange()['critical']-1; ?>$
38 |
39 |
40 | Critical:
41 | getBountyRange()['critical']; ?>$ - ∞
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
209 |
--------------------------------------------------------------------------------
/graph/graph_program_evolution_severity.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 | None:
25 | 0$
26 |
27 |
28 | Low:
29 | 1$ - getBountyRange()['medium']-1; ?>$
30 |
31 |
32 | Medium:
33 | getBountyRange()['medium']; ?>$ - getBountyRange()['high']-1; ?>$
34 |
35 |
36 | High:
37 | getBountyRange()['high']; ?>$ - getBountyRange()['critical']-1; ?>$
38 |
39 |
40 | Critical:
41 | getBountyRange()['critical']; ?>$ - ∞
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
184 |
--------------------------------------------------------------------------------
/graph/graph_program_times.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
18 |
19 |
20 |
94 |
--------------------------------------------------------------------------------
/graph/graph_program_times2.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
18 |
19 |
20 |
94 |
--------------------------------------------------------------------------------
/graph/graph_program_times_resolution.php:
--------------------------------------------------------------------------------
1 |
16 |
17 |
20 |
21 |
76 |
--------------------------------------------------------------------------------
/graph/graph_program_times_triage.php:
--------------------------------------------------------------------------------
1 |
16 |
17 |
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 |
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 |
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 |
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 |
24 |
25 |
30 |
--------------------------------------------------------------------------------
/include/hacker_infos.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
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 | Title
7 | Program
8 | Bounty
9 | Tags
10 | CreatedAt
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 |
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 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | s:getState(); ?>
38 | r:pgetRating(); ?>
39 | getTitle(); ?>
40 | 0 ) { ?>
41 |
42 |
43 |
44 |
45 | 0
46 |
47 |
48 |
49 | getProgram()); ?>
50 |
51 |
52 | getTotalBounty(); ?> $
53 |
54 |
55 | getTags()) ) {
56 | foreach( $r->getTags() as $t ) { ?>
57 |
58 |
60 | untaged
61 |
62 |
63 |
64 | getCreatedAt()); ?>
65 |
66 |
67 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/include/popup_about.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
Platform
10 |
11 | For the moment only Hackerone is supported, but I'm waiting for your help to implement other platforms.
12 | Any ideas are welcome: https://github.com/gwen001/BBstats
13 |
14 |
Recommendation
15 |
16 | It's not recommanded to manually change creation dates of reports and bounty amounts.
17 | Tags are a good way to set the type of a vulnerability: rce, xss, sqli, idor...
18 |
19 |
Disclaimer
20 |
21 | This program performs only read actions.
22 | It doesn't store any sensitive details of the reports. Only the following datas are used:
23 | id, program, title, reputation, bounties, state, creation date.
24 |
25 |
License
26 |
27 | This program is MIT licensed.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
42 |
--------------------------------------------------------------------------------
/include/popup_more.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 | You have submitted a total of getTotalReport(); ?> reports, earn getTotalBounty(); ?> $ and your reputation is now getTotalReputation(); ?> .
11 |
12 |
13 | getFirstReportDate())) ); $diff_m=($diff->y*12)+$diff->m+2; ?>
14 | Your average report per month is: getTotalReport()/$diff_m) ); ?> .
15 | Your average bounty per month is: getTotalBounty()/$diff_m) ); ?> $ .
16 | Your average reputation per month is: getTotalReputation()/$diff_m) ); ?> .
17 |
18 |
19 |
20 |
21 |
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 |
2 |
3 |
4 |
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 | Title
6 | Hacker
7 | Bounty
8 | Tags
9 | CreatedAt
10 |
11 |
12 |
13 | $r ) {
16 | if( $r->getIgnore() ) { $tr_class='ignored'; } else { $tr_class=''; }
17 | ?>
18 |
19 |
20 | s:getState(); ?>
21 | r:getSeverity(); ?>
22 | getTitle(); ?>
23 |
24 |
25 | getReporter()); ?>
26 |
27 |
28 | getTotalBounty(); ?> $
29 |
30 |
31 | getTags()) ) {
32 | foreach( $r->getTags() as $t ) { ?>
33 |
34 |
36 | untaged
37 |
38 |
39 |
40 | getCreatedAt()); ?>
41 |
42 |
43 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/include/program_reports.php:
--------------------------------------------------------------------------------
1 | Reports you can read ( )
2 |
3 |
4 | hacktivity as $r ) {
5 | if( $r->title ) { ?>
6 |
7 | getCreatedAt()); ?>
8 | getTitle(); ?>
9 | getTotalBounty(); ?>$
10 |
11 |
13 |
14 |
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 |
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('').children("ul"),m);i&&b(h).find("[data-dt-idx="+i+"]").focus()};return f});
9 |
--------------------------------------------------------------------------------
/program.php:
--------------------------------------------------------------------------------
1 | getReports();
14 |
15 | ?>
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Your bug bounty stats
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
45 |
50 |
55 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
87 |
92 |
97 |
98 |
99 |
100 |
101 |
102 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/quh1.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $# -eq 1 ]; then
4 | n=$1
5 | else
6 | n=50
7 | fi
8 |
9 | php data-grabber.php -p hackerone -g security -a u -r -t
10 |
--------------------------------------------------------------------------------
/quick-init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | php data-grabber.php -p hackerone -a n -rr -tt -e
4 |
--------------------------------------------------------------------------------
/quick-update.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ $# -eq 1 ]; then
4 | n=$1
5 | else
6 | n=50
7 | fi
8 |
9 | php data-grabber.php -p hackerone -a u -r -t -e -n $n
10 |
--------------------------------------------------------------------------------