/** * 污点分析的函数 * @param BasicBlock $block 当前基本块 * @param Node $node 当前的函数调用node * @param string $argName 危险参数名 * @param FileSummary 当前文件摘要 */ public function analysis($block, $node, $argName, $fileSummary) { //传入变量本身就是source $varName = substr($argName, 0, strpos($argName, '[')); if (in_array($varName, $this->sourcesArr) || in_array($argName, $this->sourcesArr)) { //报告漏洞 $path = $fileSummary->getPath(); $type = TypeUtils::getTypeByFuncName(NodeUtils::getNodeFunctionName($node)); $this->report($path, $path, $node, $argName, $type); } else { $path = $fileSummary->getPath(); //获取前驱基本块集合并将当前基本量添加至列表 $this->getPrevBlocks($block); $block_list = $this->pathArr; array_push($block_list, $block); //多个基本块的处理 $this->pathArr = array(); $this->multiBlockHandler($block, $argName, $node, $fileSummary); $this->multiFileHandler($block, $argName, $node, $fileSummary); } }
public function leaveNode(Node $node) { //处理过程间代码,即调用的方法定义中的源码 if ($node->getType() == 'Expr_FuncCall' || $node->getType() == 'Expr_MethodCall' || $node->getType() == 'Expr_StaticCall') { //获取到方法的名称 $nodeName = NodeUtils::getNodeFunctionName($node); $ret = NodeUtils::isSinkFunction($nodeName, $this->scan_type); //进行危险参数的辨别 if ($ret[0] == true) { //处理系统内置的sink //找到了mysql_query $cfg = new CFGGenerator(); //array(where)找到危险参数的位置 $args = $ret[1]; if (is_array($args[0])) { $args = $args[0]; } $vars = $this->senstivePostion($node, $this->block, $args); $type = TypeUtils::getTypeByFuncName($nodeName); if ($vars) { //返回处理结果,将多个相关变量位置返回 $this->vars = array_merge($this->vars, $vars); } if ($type) { //返回sink类型 $this->sinkType = $type; } } elseif (array_key_exists($nodeName, $this->sinkContext->getAllSinks())) { //处理已经加入sinksContext用户自定义函数 //处理用户定义的sink $type = TypeUtils::getTypeByFuncName($nodeName); if ($type) { //返回sink类型 $this->sinkType = $type; } $context = Context::getInstance(); $funcName = NodeUtils::getNodeFunctionName($node); $funcBody = $context->getClassMethodBody($funcName, $this->fileSummary->getPath(), $this->fileSummary->getIncludeMap()); if (!$funcBody) { break; } $cfg = new CFGGenerator(); //$this->block->function[$nodeName] $arr = $this->sinkContext->getAllSinks(); $arr = $arr[$nodeName]; foreach ($arr as $pos) { $argName = NodeUtils::getNodeFuncParams($node); $argName = $argName[$pos]; $this->vars = $this->sinkMultiBlockTraceback($argName, $this->block, 0); } } else { } } }