31
31
from .config import Config , running_path , package_path
32
32
from .engine import Running
33
33
from .log import logger
34
- from .utils import allowed_file , secure_filename , PY2
34
+ from .utils import allowed_file , secure_filename , PY2 , split_branch
35
35
36
36
try :
37
37
# Python 3
@@ -299,8 +299,57 @@ def post():
299
299
else :
300
300
return {'code' : 1002 , 'msg' : 'No such file.' }
301
301
302
- return {'code' : 1001 , 'result' : {'file_content' : file_content ,
303
- 'extension' : extension }}
302
+ return {'code' : 1001 , 'result' : {'file_content' : file_content , 'extension' : extension }}
303
+
304
+
305
+ class Search (Resource ):
306
+ @staticmethod
307
+ def post ():
308
+ """
309
+ Search specific rule.
310
+ :return:
311
+ """
312
+ data = request .json
313
+ if not data or data == "" :
314
+ return {'code' : 1003 , 'msg' : 'Only support json, please post json data.' }
315
+
316
+ sid = data .get ('sid' )
317
+ if not sid or sid == '' :
318
+ return {'code' : 1002 , 'msg' : 'sid is required.' }
319
+
320
+ rule_id = data .get ('rule_id' )
321
+ if not rule_id or rule_id == '' :
322
+ return {'code' : 1002 , 'msg' : 'rule_id is required.' }
323
+
324
+ scan_list_file = os .path .join (running_path , '{sid}_list' .format (sid = sid ))
325
+ if not os .path .exists (scan_list_file ):
326
+ return {'code' : 1002 , 'msg' : 'No such sid.' }
327
+
328
+ with open (scan_list_file , 'r' ) as f :
329
+ scan_list = json .load (f )
330
+
331
+ if not isinstance (rule_id , list ):
332
+ rule_id = [rule_id ]
333
+
334
+ search_data = list ()
335
+ for s_sid in scan_list .get ('sids' ).keys ():
336
+ target , branch = split_branch (scan_list .get ('sids' ).get (s_sid ))
337
+ search_result = search_rule (s_sid , rule_id )
338
+ if list (search_result .items ()).count (0 ) == len (rule_id ):
339
+ continue
340
+ search_data .append ({
341
+ 'target_info' : {
342
+ 'sid' : s_sid ,
343
+ 'target' : target ,
344
+ 'branch' : branch ,
345
+ },
346
+ 'search_result' : search_result ,
347
+ })
348
+
349
+ return {
350
+ 'code' : 1001 ,
351
+ 'result' : search_data ,
352
+ }
304
353
305
354
306
355
@app .route ('/' , methods = ['GET' , 'POST' ])
@@ -333,13 +382,7 @@ def summary():
333
382
if scan_status .get ('result' ).get ('status' ) == 'running' :
334
383
still_running = scan_status .get ('result' ).get ('still_running' )
335
384
for s_sid , target_str in still_running .items ():
336
- split_target = target_str .split (':' )
337
- if len (split_target ) == 3 :
338
- target , branch = '{p}:{u}' .format (p = split_target [0 ], u = split_target [1 ]), split_target [- 1 ]
339
- elif len (split_target ) == 2 :
340
- target , branch = target_str , 'master'
341
- else :
342
- target , branch = target_str , 'master'
385
+ target , branch = split_branch (target_str )
343
386
still_running [s_sid ] = {'target' : target ,
344
387
'branch' : branch }
345
388
else :
@@ -357,21 +400,16 @@ def summary():
357
400
not_finished_number = scan_status .get ('result' ).get ('not_finished' )
358
401
359
402
total_vul_number , critical_vul_number , high_vul_number , medium_vul_number , low_vul_number = 0 , 0 , 0 , 0 , 0
360
- rule_filter = dict ()
403
+ rule_num = dict ()
404
+ rules = dict ()
361
405
targets = list ()
362
406
363
407
for s_sid , target_str in scan_list .get ('sids' ).items ():
364
408
if s_sid not in still_running :
365
409
target_info = dict ()
366
410
367
411
# 分割项目地址与分支,默认 master
368
- split_target = target_str .split (':' )
369
- if len (split_target ) == 3 :
370
- target , branch = '{p}:{u}' .format (p = split_target [0 ], u = split_target [1 ]), split_target [- 1 ]
371
- elif len (split_target ) == 2 :
372
- target , branch = target_str , 'master'
373
- else :
374
- target , branch = target_str , 'master'
412
+ target , branch = split_branch (target_str )
375
413
376
414
target_info .update ({
377
415
'sid' : s_sid ,
@@ -403,9 +441,11 @@ def summary():
403
441
low_vul_number += 1
404
442
405
443
try :
406
- rule_filter [vul .get ('rule_name' )] += 1
444
+ rule_num [vul .get ('rule_name' )] += 1
407
445
except KeyError :
408
- rule_filter [vul .get ('rule_name' )] = 1
446
+ rule_num [vul .get ('rule_name' )] = 1
447
+
448
+ rules [vul .get ('id' )] = vul .get ('rule_name' )
409
449
410
450
return render_template (template_name_or_list = 'summary.html' ,
411
451
total_targets_number = total_targets_number ,
@@ -418,7 +458,8 @@ def summary():
418
458
high_vul_number = high_vul_number ,
419
459
medium_vul_number = medium_vul_number ,
420
460
low_vul_number = low_vul_number ,
421
- vuls = rule_filter ,
461
+ rule_num = rule_num ,
462
+ rules = rules ,
422
463
running = still_running ,)
423
464
424
465
@@ -461,6 +502,30 @@ def guess_type(fn):
461
502
return extension .lower ()
462
503
463
504
505
+ def search_rule (sid , rule_id ):
506
+ """
507
+ Search specific rule name in scan data.
508
+ :param sid: scan data id
509
+ :param rule_id: a list of rule name
510
+ :return: {rule_name1: num1, rule_name2: num2}
511
+ """
512
+ scan_data_file = os .path .join (running_path , '{sid}_data' .format (sid = sid ))
513
+ search_result = dict .fromkeys (rule_id , 0 )
514
+ if not os .path .exists (scan_data_file ):
515
+ return search_result
516
+
517
+ with open (scan_data_file , 'r' ) as f :
518
+ scan_data = json .load (f )
519
+
520
+ if scan_data .get ('code' ) == 1001 and len (scan_data .get ('result' ).get ('vulnerabilities' )) > 0 :
521
+ for vul in scan_data .get ('result' ).get ('vulnerabilities' ):
522
+ if vul .get ('id' ) in rule_id :
523
+ search_result [vul .get ('id' )] += 1
524
+ return search_result
525
+ else :
526
+ return search_result
527
+
528
+
464
529
def start (host , port , debug ):
465
530
logger .info ('Start {host}:{port}' .format (host = host , port = port ))
466
531
api = Api (app )
@@ -470,6 +535,7 @@ def start(host, port, debug):
470
535
api .add_resource (FileUpload , '/api/upload' )
471
536
api .add_resource (ResultData , '/api/list' )
472
537
api .add_resource (ResultDetail , '/api/detail' )
538
+ api .add_resource (Search , '/api/search' )
473
539
474
540
# consumer
475
541
threads = []
0 commit comments