/** * 处理赋值的assign语句,添加至dataFlows中 * @param AST $node * @param DataFlow $dataFlow * @param string $type */ public function assignHandler($node, $dataFlow, $type, $block, $fileSummary) { $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)); } 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); 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")) { if ($type == "left") { $dataFlow->setLocation($arr); $dataFlow->setName(NodeUtils::getNodeStringName($part)); } else { if ($type == "right") { //处理净化信息和编码信息 SanitizationHandler::setSanitiInfo($part, $dataFlow, $block, $fileSummary); EncodingHandler::setEncodeInfo($part, $dataFlow, $block, $fileSummary); } } } //处理三元表达式 if ($part && $part->getType() == "Expr_Ternary") { BIFuncUtils::ternaryHandler($type, $part, $dataFlow); } } }
/** * 获取函数的参数名称 * @param Node $node 函数调用的node * @return array(arg1[,arg2,arg3,...]) */ public static function getNodeFuncParams($node) { if (!$node instanceof Node) { return null; } //支持echo和print $funcName = self::getNodeFunctionName($node); if ($funcName == "echo") { $ret = array(); if ($node->exprs[0]->getType() == "Expr_BinaryOp_Concat") { $ret = self::getConcatParams($node->exprs[0]); } else { if (SymbolUtils::isValue($node->exprs[0])) { return array(); } else { $res = self::getNodeStringName($node->exprs[0]); if (is_array($res)) { array_merge($ret, $res); } else { array_push($ret, $res); } } } return $ret; } else { if ($funcName == 'include') { $ret = array(); if ($node->expr->getType() == "Expr_BinaryOp_Concat") { $ret = self::getConcatParams($node->expr); } elseif ($node->expr->getType() == "Scalar_Encapsed") { $args = $node->expr->parts; foreach ($args as $arg) { if (SymbolUtils::isValue($arg)) { continue; } else { array_push($ret, NodeUtils::getNodeStringName($arg)); } } } else { if (SymbolUtils::isValue($node->expr)) { return array(); } else { $ret = self::getNodeStringName($node->expr); } } return $ret; } else { if ($funcName == "print") { $ret = array(); if ($node->expr->getType() == "Expr_BinaryOp_Concat") { $ret = self::getConcatParams($node->expr); } else { if (SymbolUtils::isValue($node->expr)) { return array(); } else { $ret = self::getNodeStringName($node->expr); } } return $ret; } else { if ($funcName == "eval") { $ret = array(); if ($node->expr->getType() == "Expr_BinaryOp_Concat") { $ret = self::getConcatParams($node->expr); } else { if (SymbolUtils::isValue($node->expr)) { return array(); } else { $ret = self::getNodeStringName($node->expr); } } return $ret; } } } } //处理其他的函数 $argsArr = array(); if ($node->args) { foreach ($node->args as $arg) { //如果为concat类型 if ($arg->value->getType() == "Expr_BinaryOp_Concat") { $concatArr = self::getConcatParams($arg->value); array_push($argsArr, $concatArr); } else { array_push($argsArr, NodeUtils::getNodeStringName($arg)); } } } elseif ($node->params) { foreach ($node->params as $arg) { if ($arg->getType() == "Expr_BinaryOp_Concat") { $concatArr = self::getConcatParams($arg->value); array_push($argsArr, $concatArr); } else { array_push($argsArr, NodeUtils::getNodeStringName($arg)); } } } return $argsArr; }
/** * 根据AST node获取相应的symbol * @param unknown $node */ public static function getSymbolByNode($node) { if ($node && SymbolUtils::isValue($node)) { //在DataFlow加入Location以及name $vs = new ValueSymbol(); $vs->setValueByNode($node); return $vs; } elseif ($node && SymbolUtils::isVariable($node)) { //加入dataFlow $vars = new VariableSymbol(); $vars->setNameByNode($node); $vars->setValue($node); return $vars; } elseif ($node && SymbolUtils::isArrayDimFetch($node)) { //加入dataFlow $arr = new ArrayDimFetchSymbol(); $arr->setValue($node); return $arr; } elseif ($node && SymbolUtils::isConcat($node)) { $concat = new ConcatSymbol(); $concat->setItemByNode($node); return $concat; } elseif ($node && $node->getType() == "Scalar_Encapsed") { $arr = array(); $symbol = new MutipleSymbol(); foreach ($node->parts as $item) { if (is_object($item) && self::isValue($item) == false) { $sym = self::getSymbolByNode($item); array_push($arr, $sym); } } $symbol->setSymbols($arr); return $symbol; } else { return null; } }
public function leaveNode(Node $node) { global $SECURES_TYPE_ALL; if (!$node instanceof Node) { return null; } if ($node->getType() == 'Stmt_Return') { $part = $node->expr; if (SymbolUtils::isValue($part)) { //return value if (!is_array($this->sanitiInfo['type'])) { $this->sanitiInfo['type'] = array($this->sanitiInfo['type']); } $type = array_intersect($this->sanitiInfo['type'], $SECURES_TYPE_ALL); $this->sanitiInfo = array(true, 'type' => $type); } elseif (SymbolUtils::isVariable($part)) { //return variable $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $ret = $this->sanitiMultiBlockHandler($node->expr, $block); if ($ret[0]) { $type = array_intersect($this->sanitiInfo['type'], $ret['type']); $this->sanitiInfo = array(true, 'type' => $type); } else { $this->sanitiInfo = null; } } elseif (SymbolUtils::isConstant($part)) { //return constant $type = array_intersect($this->sanitiInfo['type'], $SECURES_TYPE_ALL); $this->sanitiInfo = array(true, 'type' => $type); } elseif (SymbolUtils::isArrayDimFetch($part)) { //return array $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $ret = $this->sanitiMultiBlockHandler($node->expr, $block); if ($ret[0]) { $type = array_intersect($this->sanitiInfo['type'], $ret['type']); $this->sanitiInfo = array(true, 'type' => $type); } else { $this->sanitiInfo = null; } } elseif (SymbolUtils::isConcat($part)) { //return concat $concat = new ConcatSymbol(); $concat->setItemByNode($part); $items = $concat->getItems(); if (!$items) { return null; } $context = Context::getInstance(); $funcBody = $context->getFunctionBody($this->funcName); if (!$funcBody) { return null; } $nodes = $funcBody->stmts; $cfg = new CFGGenerator(); $block = $cfg->CFGBuilder($nodes, NULL, NULL, NULL); $retarr = $SECURES_TYPE_ALL; foreach ($items as $item) { $ret = $this->sanitiMultiBlockHandler($item, $block); if ($ret[0]) { $retarr = array_intersect($retarr, $ret['type']); } else { $this->sanitiInfo = array(false); break; } } $this->sanitiInfo = array(true, 'type' => $retarr); } else { //处理函数调用 if ($part->getType() == 'Expr_FuncCall' || $part->getType() == 'Expr_MethodCall' || $part->getType() == 'Expr_StaticCall') { $ret = SanitizationHandler::SantiniFuncHandler($part, $this->fileSummary); if ($ret) { $saniType = $ret->getSanitiType(); if (is_array($saniType[0])) { $saniType = $saniType[0]; } $type = array_intersect($this->sanitiInfo['type'], $saniType); $this->sanitiInfo = array(true, 'type' => $type); } } } } else { return null; } }
/** * 分析传入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); } }