/** * 污点分析中,对当前基本块的探测 * @param BasicBlock $block 当前基本块 * @param Node $node 当前调用sink的node * @param string $argName 危险参数的名称 * @param FileSummary $fileSummary 当前文件的文件摘要 * */ public function currBlockTaintHandler($block, $node, $argName, $fileSummary, $flowNum = 0) { $tempNum = $flowNum; //获取数据流信息 $flows = $block->getBlockSummary()->getDataFlowMap(); $flows = array_reverse($flows); //逆序处理flows //将处理过的flow移除 while ($tempNum) { $tempNum--; array_shift($flows); } foreach ($flows as $flow) { $flowNum++; if ($flow->getName() == $argName) { //处理净化信息,如果被编码或者净化则返回safe //先对左边的变量进行查询 if (is_object($flow->getLocation())) { $target = $flow->getLocation(); $type = TypeUtils::getTypeByFuncName(NodeUtils::getNodeFunctionName($node)); $encodingArr = $target->getEncoding(); $saniArr = $target->getSanitization(); $res = $this->isSanitization($type, $target, $saniArr, $encodingArr); if ($res == true) { return "safe"; } } //获取flow中的右边赋值变量 //得到flow->getValue()的变量node //$sql = $a . $b ; => array($a,$b) $vars = $this->getVarsByFlow($flow); foreach ($vars as $var) { if ($var instanceof ValueSymbol || !is_object($var)) { continue; } $varName = $this->getVarName($var); //如果var右边有source项 if (in_array($varName, $this->sourcesArr)) { // $ret = $this->multiFileHandler($block, $varName, $node, $fileSummary) ; // if($ret == 'safe'){ // continue ; // } //报告漏洞 $path = $fileSummary->getPath(); $this->report($path, $path, $node, $flow->getLocation(), $type); continue; } else { //首先进行文件夹的分析 $this->multiFileHandler($block, $varName, $node, $fileSummary); //文件间分析失败,递归 $this->currBlockTaintHandler($block, $node, $varName, $fileSummary, $flowNum); } } } } }
/** * sink单块回溯 * @param string $argName * @param BasicBlock $block * @param flowNum 遍历过的flow数量 * @return array */ public function sinkTracebackBlock($argName, $block, $flowsNum) { $flows = $block->getBlockSummary()->getDataFlowMap(); //需要将遍历过的dataflow删除 $temp = $flowsNum; while ($temp > 0) { array_pop($flows); $temp--; } //将块内数据流逆序,从后往前遍历 $flows = array_reverse($flows); foreach ($flows as $flow) { $flowsNum++; //trace back if ($flow->getName() == $argName) { //处理净化信息 if ($flow->getLocation()->getSanitization()) { return "safe"; } //得到flow->getValue()的变量node //$sql = $a . $b ; => array($a,$b) if ($flow->getValue() instanceof ConcatSymbol) { $vars = $flow->getValue()->getItems(); } else { $vars = array($flow->getValue()); } $retarr = array(); foreach ($vars as $var) { $var = NodeUtils::getNodeStringName($var); $ret = $this->sinkMultiBlockTraceback($var, $block, $flowsNum); //变量经过净化,这不需要跟踪该变量 if ($ret == "safe") { $retarr = array_slice($retarr, array_search($var, $retarr)); } else { $retarr = array_merge($ret, $retarr); } } return $retarr; } } if ($argName instanceof Node) { $argName = NodeUtils::getNodeStringName($argName); return array($argName); } return $this->sinkMultiBlockTraceback($argName, $block, $flowsNum); }