/**
  * 处理summary的编码信息
  * @param node $node
  * @param DataFlow $dataFlow
  * @param block $block
  * @param fileSummary $fileSummary
  */
 public static function setEncodeInfo($node, $dataFlow, $block, $fileSummary)
 {
     global $F_ENCODING_STRING;
     $funcName = NodeUtils::getNodeFunctionName($node);
     //发现有编码操作的函数,将编码信息加入至map中
     if (in_array($funcName, $F_ENCODING_STRING)) {
         $dataFlow->getLocation()->addEncoding($funcName);
         //向上追踪变量,相同变量的净化信息,全部添加
         $funcParams = NodeUtils::getNodeFuncParams($node);
         //traceback
         $sameVarEncodeInfo = array();
         foreach ($funcParams as $param) {
             $dataFlows = $block->getBlockSummary()->getDataFlowMap();
             $dataFlows = array_reverse($dataFlows);
             $ret = self::encodeSameVarMultiBlockHandler($param, $block, $dataFlows);
             //如果一个参数没有净化,则未净化
             if (!$ret[0]) {
                 $sameVarEncodeInfo = array();
                 break;
             }
             $sameVarEncodeInfo = array_merge($sameVarEncodeInfo, $ret['funcs']);
         }
         //加入此变量的净化信息中
         foreach ($sameVarEncodeInfo as $funcName) {
             $dataFlow->getLocation()->addEncoding($funcName);
         }
     }
     //清除解码
     EncodingHandler::clearEncodeInfo($funcName, $node, $dataFlow);
     //print_r($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);
     }
 }
 /**
  * 污点分析的函数
  * @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);
     }
 }
Exemplo n.º 4
0
 /**
  * 根据sink方法的名称获取危险参数的位置
  * 比如提交mysql_query的调用node,返回危险参数位置array(0)
  * 如果找不到,默认返回array()
  * @param Node $node
  */
 public static function getVulArgs($node)
 {
     global $F_SINK_ALL, $F_SINK_ARRAY;
     $funcName = NodeUtils::getNodeFunctionName($node);
     $nameNum = count($F_SINK_ARRAY);
     //从上下文中获取用户定义sink
     $userDefinedSink = UserDefinedSinkContext::getInstance();
     $U_SINK_ALL = $userDefinedSink->getAllSinks();
     //如果是系统的sink
     if (key_exists($funcName, $F_SINK_ALL)) {
         for ($i = 0; $i < $nameNum; $i++) {
             if (key_exists($funcName, $F_SINK_ARRAY[$i])) {
                 return $F_SINK_ARRAY[$i][$funcName][0];
             }
         }
         return array();
     }
     //如果是用户的sink
     if (key_exists($funcName, $U_SINK_ALL)) {
         foreach ($userDefinedSink->getAllSinkArray() as $value) {
             if (key_exists($funcName, $value)) {
                 return $U_SINK_ALL[$funcName][0];
             }
         }
         return array();
     }
 }
 /**
  * @param 函数体 $stmts
  * @param 函数参数 $params
  * @return 一个函数的净化信息对象
  */
 function findSanitizeParam($stmts, $params)
 {
     //print_r($stmts);
     //print_r($params);
     foreach ($stmts as $node) {
         $type = $node->getType();
         switch ($type) {
             //function
             case "Expr_FuncCall":
                 $funcname = NodeUtils::getNodeFunctionName($node);
                 //查找函数是否在净化函数中,净化类别
                 $ret = $this->isSecureFunction($funcname);
                 if ($ret[0]) {
                     //默认净化函数净化所有参数
                     foreach ($node->args as $arg) {
                         $argName = NodeUtils::getNodeStringName($arg);
                         $pos = $this->searchPos($argName, $params);
                         if ($pos > -1) {
                             //当函数的第1个参数净化时,数组为0,记为1
                             $this->oneFunction->addSanitizeParam($pos + 1, $ret['type']);
                         }
                     }
                 } else {
                     //user define function
                     //find function body in context
                     $context = Context::getInstance();
                     $funcnode = $context->getFunctionBody($funcname);
                     if (!$funcnode) {
                         break;
                     }
                     //递归,return onefunction
                     $next = new SanitizeParamsFinder(null, $funcname);
                     $ret = $next->findSanitizeParam($funcnode->stmts, $funcnode->params);
                     if (!$ret) {
                         break;
                     }
                     //根据return onefunction,加入到this->onefunction
                     foreach ($ret->getSanitizeParams() as $param) {
                         //计算参数位置,因为认为第一个参数设为位置1,而AST树中 是从0开始
                         $postion = $param['positon'] - 1;
                         $pos = $this->searchPos(NodeUtils::getNodeStringName($node->args[$postion]), $params);
                         if ($pos > -1) {
                             //当函数的第1个参数净化时,数组为0,记为1
                             $this->oneFunction->addSanitizeParam($pos + 1, $param['type']);
                         }
                     }
                 }
                 break;
                 //class method
             //class method
             case "Expr_MethodCall":
                 //class static method
             //class static method
             case "Expr_StaticCall":
                 $funcname = NodeUtils::getNodeFunctionName($node);
                 //查找函数是否在净化函数中,净化类别
                 $ret = $this->isSecureFunction($funcname);
                 if ($ret[0]) {
                     //默认净化函数净化所有参数
                     foreach ($node->args as $arg) {
                         $argName = NodeUtils::getNodeStringName($arg);
                         $pos = $this->searchPos($argName, $params);
                         if ($pos > -1) {
                             //当函数的第1个参数净化时,数组为0,记为1
                             $this->oneFunction->addSanitizeParam($pos + 1, $ret['type']);
                         }
                     }
                 } else {
                     //user define function
                     //find function body in context
                     $context = Context::getInstance();
                     $funcnode = $context->getFunctionBody($funcname);
                     if (!$funcnode) {
                         break;
                     }
                     //递归,return onefunction
                     $next = new SanitizeParamsFinder($this->className, $funcname);
                     $ret = $next->findSanitizeParam($funcnode->stmts, $funcnode->params);
                     if (!$ret) {
                         break;
                     }
                     //根据return onefunction,加入到this->onefunction
                     foreach ($ret->getSanitizeParams() as $param) {
                         //计算参数位置,因为认为第一个参数设为位置1,而AST树中 是从0开始
                         $postion = $param['positon'] - 1;
                         $pos = $this->searchPos(NodeUtils::getNodeStringName($node->args[$postion]), $params);
                         if ($pos > -1) {
                             //当函数的第1个参数净化时,数组为0,记为1
                             $this->oneFunction->addSanitizeParam($pos + 1, $param['type']);
                         }
                     }
                 }
                 break;
             case "Stmt_Return":
                 //处理return中的函数调用
                 if ($node->expr->getType() != "Expr_FuncCall") {
                     break;
                 }
                 $funcName = NodeUtils::getNodeStringName($node->expr->name);
                 //递归,return onefunction
                 $next = new SanitizeParamsFinder(null, $funcName);
                 $ret = $next->findSanitizeParam(array($node->expr), $node->expr->args);
                 if (!$ret) {
                     break;
                 }
                 //根据return onefunction,加入到this->onefunction
                 foreach ($ret->getSanitizeParams() as $param) {
                     //计算参数位置,因为认为第一个参数设为位置1,而AST树中 是从0开始
                     $postion = $param['positon'] - 1;
                     $pos = $this->searchPos(NodeUtils::getNodeStringName($node->expr->args[$postion]), $params);
                     if ($pos > -1) {
                         //当函数的第1个参数净化时,数组为0,记为1
                         $this->oneFunction->addSanitizeParam($pos + 1, $param['type']);
                     }
                 }
                 break;
             case "Expr_Assign":
                 //处理赋值右边中的函数调用
                 if ($node->expr->getType() != "Expr_FuncCall") {
                     break;
                 }
                 $funcName = NodeUtils::getNodeStringName($node->expr->name);
                 //递归,return onefunction
                 $next = new SanitizeParamsFinder(null, $funcName);
                 $ret = $next->findSanitizeParam(array($node->expr), $node->expr->args);
                 if (!$ret) {
                     break;
                 }
                 //根据return onefunction,加入到this->onefunction
                 foreach ($ret->getSanitizeParams() as $param) {
                     //计算参数位置,因为认为第一个参数设为位置1,而AST树中 是从0开始
                     $postion = $param['positon'] - 1;
                     $pos = $this->searchPos(NodeUtils::getNodeStringName($node->expr->args[$postion]), $params);
                     if ($pos > -1) {
                         $this->oneFunction->addSanitizeParam($pos + 1, $param['type']);
                     }
                 }
                 break;
             default:
                 break;
         }
     }
     if ($this->isSanitizeFunc($this->oneFunction)) {
         return $this->oneFunction;
     }
 }
 /**
  * 净化函数处理函数
  * @param funcNode $node
  * @return null | array(funcName,type)
  */
 public static function SantiniFuncHandler($node, $fileSummary)
 {
     global $F_SECURES_ALL;
     $funcName = NodeUtils::getNodeFunctionName($node);
     //查看系统净化函数及已查找函数的信息
     $ret = self::isSecureFunction($funcName);
     if ($ret[0]) {
         $oneFunction = new OneFunction($funcName);
         $oneFunction->setSanitiType($ret['type']);
         return $oneFunction;
     } else {
         //未查找过函数
         $context = Context::getInstance();
         $require_array = $fileSummary->getIncludeMap();
         $path = $fileSummary->getPath();
         $funcBody = $context->getClassMethodBody($funcName, $path, $require_array);
         if (!$funcBody) {
             return null;
         }
         $visitor = new SanitiFunctionVisitor();
         $parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative());
         $traverser = new PhpParser\NodeTraverser();
         $traverser->addVisitor($visitor);
         $visitor->funcName = $funcName;
         $visitor->fileSummary = $fileSummary;
         $traverser->traverse($funcBody->stmts);
         if ($visitor->sanitiInfo[0]) {
             //将净化函数加入净化UserSanitizeFuncContext
             $oneFunction = new OneFunction($funcName);
             $oneFunction->setSanitiType($visitor->sanitiInfo['type']);
             $SanitiFuncContext = UserSanitizeFuncConetxt::getInstance();
             $SanitiFuncContext->addFunction($oneFunction);
             return $oneFunction;
         } else {
             return null;
         }
     }
 }
Exemplo n.º 7
0
 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 {
         }
     }
 }