Exemplo n.º 1
0
 /**
  * 根据方法名查询sink所属的漏洞类别
  * @param string $funcName
  * @return string
  */
 public static function getTypeByFuncName($funcName)
 {
     //系统内置sink
     global $F_SINK_ALL, $F_SINK_ARRAY;
     //用户自定义sink
     $userDefinedSink = UserDefinedSinkContext::getInstance();
     $U_SINK_ALL = $userDefinedSink->getAllSinks();
     //系统sink
     if (key_exists($funcName, $F_SINK_ALL)) {
         foreach ($F_SINK_ARRAY as $value) {
             if (key_exists($funcName, $value)) {
                 return $value['__NAME__'];
             }
         }
     }
     //用户sink
     if (key_exists($funcName, $U_SINK_ALL)) {
         foreach ($userDefinedSink->getAllSinkArray() as $value) {
             if (key_exists($funcName, $value)) {
                 return $value['__NAME__'];
             }
         }
     }
     return NULL;
 }
Exemplo n.º 2
0
 /**
  * 根据净化栈和漏洞类型判断是否受到净化
  * @param string $type  漏洞类型
  * @param array $sanitiArr  净化栈
  * @return bool true 表示受到净化   false反之
  */
 public static function checkSanitiByArr($type, $sanitiArr)
 {
     //获取用户自定义sink上下文
     $userDefSinkContext = UserDefinedSinkContext::getInstance();
     //判断sanitiArr中是否存在list中
     $userDefSinkSaniti = $userDefSinkContext->getSinksSanitiByType($type);
     $confDefSinkSaniti = self::getSecureListByType($type);
     $commonDefSinkSaniti = self::getCommonSecureList();
     $combine_list = array_merge($userDefSinkSaniti, $confDefSinkSaniti, $commonDefSinkSaniti);
     foreach ($sanitiArr as $value) {
         if (in_array($value->funcName, $combine_list)) {
             return true;
         }
     }
     return false;
 }
Exemplo n.º 3
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();
     }
 }
 public static function getInstance()
 {
     if (!self::$instance instanceof self) {
         self::$instance = new self();
     }
     return self::$instance;
 }
Exemplo n.º 5
0
 /**
  * 处理函数调用
  * @param node $node 调用方法的节点
  * @param BasicBlock $block 当前基本块
  * @param fileSummary $fileSummary  当前文件摘要
  */
 public function functionHandler($node, $block, $fileSummary)
 {
     //根据用户指定的扫描类型,查找相类型的sink函数
     global $scan_type;
     //获取调用的函数名判断是否是sink调用
     $funcName = NodeUtils::getNodeFunctionName($node);
     //判断是否为sink函数,返回格式为array(true,funcname) or array(false)
     $ret = NodeUtils::isSinkFunction($funcName, $scan_type);
     if ($ret[0] != null && $ret[0] === true) {
         //如果发现了sink调用,启动污点分析
         $analyser = new TaintAnalyser();
         //获取危险参数的位置
         $argPosition = NodeUtils::getVulArgs($node);
         if (count($argPosition) == 0) {
             return;
         }
         //获取到危险参数位置的变量
         $argArr = NodeUtils::getFuncParamsByPos($node, $argPosition);
         //遍历危险参数名,调用污点分析函数
         if (count($argArr) > 0) {
             foreach ($argArr as $item) {
                 if (is_array($item)) {
                     foreach ($item as $v) {
                         $analyser->analysis($block, $node, $v, $fileSummary);
                     }
                 } else {
                     $analyser->analysis($block, $node, $item, $fileSummary);
                 }
             }
         }
     } else {
         //如果不是sink调用,启动过程间分析
         $context = Context::getInstance();
         $funcBody = $context->getClassMethodBody($funcName, $this->fileSummary->getPath(), $this->fileSummary->getIncludeMap());
         //check
         if (!$funcBody || !is_object($funcBody)) {
             return;
         }
         if ($funcBody->getType() == "Stmt_ClassMethod") {
             $funcBody->stmts = $funcBody->stmts[0];
         }
         //构建相应方法体的block和summary
         $nextblock = $this->CFGBuilder($funcBody->stmts, NULL, NULL, NULL);
         //ret危险参数的位置比如:array(0)
         $ret = $this->sinkFunctionHandler($funcBody, $nextblock, $block);
         if (!$ret) {
             return;
         }
         //找到了array('del',array(0)) ;
         $userDefinedSink = UserDefinedSinkContext::getInstance();
         //$type应该从visitor中获取,使用$ret返回
         $type = $ret['type'];
         unset($ret['type']);
         //加入用户sink上下文
         $item = array($funcName, $ret);
         $userDefinedSink->addByTagName($item, $type);
         //开始污点分析
         $argPosition = NodeUtils::getVulArgs($node);
         $argArr = NodeUtils::getFuncParamsByPos($node, $argPosition);
         if (count($argArr) > 0) {
             $analyser = new TaintAnalyser();
             foreach ($argArr as $item) {
                 if (is_array($item)) {
                     foreach ($item as $v) {
                         $analyser->analysis($block, $node, $v, $this->fileSummary);
                     }
                 } else {
                     $analyser->analysis($block, $node, $item, $this->fileSummary);
                 }
             }
         }
     }
 }