/** * 分离isset结构中的类型 * isset($id) ? $_GET['id'] : 2; * 转为: * array($_GET[id],2) * @param unknown $node */ public function setItemByNode($node) { //处理三元表达式 if ($node->getType() == "Expr_Ternary") { if ($node->if->getType() == "Expr_Ternary") { $this->setItemByNode($node->if); } if ($node->else->getType() == "Expr_Ternary") { $this->setItemByNode($node->else); } $if_node = SymbolUtils::getSymbolByNode($node->if); $else_node = SymbolUtils::getSymbolByNode($node->else); $if_node && $this->addSymbol($if_node); $else_node && $this->addSymbol($else_node); } else { return; } }
/** * @param Node $node * @param 数据流 $dataFlow */ public static function setSanitiInfo($node, $dataFlow, $block, $fileSummary) { $dataFlows = $block->getBlockSummary()->getDataFlowMap(); $sanitiInfo = self::SantiniFuncHandler($node, $fileSummary); $sanitiInfo = null; if ($sanitiInfo) { $args = NodeUtils::getFuncParamsNode($node); if (count($args) > 0) { if (!$dataFlow->getValue()) { $arg = SymbolUtils::getSymbolByNode($args[0]); $dataFlow->setValue($arg); } } //向上追踪变量,相同变量的净化信息,全部添加 $funcParams = NodeUtils::getNodeFuncParams($node); //traceback $sameVarSanitiInfo = array(); foreach ($funcParams as $param) { $dataFlows = $block->getBlockSummary()->getDataFlowMap(); $dataFlows = array_reverse($dataFlows); $ret = self::sanitiSameVarMultiBlockHandler($param, $block, $dataFlows, $fileSummary); //如果一个参数没有净化,则未净化 if (!$ret[0]) { $sameVarSanitiInfo = array(); break; } $sameVarSanitiInfo = array_merge($sameVarSanitiInfo, $ret['funcs']); } //加入此变量的净化信息中 foreach ($sameVarSanitiInfo as $oneFunction) { $dataFlow->getLocation()->addSanitization($oneFunction); } $dataFlow->getLocation()->addSanitization($sanitiInfo); } $funcName = NodeUtils::getNodeFunctionName($node); //清除反作用的函数 SanitizationHandler::clearSantiInfo($funcName, $node, $dataFlow); }
/** * 处理赋值性的一些内置函数 * 比如: * $id = urlencode($_GET['id']) ; * @param unknown $part * @param unknown $type * @param unknown $dataFlow */ public static function assignFuncHandler($part, $type, $dataFlow, $funcName) { $single_func = self::getSingleFuncs(); $encoding_convert = array('iconv'); if ($type == "right" && array_key_exists($funcName, $single_func)) { //首先搜索不安全字符的转换函数 if (in_array($funcName, $encoding_convert)) { $oneFunction = new OneFunction($funcName); $dataFlow->getLocation()->addSanitization($oneFunction); } $position = $single_func[$funcName]; $value = $part->args[$position]->value; //解决trim(urlencode($id))的方法嵌套问题 if ($value->getType() == 'Expr_FuncCall') { $new_name = NodeUtils::getNodeFunctionName($value); self::assignFuncHandler($value, $type, $dataFlow, $new_name); } if ($dataFlow->getValue() != null) { return; } $vars = SymbolUtils::getSymbolByNode($value); $dataFlow->setValue($vars); } }
/** * 根据sink的类型、危险参数的净化信息列表、编码列表 * 判断是否是有效的净化 * 返回: * (1)true =>得到净化 * (2)false =>没有净化 * 'XSS','SQLI','HTTP','CODE','EXEC','LDAP','INCLUDE','FILE','XPATH','FILEAFFECT' * @param string $type 漏洞的类型,使用TypeUtils可以获取 * @param Symbol $var 危险参数 * @param array $saniArr 危险参数的净化信息栈 * @param array $encodingArr 危险参数的编码信息栈 */ public function isSanitization($type, $var, $saniArr_obj, $encodingArr) { //整理saniArr $saniArr = array(); if (is_object($saniArr_obj)) { foreach ($saniArr_obj as $value) { array_push($saniArr, $value->funcName); } } else { $saniArr = $saniArr_obj; } $is_clean = null; $var_type = ''; if ($var instanceof Node) { $var = SymbolUtils::getSymbolByNode($var); } if ($var instanceof ValueSymbol) { return true; } //如果symbol类型为int,直接返回安全true if (!in_array($var->getType(), array('string', 'valueInt'))) { return true; } //根据不同的漏洞类型进行判断 switch ($type) { case 'SQLI': $sql_analyser = new SqliAnalyser(); $is_clean = $sql_analyser->analyse($var, $saniArr, $encodingArr); break; case 'XSS': $xss_analyser = new XssAnalyser(); $is_clean = $xss_analyser->analyse($var, $saniArr, $encodingArr); break; case 'HTTP': $http_analyser = new HeaderAnalyser(); $is_clean = $http_analyser->analyse($var, $saniArr, $encodingArr); break; case 'CODE': $code_analyser = new CodeAnalyser(); $is_clean = $code_analyser->analyse($var, $saniArr, $encodingArr); break; case 'EXEC': $exec_analyser = new ExecAnalyser(); $is_clean = $exec_analyser->analyse($var, $saniArr, $encodingArr); break; case 'LDAP': $ldap_analyser = new LDPAAnalyser(); $is_clean = $ldap_analyser->analyse($var, $saniArr, $encodingArr); break; case 'INCLUDE': $include_analyser = new IncludeAnalyser(); $is_clean = $include_analyser->analyse($var, $saniArr, $encodingArr); break; case 'FILE': $file_analyser = new FileAnalyser(); $is_clean = $file_analyser->analyse($var, $saniArr, $encodingArr); break; case 'XPATH': $xpath_analyser = new XPathAnalyser(); $is_clean = $xpath_analyser->analyse($var, $saniArr, $encodingArr); break; case 'FILEAFFECT': $file_affect_analyser = new FileAffectAnalyser(); $is_clean = $file_affect_analyser->analyse($var, $saniArr, $encodingArr); break; } return $is_clean; }
public function leaveNode(Node $node) { $type = $node->getType(); if ($type == "Expr_BinaryOp_Concat") { if ($node->right) { //转为symbol $right_symbol = SymbolUtils::getSymbolByNode($node->right); $right_symbol != null && array_push($this->items, $right_symbol); } if ($node->left->getType() != "Expr_BinaryOp_Concat") { $left_symbol = SymbolUtils::getSymbolByNode($node->left); $left_symbol != null && array_push($this->items, $left_symbol); } } else { if ($type == "Scalar_Encapsed") { foreach ($node->parts as $item) { if (!is_object($item)) { $valueSymbol = new ValueSymbol(); $valueSymbol->setValue($item); $valueSymbol != null && array_push($this->items, $valueSymbol); } else { $setItem = SymbolUtils::getSymbolByNode($item); $setItem != null && array_push($this->items, $setItem); } } } } }
/** * 分析传入node赋值语句,以及当前block, * 生成block summary中的一条记录 * @param ASTNode $node 赋值语句 * @param BasicBlock $block * @param string $type 处理赋值语句的var和expr类型(left or right) */ private function assignHandler($node, $block, $dataFlow, $type) { global $scan_type; $part = null; if ($type == "left") { $part = $node->var; } else { if ($type == "right") { $part = $node->expr; } else { return; } } //处理$GLOBALS的赋值 //$GLOBAL['name'] = "chongrui" ; 数据流信息为 $name = "chongrui" ; if ($part && SymbolUtils::isArrayDimFetch($part) && substr(NodeUtils::getNodeStringName($part), 0, 7) == "GLOBALS") { //加入dataFlow $arr = new ArrayDimFetchSymbol(); $arr->setValue($part); if ($type == "left") { $dataFlow->setLocation($arr); $dataFlow->setName(NodeUtils::getNodeGLOBALSNodeName($part)); //加入registerglobal $this->registerGLOBALSHandler($part, $block); } else { if ($type == "right") { $dataFlow->setValue($arr); } } return; } //处理赋值语句,存放在DataFlow //处理赋值语句的左边 if ($part && SymbolUtils::isValue($part)) { //在DataFlow加入Location以及name $vs = new ValueSymbol(); $vs->setValueByNode($part); if ($type == "left") { $dataFlow->setLocation($vs); $dataFlow->setName($part->name); } else { if ($type == "right") { $dataFlow->setValue($vs); } } } elseif ($part && SymbolUtils::isVariable($part)) { //加入dataFlow $vars = new VariableSymbol(); $vars->setValue($part); if ($type == "left") { $dataFlow->setLocation($vars); $dataFlow->setName($part->name); } else { if ($type == "right") { $dataFlow->setValue($part); } } } elseif ($part && SymbolUtils::isConstant($part)) { //加入dataFlow $con = new ConstantSymbol(); $con->setValueByNode($part); $con->setName($part->name->parts[0]); if ($type == "left") { $dataFlow->setLocation($con); $dataFlow->setName($part->name); } else { if ($type == "right") { $dataFlow->setValue($con); } } } elseif ($part && SymbolUtils::isArrayDimFetch($part)) { //加入dataFlow $arr = new ArrayDimFetchSymbol(); $arr->setValue($part); $arr->setNameByNode($node); if ($type == "left") { $dataFlow->setLocation($arr); $dataFlow->setName(NodeUtils::getNodeStringName($part)); } else { if ($type == "right") { $dataFlow->setValue($arr); } } } elseif ($part && SymbolUtils::isConcat($part)) { $concat = new ConcatSymbol(); $concat->setItemByNode($part); if ($type == "left") { $dataFlow->setLocation($concat); $dataFlow->setName($part->name); } else { if ($type == "right") { $dataFlow->setValue($concat); } } } else { //不属于已有的任何一个symbol类型,如函数调用,类型转换 if ($part && ($part->getType() == "Expr_FuncCall" || $part->getType() == "Expr_MethodCall" || $part->getType() == "Expr_StaticCall")) { //处理 id = urlencode($_GET['id']) ; if ($type == 'right' && !SymbolUtils::isValue($part)) { $funcName = NodeUtils::getNodeFunctionName($part); BIFuncUtils::assignFuncHandler($part, $type, $dataFlow, $funcName); if ($dataFlow->getValue() != null) { //如果处理完函数赋值,则立即返回 $block->getBlockSummary()->addDataFlowItem($dataFlow); return; } else { //处理 id = urlencode($_GET['id']) ; //检查是否为sink函数 $this->functionHandler($part, $block, $this->fileSummary); //处理净化信息和编码信息 SanitizationHandler::setSanitiInfo($part, $dataFlow, $block, $this->fileSummary); EncodingHandler::setEncodeInfo($part, $dataFlow, $block, $this->fileSummary); } } } //处理类型强制转换 if ($part && ($part->getType() == "Expr_Cast_Int" || $part->getType() == "Expr_Cast_Double") && $type == "right") { $dataFlow->getLocation()->setType("int"); $symbol = SymbolUtils::getSymbolByNode($part->expr); $dataFlow->setValue($symbol); } //处理三元表达式 if ($part && $part->getType() == "Expr_Ternary") { BIFuncUtils::ternaryHandler($type, $part, $dataFlow); } //处理双引号中包含的变量 if ($part && $part->getType() == "Scalar_Encapsed") { $symbol = SymbolUtils::getSymbolByNode($part); $dataFlow->setValue($symbol); } } //else //处理完一条赋值语句,加入DataFlowMap if ($type == "right") { $block->getBlockSummary()->addDataFlowItem($dataFlow); } }