Skip to content

Commit d5bb3c5

Browse files
committed
add scanType support
支持扫描类型:根据用户需要的扫描类型扫描漏洞,例如scanType = 'SQLI',则扫描SQLI漏洞
1 parent ca85475 commit d5bb3c5

File tree

7 files changed

+186
-92
lines changed

7 files changed

+186
-92
lines changed

CFGGenerator.php

+12-65
Original file line numberDiff line numberDiff line change
@@ -470,16 +470,19 @@ private function sinkFunctionHandler($node,$block,$parentBlock){
470470

471471

472472
/**
473-
* 检测是否为sink函数
473+
* 处理函数调用
474474
* @param node $node
475475
* @param BasicBlock $block
476476
* @param fileSummary $fileSummary
477477
*/
478478
private function functionHandler($node,$block, $fileSummary){
479+
//根据用户指定的扫描类型,查找相类型的sink函数
480+
global $scan_type;
481+
479482
//获取调用的函数名判断是否是sink调用
480483
$funcName = NodeUtils::getNodeFunctionName($node);
481484
//判断是否为sink函数,返回格式为array(true,funcname) or array(false)
482-
$ret = NodeUtils::isSinkFunction($funcName);
485+
$ret = NodeUtils::isSinkFunction($funcName, $scan_type);
483486
if($ret[0]){
484487
//如果发现了sink调用,启动污点分析
485488
$analyser = new TaintAnalyser() ;
@@ -607,63 +610,6 @@ public function simulate($block){
607610
case 'Expr_Print':
608611
case 'Expr_FuncCall':
609612
echo "<pre>";
610-
//获取调用的函数名判断是否是sink调用
611-
$funcName = NodeUtils::getNodeFunctionName($node);
612-
//判断是否为sink函数,返回格式为array(true,funcname) or array(false)
613-
$ret = NodeUtils::isSinkFunction($funcName);
614-
if($ret[0]){
615-
//如果发现了sink调用,启动污点分析
616-
$analyser = new TaintAnalyser() ;
617-
618-
//获取危险参数的位置
619-
$argPosition = NodeUtils::getVulArgs($node) ;
620-
if(count($argPosition) == 0){
621-
break ;
622-
}
623-
624-
//获取到危险参数位置的变量
625-
$argArr = NodeUtils::getFuncParamsByPos($node, $argPosition);
626-
627-
//遍历危险参数名,调用污点分析函数
628-
if(count($argArr) > 0){
629-
foreach ($argArr as $item){
630-
if(is_array($item)){
631-
foreach ($item as $v){
632-
$analyser->analysis($block, $node, $v, $this->fileSummary) ;
633-
}
634-
}else{
635-
$analyser->analysis($block, $node, $item, $this->fileSummary) ;
636-
}
637-
638-
}
639-
640-
}
641-
642-
}else{
643-
//如果不是sink调用,启动过程间分析
644-
$context = Context::getInstance() ;
645-
$funcBody = $context->getClassMethodBody($funcName,$this->fileSummary->getPath(),$this->fileSummary->getIncludeMap());
646-
if(!$funcBody) break ;
647-
648-
$nextblock = $this->CFGBuilder($funcBody->stmts, NULL, NULL, NULL) ;
649-
//ret危险参数的位置比如:array(0)
650-
$ret = $this->functionHandler($funcBody, $nextblock, $block);
651-
if(!$ret){
652-
break;
653-
}
654-
655-
//找到了array('del',array(0)) ;
656-
$userDefinedSink = UserDefinedSinkContext::getInstance() ;
657-
658-
//$type应该从visitor中获取,使用$ret返回
659-
$type = $ret['type'] ;
660-
unset($ret['type']) ;
661-
662-
//加入用户sink上下文
663-
$item = array($funcName,$ret) ;
664-
$userDefinedSink->addByTagName($item, $type) ;
665-
}
666-
667613
$this->functionHandler($node, $block, $this->fileSummary);
668614
break ;
669615
}
@@ -1042,19 +988,20 @@ public function sinkTracebackBlock($argName,$block,$flowsNum){
1042988
}
1043989
}
1044990

1045-
991+
$scan_type = 'XSS';
1046992
echo "<pre>" ;
1047993
//从用户那接受项目路径
1048994
$project_path = 'F:/wamp/www/phpvulhunter/test';
1049995
//初始化
1050996
$initModule = new InitModule() ;
1051997
$initModule->init($project_path) ;
1052998

1053-
//$path = 'F:/wamp/www/phpvulhunter/test/simple_demo.php';
1054-
//$absPath = $path;
1055-
//$ret = FileSummaryGenerator::getFileSummary($absPath);
1056-
//print_r($ret);
1057-
//FileSummaryGenerator::getIncludeFilesDataFlows($ret);
999+
// $path = 'F:/wamp/www/phpvulhunter/test/simple_demo.php';
1000+
// $absPath = $path;
1001+
// $ret = FileSummaryGenerator::getFileSummary($absPath);
1002+
// print_r($ret);
1003+
// $retFlows = FileSummaryGenerator::getIncludeFilesDataFlows($ret);
1004+
// print_r($retFlows);
10581005

10591006
$cfg = new CFGGenerator() ;
10601007
$visitor = new MyVisitor() ;

FileSummaryGenerator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public static function getFileSummary($absPath){
5454
foreach ($nodes as $node){
5555
//搜集节点中的require include require_once include_once的PHP文件名称
5656
$fileSummary->addIncludeToMap(NodeUtils::getNodeIncludeInfo($node)) ;
57-
57+
5858
if(!is_object($node)) continue ;
5959

6060
//不分析函数定义

summary/FileSummary.class.php

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public function addDataFlow($dataFlow){
5050
public function addIncludeToMap($include){
5151
if($include){
5252
array_push($this->includeMap,$include) ;
53+
$this->includeMap = array_unique($this->includeMap);
5354
}
5455
}
5556

test/simple_demo.php

+24-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
<?php
2+
23
require_once '/a.php';
34
require_once './source.php';
45
require_once '../../b.php';
56

6-
$a = 2;
7-
$d = 123;
8-
$s = 1234;
9-
$a .= 23;
7+
function goods_del($s,$id)
8+
{
9+
$a = $id;
10+
del2($a,$b);
11+
$d = mysql_query($s);
12+
13+
}
14+
15+
function del2($where,$hi)
16+
{
17+
$where = ' WHERE '.$where;
18+
$sql = 'DELETE FROM '.$where;
19+
$sql = jinghua($sql1,$hi);
20+
$sql = $sql;
21+
return mysql_query($sql);
22+
}
23+
24+
function jinghua($str,$str1){
25+
$str1 = addslashes($str1);
26+
return addslashes($str);
27+
}
28+
29+
1030
goods_del($id) ;
1131
?>

test/test/a.php

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<?php
2+
require_once 'c.php';
23
$a = 111;
34
?>

test/test/c.php

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
$c = 3;
3+
?>

utils/NodeUtils.class.php

+144-22
Original file line numberDiff line numberDiff line change
@@ -332,33 +332,155 @@ public static function getNodeIncludeInfo($node){
332332
* @param string $funcName
333333
* @return array(is_sink,args_position)
334334
*/
335-
public static function isSinkFunction($funcName){
336-
global $F_SINK_ALL,$F_SINK_ARRAY ;
335+
public static function isSinkFunction($funcName, $scanType){
336+
global $F_SINK_ALL, $F_SINK_ARRAY ;
337337
$nameNum = count($F_SINK_ARRAY);
338338
$userDefinedSink = UserDefinedSinkContext::getInstance() ;
339339
$U_SINK_ALL = $userDefinedSink->getAllSinks() ;
340340

341-
//如果是系统的sink
342-
if(key_exists($funcName, $F_SINK_ALL)){
343-
for($i = 0;$i < $nameNum; $i++){
344-
if(key_exists($funcName, $F_SINK_ARRAY[$i])){
345-
return array(true,$F_SINK_ARRAY[$i][$funcName][0]);
346-
}
347-
}
348-
return array(false);
349-
}
350-
351-
//如果是用户的sink
352-
if(key_exists($funcName, $U_SINK_ALL)){
353-
foreach ($userDefinedSink->getAllSinkArray() as $value){
354-
if(key_exists($funcName, $value)){
355-
return array(true,$U_SINK_ALL[$funcName]) ;
356-
}
357-
}
358-
359-
return array(false) ;
341+
//根据scanType,查找sink函数
342+
switch ($scanType){
343+
case 'ALL':
344+
//如果是系统的sink
345+
if(key_exists($funcName, $F_SINK_ALL)){
346+
for($i = 0;$i < $nameNum; $i++){
347+
if(key_exists($funcName, $F_SINK_ARRAY[$i])){
348+
return array(true,$F_SINK_ARRAY[$i][$funcName][0]);
349+
}
350+
}
351+
return array(false);
352+
}
353+
354+
//如果是用户的sink
355+
if(key_exists($funcName, $U_SINK_ALL)){
356+
foreach ($userDefinedSink->getAllSinkArray() as $value){
357+
if(key_exists($funcName, $value)){
358+
return array(true,$U_SINK_ALL[$funcName]) ;
359+
}
360+
}
361+
return array(false) ;
362+
}
363+
case 'XSS':
364+
global $F_XSS;
365+
//如果是系统的sink
366+
if (key_exists($funcName, $F_XSS)){
367+
return array(true, $F_XSS[$funcName][0]);
368+
}
369+
//如果是用户的sink
370+
if (key_exists($funcName, $userDefinedSink->getF_XSS())){
371+
return array(true,$U_SINK_ALL[$funcName]) ;
372+
}
373+
return array(false) ;
374+
break;
375+
case 'SQLI':
376+
global $F_DATABASE;
377+
//如果是系统的sink
378+
if (key_exists($funcName, $F_DATABASE)){
379+
return array(true, $F_DATABASE[$funcName][0]);
380+
}
381+
//如果是用户的sink
382+
if (key_exists($funcName, $userDefinedSink->getF_DATABASE())){
383+
return array(true,$U_SINK_ALL[$funcName]) ;
384+
}
385+
return array(false) ;
386+
break;
387+
case 'HTTP':
388+
global $F_HTTP_HEADER;
389+
//如果是系统的sink
390+
if (key_exists($funcName, $F_HTTP_HEADER)){
391+
return array(true, $F_HTTP_HEADER[$funcName][0]);
392+
}
393+
//如果是用户的sink
394+
if (key_exists($funcName, $userDefinedSink->getF_HTTP_HEADER())){
395+
return array(true,$U_SINK_ALL[$funcName]) ;
396+
}
397+
return array(false) ;
398+
break;
399+
case 'CODE':
400+
global $F_CODE;
401+
//如果是系统的sink
402+
if (key_exists($funcName, $F_CODE)){
403+
return array(true, $F_CODE[$funcName][0]);
404+
}
405+
//如果是用户的sink
406+
if (key_exists($funcName, $userDefinedSink->getF_CODE())){
407+
return array(true,$U_SINK_ALL[$funcName]) ;
408+
}
409+
return array(false) ;
410+
break;
411+
case 'EXEC':
412+
global $F_EXEC;
413+
//如果是系统的sink
414+
if (key_exists($funcName, $F_EXEC)){
415+
return array(true, $F_EXEC[$funcName][0]);
416+
}
417+
//如果是用户的sink
418+
if (key_exists($funcName, $userDefinedSink->getF_EXEC())){
419+
return array(true,$U_SINK_ALL[$funcName]) ;
420+
}
421+
return array(false) ;
422+
break;
423+
case 'LDAP':
424+
global $F_LDAP;
425+
//如果是系统的sink
426+
if (key_exists($funcName, $F_LDAP)){
427+
return array(true, $F_LDAP[$funcName][0]);
428+
}
429+
//如果是用户的sink
430+
if (key_exists($funcName, $userDefinedSink->getF_LDAP())){
431+
return array(true,$U_SINK_ALL[$funcName]) ;
432+
}
433+
return array(false) ;
434+
break;
435+
case 'INCLUDE':
436+
global $F_FILE_INCLUDE;
437+
//如果是系统的sink
438+
if (key_exists($funcName, $F_FILE_INCLUDE)){
439+
return array(true, $F_FILE_INCLUDE[$funcName][0]);
440+
}
441+
//如果是用户的sink
442+
if (key_exists($funcName, $userDefinedSink->getF_FILE_INCLUDE())){
443+
return array(true,$U_SINK_ALL[$funcName]) ;
444+
}
445+
return array(false) ;
446+
break;
447+
case 'FILE':
448+
global $F_FILE_READ;
449+
//如果是系统的sink
450+
if (key_exists($funcName, $F_FILE_READ)){
451+
return array(true, $F_FILE_READ[$funcName][0]);
452+
}
453+
//如果是用户的sink
454+
if (key_exists($funcName, $userDefinedSink->getF_FILE_READ())){
455+
return array(true,$U_SINK_ALL[$funcName]) ;
456+
}
457+
return array(false) ;
458+
break;
459+
case 'XPATH':
460+
global $F_XPATH;
461+
//如果是系统的sink
462+
if (key_exists($funcName, $F_XPATH)){
463+
return array(true, $F_XPATH[$funcName][0]);
464+
}
465+
//如果是用户的sink
466+
if (key_exists($funcName, $userDefinedSink->getF_XPATH())){
467+
return array(true,$U_SINK_ALL[$funcName]) ;
468+
}
469+
return array(false) ;
470+
break;
471+
case 'FILEAFFECT':
472+
global $F_FILE_AFFECT;
473+
//如果是系统的sink
474+
if (key_exists($funcName, $F_FILE_AFFECT)){
475+
return array(true, $F_FILE_AFFECT[$funcName][0]);
476+
}
477+
//如果是用户的sink
478+
if (key_exists($funcName, $userDefinedSink->getF_FILE_AFFECT())){
479+
return array(true,$U_SINK_ALL[$funcName]) ;
480+
}
481+
return array(false) ;
482+
break;
360483
}
361-
362484
return array(false);
363485

364486
}

0 commit comments

Comments
 (0)