Giter Site home page Giter Site logo

lorexxar / kunlun-m Goto Github PK

View Code? Open in Web Editor NEW
2.1K 54.0 304.0 16.21 MB

KunLun-M是一个完全开源的静态白盒扫描工具,支持PHP、JavaScript的语义扫描,基础安全、组件安全扫描,Chrome Ext\Solidity的基础扫描。

License: MIT License

Python 56.97% HTML 8.96% Java 0.01% PHP 0.29% Hack 0.01% Solidity 1.35% CSS 27.78% JavaScript 4.55% Dockerfile 0.09% Shell 0.01%

kunlun-m's Introduction

  • 自Cobra-W 2.0版本起,Cobra-W正式更名为Kunlun-M(昆仑镜),

  • KunLun-M(昆仑镜)已进入弱维护阶段,如果有bug或者明显的问题会更新,但不会再更新新功能,主要是我认为Kunlun-M的架构拖累了后续的发展方向,仅在PHP扫描中以当前的架构已经几乎做到极限了,后续可能会有新的工具?也可能没有?敬请期待~

  • 请使用python3.6+运行该工具,已停止维护python2.7环境

Kunlun-Mirror

GitHub (pre-)release license

 _   __            _                      ___  ___
| | / /           | |                     |  \/  |
| |/ / _   _ _ __ | |    _   _ _ __       | .  . |
|    \| | | | '_ \| |   | | | | '_ \ _____| |\/| |
| |\  \ |_| | | | | |___| |_| | | | |_____| |  | |
\_| \_/\__,_|_| |_\_____/\__,_|_| |_|     \_|  |_/  -v2.0

GitHub: https://github.com/LoRexxar/Kunlun-M

KunLun-M is a static code analysis system that automates the detecting vulnerabilities and security issue.

Main Program

positional arguments:
  {init,config,scan,show,console}
    init                Kunlun-M init before use.
    config              config for rule&tamper
    scan                scan target path
    show                show rule&tamper
    console             enter console mode

optional arguments:
  -h, --help            show this help message and exit

Usage:
  python kunlun.py scan -t tests/vulnerabilities
  python kunlun.py scan -t tests/vulnerabilities -r 1000, 1001
  python kunlun.py scan -t tests/vulnerabilities -tp wordpress
  python kunlun.py scan -t tests/vulnerabilities -d -uc

  python kunlun.py list rule -k php

Introduction

Cobra是一款源代码安全审计工具,支持检测多种开发语言源代码中的大部分显著的安全问题和漏洞。 https://github.com/wufeifei/cobra

Cobra-W是从Cobra2.0发展而来的分支,将工具重心从尽可能的发现威胁转变为提高发现漏洞的准确率以及精度。 https://github.com/LoRexxar/Kunlun-M/tree/cobra-w

Kunlun-Mirror是从Cobra-W2.0发展而来,在经历了痛苦的维护改进原工具之后,昆仑镜将工具的发展重心放在安全研究员的使用上,将会围绕工具化使用不断改进使用体验。

目前工具主要支持php、javascript的语义分析,以及chrome ext, solidity的基础扫描.

Stargazers

why KunLun-M

KunLun-M可能是市面上唯一的开源并长期维护的自动化代码审计工具,希望开源工具可以推动白盒审计的发展:>.

特点

与其他代码审计相比:

  • 静态分析,环境依赖小。
  • 语义分析,对漏洞有效性判断程度更深。
  • 多种语言支持。
  • 开源python实现,更易于二次开发。

与Cobra相比:

  • 深度重写AST,大幅度减少漏洞误报率。
  • 底层api重写,支持windows、linux等多平台。
  • 多层语义解析、函数回溯,secret机制,新增多种机制应用于语义分析。
  • 新增javascript语义分析,用于扫描包含js相关代码。

与Cobra-W相比(todo):

  • 深度优化AST分析流程,使其更符合QL的概念,便于下一阶段的优化。
  • 深度优化辅助审计的流程,使其更符合人类安全研究员审计辅助的习惯。
  • 深度重构代码结构,使其更符合可拓展,可优化的开源理念。

TODO

KunLun-M后续的更新计划会是跨越式更新,根据一段时间的研究和探索,我决定从底层重构这套代码分析方案

社区化工具

社区成员完成的拓展(不保证安全性,参考使用)

更新日志

changelog.md

安装

首先需要安装依赖

pip install -r requirements.txt

配置文件迁移

cp Kunlun_M/settings.py.bak Kunlun_M/settings.py

初始化数据库,默认采用sqlite作为数据库

python kunlun.py init initialize

加载规则进数据库(每次修改规则文件都需要加载)

python kunlun.py config load

docker安装

通过docker安装,默认启动web模式

sudo docker build -t kunlun-m -f ./docker/Dockerfile .

配合链接同Mysql可以实现本地扫描,web端查看结果。

Usage

cli mode

使用scan模式扫描各类源代码

python3 kunlun.py scan -t ./tests/vulnerabilities/

使用config模式加载本地的rule/tamper

python3 kunlun.py config load         # 加载rule进数据库
python3 kunlun.py config recover      # 将数据库中的rule恢复到文件
python3 kunlun.py config loadtamper   # 加载tamper进数据库
python3 kunlun.py config retamper     # 将数据库中的tamper恢复到文件

使用show模式查看目前的所有rule/tamper

python3 kunlun.py show rule           # 展示所有的rule
python3 kunlun.py show rule -k php    # 展示所有php的rule
python3 kunlun.py show tamper         # 展示所有的tamper

使用不同子模式的-h可以查看详细的帮助文档。

web mode

KunLun-M Dashbroad,并且允许通过apitoken来访问api获取数据

默认9999端口

python3 .\kunlun.py web -p 9999

修改KunLun-M/settings.py中的api-token,通过?token={api_token}访问api获取数据

# api profile
API_TOKEN = "secret_api_token"

Api List

task/list                                       查看task列表
task/<int:task_id>                              查看task详细信息
task/<int:task_id>/result                       查看task扫描结果
task/<int:task_id>/resultflow                   查看task扫描结果流
task/<int:task_id>/newevilfunc                  查看task扫描后生成的新恶意函数

rule/list                                       查看规则列表
rule/<int:rule_id>                              查看规则细节

console mode

建议使用console模式

python3 kunlun.py console


 _   __            _                      ___  ___
| | / /           | |                     |  \/  |
| |/ / _   _ _ __ | |    _   _ _ __       | .  . |
|    \| | | | '_ \| |   | | | | '_ \ _____| |\/| |
| |\  \ |_| | | | | |___| |_| | | | |_____| |  | |
\_| \_/\__,_|_| |_\_____/\__,_|_| |_|     \_|  |_/  -v2.0

GitHub: https://github.com/LoRexxar/Kunlun-M

KunLun-M is a static code analysis system that automates the detecting vulnerabilities and security issue.

Global commands:
    help                                             Print this help menu
    scan                                             Enter the scan mode
    load <scan_id>                                   Load Scan task
    showt                                            Show all Scan task list
    show [rule, tamper] <key>                        Show rules or tampers
    config [rule, tamper] <rule_id> | <tamper_name>  Config mode for rule & tamper
    exit                                             Exit KunLun-M & save Config


KunLun-M (root) >

使用KunLun-M 查看 rules 和 tampers

asciicast

使用KunLun-M 扫描漏洞

asciicast

使用KunLun-M 查看扫描结果

asciicast

plugin mode

phpunserializechain

一个自动化寻找php反序列化链的简单模型

如果是旧版本更新并使用该插件扫描同一目标,请使用-r参数renew数据库

python3 .\kunlun.py plugin php_unserialize_chain_tools -t {target_path}

EntranceFinder

一个有趣的小工具,用于解决在审计大量的php代码时,快速发现存在可能的入口页面(或是开发者都遗漏的)。

python3 .\kunlun.py plugin entrance_finder -t {target_path} -l 3

开发文档

开发文档还未更新.相应的文档内容仅供参考。

dev.md

规则插件开发

规则插件开发遵循

rules/{语言类型}/CVI_xxxx.py

在规则目录下,只有命名符合规定的规则会被成功加载,命名格式严格为CVI_编号.py

规则模板可以参考rules/rule.template

.kunlunmignore

.kunlunmignore是新引入的用于黑名单扫描目录的功能。目前只支持*语法,可以用来匹配相应的目录以及文件类型。

相匹配到的文件不会被扫描。

当然,可以通过-b来实现

404StarLink Project

KunLun-M 是 404Team 星链计划中的一环,如果对KunLun-M有任何疑问又或是想要找小伙伴交流,可以参考星链计划的加群方式。

Contributors

感谢如下贡献者对本工具发展过程中的贡献:

核心开发者:

重要贡献者:

次要贡献者:

kunlun-m's People

Contributors

akkuman avatar dongyunlee avatar heersin avatar jax777 avatar lorexxar avatar luckyc4t avatar mark0smith avatar sisselcbp avatar sndav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kunlun-m's Issues

关于适配框架的思考

作者师傅好,最近在看cobra.py的代码,特别是核心代码parser.py,发现你对这个文件改动最多,修复了不少问题,但是对于静态扫描框架一筹莫展,不知能否给一些提示,如何适配php的框架,比如laravel、symfony、yii等,以及可能会取得什么样的效果。或者采用php运行时检测hook的那种方式能取得比较好的效果?

赋值语句右边常量拼接存在递归冗余

这个问题我帮你单独提出来

function add_func($di){
	$pid="random"+"goood";
	mysql_query($pid);
}

回溯如下

[DEBUG] [MainThread] [18:42:42] [parser.py:1320] [AST] vul_function:mysql_query
[DEBUG] [MainThread] [18:42:42] [parser.py:1127] [AST] AST to find param Variable('$pid')
[DEBUG] [MainThread] [18:42:42] [parser.py:602] [BT] param=Variable('$pid'),nodes=[Function('add_func', [FormalParameter('$di', None, False, None)], [Assignment(Variable('$pid'), BinaryOp('+', 'random', 'goood'), False), FunctionCall('mysql_query', [Parameter(Variable('$pid'), False)])], False)],function_params=None, lineno=5,function_flag=0,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=0
[DEBUG] [MainThread] [18:42:42] [parser.py:797] [AST] param $pid line 5 in function add_func line 3, start ast in function
[DEBUG] [MainThread] [18:42:42] [parser.py:602] [BT] param=Variable('$pid'),nodes=[Assignment(Variable('$pid'), BinaryOp('+', 'random', 'goood'), False)],function_params=[FormalParameter('$di', None, False, None)], lineno=3,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [18:42:42] [parser.py:732] [AST] Find $pid from list for ['random', 'goood'] in line 4, start ast for list ['random', 'goood']
[DEBUG] [MainThread] [18:42:42] [parser.py:602] [BT] param=Variable('random'),nodes=[],function_params=[FormalParameter('$di', None, False, None)], lineno=3,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [18:42:42] [parser.py:602] [BT] param=Variable('goood'),nodes=[],function_params=[FormalParameter('$di', None, False, None)], lineno=3,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [18:42:42] [engine.py:809] [AST] [RET] []

IndexError: tuple index out of range

[12:01:51][cast.py:307] [AST] New vul function Music.prototype._removeHtml()
[12:01:51][engine.py:155] [New Rule] Error to unpack function param, Something error
Traceback (most recent call last):
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\engine.py", line 32, in init_match_rule
if data[2]:
IndexError: tuple index out of range

没有标记内置函数导致的深度递归搜索问题

没有标记内置函数导致的深度递归搜索问题

范例如下

protected function parse($str)
	{
		$str = $this->removeComments($str);
		$str = $this->parseIncludeComponent($str); 
		// 回车 换行
		$str = str_replace("{CR}", "<?php echo \"\\r\";?>", $str);
		$str = str_replace("{LF}", "<?php echo \"\\n\";?>", $str); 
		// if else elseif
		$str = preg_replace("/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str);
		$str = preg_replace("/\{else\}/", "<?php } else { ?>", $str);
		$str = preg_replace("/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str);
		$str = preg_replace("/\{\/if\}/", "<?php } ?>", $str); 
		// loop
		$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('<?php if(isset(\\1) && is_array(\\1)) foreach(\\1 as \\2) { ?>')", $str);
		$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/e", "\$this->addquote('<?php if(isset(\\1) && is_array(\\1)) foreach(\\1 as \\2=>\\3) { ?>')", $str);
		$str = preg_replace("/\{\/loop\}/", "<?php } ?>", $str); 
		// url生成
		$str = preg_replace("/\{url\(([^}]+)\)\}/", "<?php echo LtObjectUtil::singleton('LtUrl')->generate(\\1);?>", $str); 

		// 函数
		$str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\s*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str);
		$str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \$\\1;?>", $str); 
		// 变量
		/**
		 * 放弃支持$name.name.name

在处理分析$str,如果右值为functioncall,那么就会将右值的函数名作为新的搜索目标进入一个子递归分析中。

由于这是内置函数,所以这里产生了大量的分析代价。甚至导致严重的递归问题

CVI-1004部分语句支持误差

$query  = "SELECT id, name, inserted, size FROM products WHERE size = '$size' ORDER BY $order LIMIT $limit, $offset;";

if ($getInfo['expire']>time()) {$plan = $odb -> query("SELECT `plans`.`name` FROM `users`, `plans` WHERE `plans`.`ID` = `users`.`membership` AND `users`.`ID` = '$id'") -> fetchColumn(0);} else {$plan='No membership';}

在面对上面两种情况的时候,没办法有效的区分

javascript中常出现的对象传递语法

//---------------TEST CASE 28-------------  // PASS
function apple(fruit){
    if(fruit.hasOwnProperty('innerHTML'))
       return fruit.innerHTML;
}
yahoo=document.getElementsByTagName('div')[0];
mango=apple(yahoo);
mango=location.hash.split('#')[1]
//---------------TEST CASE 29------------  // PASS
function apple(fruit){
       if(fruit.hasOwnProperty('innerHTML'))
           return fruit.innerHTML;
}
yahoo=document.getElementsByTagName('div');
mango=apple(yahoo[0]);
url = location.hash.split('#')[1]
mango = "Hello" + url + "!";
//---------------TEST CASE 30------------  // PASS
function apple(fruit,cake){
       fruit+="";
       if(cake.hasOwnProperty('innerHTML'))
           return cake.innerHTML;
}
yahoo=document.getElementsByTagName('div')[0];
berry="123";
mango=apple(berry,yahoo);
mango=location.hash.split('#')[1]
//---------------TEST CASE 32------------  (KFP)
function apple(fruit){
   if(fruit.hasOwnProperty('innerHTML'))
      return fruit.innerText;
    else
      return fruit.innerHTML;
}
yahoo=document.getElementsByTagName('div')[0];
mango=apple(yahoo);
mango=location.hash.split('#')[1]

这4个例子都涉及到了同一个问题,就是对象传递,其关键对象传递的逻辑不符合我们常见的参数传递逻辑。

如果想要保证分析的流上下文相关性,那就必须保证是以对象传递为中心,但是自定义匹配目前是参数传递为中心,如果适配对象传递不知道会不会出现新的问题

function扫描方式下寻找目标函数无法准确解析所有语法

<?php

function read_file($li){
    return @file_get_contents($li);
}

function read_file2($li){
    return file_get_contents($li);
}


read_file(aaa($_GET['a']));
read_file2(aaa($_GET['a']));

因为敏感函数调用在return中,所以要找到漏洞函数,则需要分析当前行语句,然后解析寻找

扫描java代码报无匹配规则错误

System and Python Environment

Item Tooltip Value
System uname -a
Python python -V
Cobra python cobra.py

Description

[Description of the bug or feature]

Steps to Reproduce

  1. [First Step]
  2. [Second Step]
  3. [and so on...]

Expected behavior: [What you expected to happen]

Actual behavior: [What actually happened]

AttributeError: 'NoneType' object has no attribute 'type'

[12:02:21][engine.py:1001] Traceback (most recent call last):
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\engine.py", line 970, in scan
    result = js_scan_parser(rule_match, self.line_number, self.file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1668, in scan_parser
    analysis(all_nodes, func, back_node, int(vul_lineno), file_path, function_params=None)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1607, in analysis
    analysis_expression(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1545, in analysis_expression
    analysis_callexpression(expression, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1500, in analysis_callexpression
    analysis(nodes, vul_function, back_node, int(vul_lineno), file_path, function_params=function_params,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1622, in analysis
    analysis_If(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1450, in analysis_If
    analysis([if_body], vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1619, in analysis
    analysis(node.body, vul_function, back_node, vul_lineno, file_path, function_params=function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1629, in analysis
    analysis_callexpression(child_node.init, vul_function, back_node, vul_lineno, file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1500, in analysis_callexpression
    analysis(nodes, vul_function, back_node, int(vul_lineno), file_path, function_params=function_params,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1615, in analysis
    analysis(node.body.body, vul_function, back_node, vul_lineno, file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1622, in analysis
    analysis_If(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1454, in analysis_If
    analysis([else_body], vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1619, in analysis
    analysis(node.body, vul_function, back_node, vul_lineno, file_path, function_params=function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1622, in analysis
    analysis_If(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1454, in analysis_If
    analysis([else_body], vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1619, in analysis
    analysis(node.body, vul_function, back_node, vul_lineno, file_path, function_params=function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1622, in analysis
    analysis_If(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1450, in analysis_If
    analysis([if_body], vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1619, in analysis
    analysis(node.body, vul_function, back_node, vul_lineno, file_path, function_params=function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1607, in analysis
    analysis_expression(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1545, in analysis_expression
    analysis_callexpression(expression, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1493, in analysis_callexpression
    analysis_params(node, back_node, vul_function, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1425, in analysis_params
    is_co, cp, expr_lineno = deep_parameters_back(param, back_node, function_params, count, file_path, vul_lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1365, in deep_parameters_back
    is_co, cp, expr_lineno = parameters_back(param, back_node, function_params, lineno, vul_function=vul_function,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1340, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1340, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1324, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, else_body, function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1313, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, if_body, function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1054, in parameters_back
    if is_thisexp(cp):
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 272, in is_thisexp
    if node.object.type == "ThisExpression":
AttributeError: 'NoneType' object has no attribute 'type'

AttributeError: 'NoneType' object has no attribute 'loc'

File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1340, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 903, in parameters_back
expr_lineno = node.init.loc.start.line
AttributeError: 'NoneType' object has no attribute 'loc'

function-regex模式跳出限制不明的问题

function-regex模式起初是被设计为会跑完所有的恶意地址。

但实际上来说,只取了列表的第一个

                        if len(result) > 0:
                            if result[0]['code'] == 1:  # 函数参数可控
                                return True, 'Function-param-controllable', result[0]['chain']

                            elif result[0]['code'] == 2:  # 漏洞修复
                                return False, 'Function-param-controllable but fixed', result[0]['chain']

                            elif result[0]['code'] == 3:  # 疑似漏洞
                                return True, 'Unconfirmed Function-param-controllable', result[0]['chain']

                            elif result[0]['code'] == -1:  # 函数参数不可控
                                return False, 'Function-param-uncon', result[0]['chain']

                            elif result[0]['code'] == 4:  # 新规则生成
                                return False, 'New Core', result[0]['source']

                            logger.debug('[AST] [CODE] {code}'.format(code=result[0]['code']))
                        else:
                            logger.debug(
                                '[AST] Parser failed / vulnerability parameter is not controllable {r}'.format(
                                    r=result))
                            return False, 'Can\'t parser'

所以列表后面的就变得无意义了。

假设如果一行语句中同时存在两个敏感函数,如果第一个可控,第二个不可控,那么第二个就会被忽略,匹配到第一个之后就会直接结束。

变量赋值时右值为变量拼接时存在问题

function add_func($did){
	$did=$_GET['maple'];
	$pid="random";
	$pid=$pid.$did;
	$a = $pid ^ 'randow';
	$b = $a.'aaaaaaaaaaaaaaaaaaaaaaaaaaa';
	mysql_query($b);
}

为什么这里会选择略过呢? 考虑了什么逻辑?

[DEBUG] [MainThread] [17:50:53] [parser.py:1314] [AST] vul_function:mysql_query
[DEBUG] [MainThread] [17:50:53] [parser.py:1121] [AST] AST to find param Variable('$b')
[DEBUG] [MainThread] [17:50:53] [parser.py:791] [AST] param $b line 10 in function add_func line 3, start ast in function
[DEBUG] [MainThread] [17:50:53] [parser.py:728] [AST] Find $b from list for ['$a', 'aaaaaaaaaaaaaaaaaaaaaaaaaaa'] in line 9, start ast for list ['$a', 'aaaaaaaaaaaaaaaaaaaaaaaaaaa']
[DEBUG] [MainThread] [17:50:53] [parser.py:728] [AST] Find $a from list for ['$pid', 'randow'] in line 8, start ast for list ['$pid', 'randow']
[DEBUG] [MainThread] [17:50:53] [parser.py:728] [AST] Find $pid from list for ['$pid', '$did'] in line 6, start ast for list ['$pid', '$did']
[DEBUG] [MainThread] [17:50:53] [parser.py:741] [AST] param $pid in list ['$pid', '$did'], continue...
[DEBUG] [MainThread] [17:50:53] [parser.py:640] [AST] Find $pid=random in line 0, start ast for param random
[DEBUG] [MainThread] [17:50:53] [engine.py:809] [AST] [RET] []

if else中有严重的重复分析代码的递归

因为if else属于不同的代码块,其中变量互不影响,在完成时,是通过每一部分都进入新的递归逻辑。

但是debug发现,因为递归返回后,node没有改变,那么这部分递归仍然会重复,严重就会导致死循环,如果跳出if else的条件判断。

当污点传播到数组时没有正确的进入子作用域递归

Windows 10 x64 python3.8

Traceback (most recent call last):
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\cast.py", line 245, in is_controllable_param
_is_co, _cp, expr_lineno, chain = php_anlysis_params(param_name, self.file_path, self.line, self.sr.vul_function, self.repair_functions, self.controlled_list, isexternal=True)
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 1368, in anlysis_params
is_co, cp, expr_lineno = deep_parameters_back(param, vul_nodes, function_params, count, file_path, vul_lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 1200, in deep_parameters_back
is_co, cp, expr_lineno = parameters_back(param, back_node, function_params, lineno, vul_function=vul_function,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 950, in parameters_back
is_co, cp, expr_lineno = class_back(param, node, lineno, vul_function=vul_function, file_path=file_path,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 566, in class_back
is_co, cp, expr_lineno = parameters_back(param, vul_nodes, lineno=lineno, function_flag=1,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 898, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, vul_nodes, function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 699, in parameters_back
return parameters_back(param, nodes[:-1], function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 1168, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 1168, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 1168, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
[Previous line repeated 11 more times]
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 680, in parameters_back
is_co, cp, expr_lineno = array_back(param, nodes, file_path=file_path, isback=isback)
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\php\parser.py", line 536, in array_back
n_node = php.Variable(param_node_expr.node.value)
AttributeError: 'MethodCall' object has no attribute 'value'

javascript灵活语法中出现eval伪语法代码

javascript灵活语法中出现eval伪语法代码无法解决...

···
function timedMsg(abc,callback){
if(callback){
var t=setTimeout(eval('callback'),3000);
return 0;
}}
function fire(){
var call = location.hash.split("#")[1];
timedMsg(12,"call");
}

···

AttributeError: 'NoneType' object has no attribute 'split'

 [12:02:20][engine.py:1001] Traceback (most recent call last):
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\engine.py", line 970, in scan
    result = js_scan_parser(rule_match, self.line_number, self.file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1668, in scan_parser
    analysis(all_nodes, func, back_node, int(vul_lineno), file_path, function_params=None)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1607, in analysis
    analysis_expression(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1545, in analysis_expression
    analysis_callexpression(expression, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1500, in analysis_callexpression
    analysis(nodes, vul_function, back_node, int(vul_lineno), file_path, function_params=function_params,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1607, in analysis
    analysis_expression(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1545, in analysis_expression
    analysis_callexpression(expression, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1493, in analysis_callexpression
    analysis_params(node, back_node, vul_function, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1425, in analysis_params
    is_co, cp, expr_lineno = deep_parameters_back(param, back_node, function_params, count, file_path, vul_lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1365, in deep_parameters_back
    is_co, cp, expr_lineno = parameters_back(param, back_node, function_params, lineno, vul_function=vul_function,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1186, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, vul_nodes, function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1226, in parameters_back
    is_co, cp, expr_lineno = function_back(node, function_params, back_nodes=nodes, file_path=file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 409, in function_back
    is_co, cp, expr_lineno = parameters_back(param, nodes, function_params, file_path=file_path, isback=isback,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1313, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, if_body, function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1313, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, if_body, function_params, lineno,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1313, in parameters_back
    is_co, cp, expr_lineno = parameters_back(param, if_body, function_params, lineno,
  [Previous line repeated 1 more time]
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1138, in parameters_back
    if callee_name == vul_function or callee_name == "this." + vul_function.split(".")[-1]:

define list变量处理错误问题

在实际的扫描过程中发现,define仍然会有各式各样的结构,还不能有效的解决这个问题

 define SITELIST_TABLE=BinaryOp('.', Variable('$table_prefix'), 'sitelist')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define SMILIES_TABLE=BinaryOp('.', Variable('$table_prefix'), 'smilies')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define SPHINX_TABLE=BinaryOp('.', Variable('$table_prefix'), 'sphinx')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_TEMPLATE_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles_template')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_TEMPLATE_DATA_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles_template_data')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_THEME_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles_theme')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_IMAGESET_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles_imageset')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define STYLES_IMAGESET_DATA_TABLE=BinaryOp('.', Variable('$table_prefix'), 'styles_imageset_data')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define TEAMPAGE_TABLE=BinaryOp('.', Variable('$table_prefix'), 'teampage')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define TOPICS_TABLE=BinaryOp('.', Variable('$table_prefix'), 'topics')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define TOPICS_POSTED_TABLE=BinaryOp('.', Variable('$table_prefix'), 'topics_posted')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define TOPICS_TRACK_TABLE=BinaryOp('.', Variable('$table_prefix'), 'topics_track')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define TOPICS_WATCH_TABLE=BinaryOp('.', Variable('$table_prefix'), 'topics_watch')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define USER_GROUP_TABLE=BinaryOp('.', Variable('$table_prefix'), 'user_group')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define USER_NOTIFICATIONS_TABLE=BinaryOp('.', Variable('$table_prefix'), 'user_notifications')
[DEBUG] [MainThread] [14:10:13] [pretreatment.py:68] [AST][Pretreatment] new define USERS_TABLE=BinaryOp('.', Variable('$table_prefix'), 'users')

'ArrayOffset' object has no attribute 'name'

<?php 

function random($val){
	$b=$_GET['maple'];
	$c=$b[0];
	mysql_query($c);
}

回溯和报错:

[DEBUG] [MainThread] [18:13:28] [engine.py:801] [RULE_MATCH] ['mysql_query', 'mysql_db_query']
[DEBUG] [MainThread] [18:13:28] [parser.py:1316] [AST] vul_function:mysql_query
[DEBUG] [MainThread] [18:13:28] [parser.py:1123] [AST] AST to find param Variable('$c')
[DEBUG] [MainThread] [18:13:28] [parser.py:598] [BT] param=Variable('$c'),nodes=[Function('random', [FormalParameter('$val', None, False, None)], [Assignment(Variable('$b'), ArrayOffset(Variable('$_GET'), 'maple'), False), Assignment(Variable('$c'), ArrayOffset(Variable('$b'), 0), False), FunctionCall('mysql_query', [Parameter(Variable('$c'), False)])], False)],function_params=None, lineno=6,function_flag=0,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=0
[DEBUG] [MainThread] [18:13:28] [parser.py:793] [AST] param $c line 6 in function random line 3, start ast in function
[DEBUG] [MainThread] [18:13:28] [parser.py:598] [BT] param=Variable('$c'),nodes=[Assignment(Variable('$b'), ArrayOffset(Variable('$_GET'), 'maple'), False), Assignment(Variable('$c'), ArrayOffset(Variable('$b'), 0), False)],function_params=[FormalParameter('$val', None, False, None)], lineno=3,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [18:13:28] [parser.py:641] [AST] Find $c=$b in line 5, start ast for param $b
[DEBUG] [MainThread] [18:13:28] [parser.py:598] [BT] param=ArrayOffset(Variable('$b'), 0),nodes=[Assignment(Variable('$b'), ArrayOffset(Variable('$_GET'), 'maple'), False)],function_params=[FormalParameter('$val', None, False, None)], lineno=3,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=0
[DEBUG] [MainThread] [18:13:28] [parser.py:615] [AST] AST analysis for ArrayOffset  in line 5
[DEBUG] [MainThread] [18:13:28] [parser.py:1169] Traceback (most recent call last):
  File "/root/Cobra-W/cobra/core_engine/php/parser.py", line 1155, in anlysis_function
    file_path=file_path)
  File "/root/Cobra-W/cobra/core_engine/php/parser.py", line 1322, in analysis_variable_node
    is_co, cp, expr_lineno, chain = anlysis_params(param, file_path, param_lineno, vul_function=vul_function)
  File "/root/Cobra-W/cobra/core_engine/php/parser.py", line 1133, in anlysis_params
    vul_function=vul_function)
  File "/root/Cobra-W/cobra/core_engine/php/parser.py", line 967, in deep_parameters_back
    file_path=file_path, isback=isback, parent_node=0)
  File "/root/Cobra-W/cobra/core_engine/php/parser.py", line 812, in parameters_back
    if node_param.name == cp.name:
AttributeError: 'ArrayOffset' object has no attribute 'name'

[DEBUG] [MainThread] [18:13:28] [engine.py:809] [AST] [RET] []

请问支持php7吗?

RT,另外想主要对php代码做分析,和rips0.55比较,哪个在php上面的表现性能比较好呢?

xss demo

test.jsp
<% out.println(request.getParameter("id")); %>

image

消除来自cobra的历史遗留问题

下个大版本中删除修复来自cobra的历史遗留问题。
1、来自cobra的mac特殊处理
2、不同format的结束输出在迭代过程中坏了
3、output的对接问题
4、来自自定义匹配模式无限多的bug -> 把这部分尽量重构掉
5、统一AST分析中进入递归的逻辑,将return逻辑尽量统一。
6、来自git的输入模式修复
7、逐渐去除在tmp目录下无意义的输出

逻辑结构回溯有问题

function add_func($any){
	$did=$_GET['maple'];
	$pid="random";
	if(1>0){
		$pid=$did;
	}
	mysql_query($pid);
}

递归回溯

[DEBUG] [MainThread] [17:07:12] [parser.py:1317] [AST] vul_function:mysql_query
[DEBUG] [MainThread] [17:07:12] [parser.py:1124] [AST] AST to find param Variable('$pid')
[DEBUG] [MainThread] [17:07:12] [parser.py:598] [BT] param=Variable('$pid'),nodes=[Assignment(Variable('$glob'), ArrayOffset(Variable('$_GET'), 'maple'), False), Function('add_func', [FormalParameter('$di', None, False, None)], [Assignment(Variable('$did'), ArrayOffset(Variable('$_GET'), 'maple'), False), Assignment(Variable('$pid'), 'random', False), If(BinaryOp('>', 1, 0), Block([Assignment(Variable('$pid'), Variable('$did'), False)]), [], None), FunctionCall('mysql_query', [Parameter(Variable('$pid'), False)])], False)],function_params=None, lineno=33,function_flag=0,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=0
[DEBUG] [MainThread] [17:07:12] [parser.py:794] [AST] param $pid line 33 in function add_func line 23, start ast in function
[DEBUG] [MainThread] [17:07:12] [parser.py:598] [BT] param=Variable('$pid'),nodes=[Assignment(Variable('$did'), ArrayOffset(Variable('$_GET'), 'maple'), False), Assignment(Variable('$pid'), 'random', False), If(BinaryOp('>', 1, 0), Block([Assignment(Variable('$pid'), Variable('$did'), False)]), [], None)],function_params=[FormalParameter('$di', None, False, None)], lineno=23,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [17:07:12] [parser.py:849] [AST] param $pid line 27 in if/else, start ast in if/else
[DEBUG] [MainThread] [17:07:12] [parser.py:598] [BT] param=Variable('$pid'),nodes=[Assignment(Variable('$pid'), Variable('$did'), False)],function_params=[FormalParameter('$di', None, False, None)], lineno=27,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=If(BinaryOp('>', 1, 0), Block([Assignment(Variable('$pid'), Variable('$did'), False)]), [], None)
[DEBUG] [MainThread] [17:07:12] [parser.py:641] [AST] Find $pid=$did in line 28, start ast for param $did
[DEBUG] [MainThread] [17:07:12] [parser.py:598] [BT] param=Variable('$did'),nodes=[],function_params=[FormalParameter('$di', None, False, None)], lineno=27,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=0
[DEBUG] [MainThread] [17:07:12] [parser.py:598] [BT] param=Variable('$pid'),nodes=[Assignment(Variable('$did'), ArrayOffset(Variable('$_GET'), 'maple'), False), Assignment(Variable('$pid'), 'random', False)],function_params=[FormalParameter('$di', None, False, None)], lineno=23,function_flag=1,vul_function=mysql_query,file_path=/root/cobra/tests/vulnerabilities/sql.php,isback=False,parent_node=None
[DEBUG] [MainThread] [17:07:12] [parser.py:641] [AST] Find $pid=random in line 0, start ast for param random
[DEBUG] [MainThread] [17:07:12] [engine.py:809] [AST] [RET] []

换成while 也一样,都不能报。cobra可以报,cobra在处理逻辑结构的时候把block里面的节点拿出来放到back_nodes里面去了。

为Cobra-W添加console模式

为Cobra-W添加console模式

可以方便的管理和控制扫描结果,包括查看结果,查看未确认漏洞,管理新敏感函数,管理结果,生成html结果报告。

展示更详细的信息等

UnboundLocalError: local variable 'param' referenced before assignment

[12:01:54][cast.py:323] [AST] Can't get param, check built-in rule
Traceback (most recent call last):
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\cast.py", line 292, in is_controllable_param
_is_co, _cp, expr_lineno, chain = js_analysis_params(param_name, [],
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1425, in analysis_params
is_co, cp, expr_lineno = deep_parameters_back(param, back_node, function_params, count, file_path, vul_lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1365, in deep_parameters_back
is_co, cp, expr_lineno = parameters_back(param, back_node, function_params, lineno, vul_function=vul_function,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1186, in parameters_back
is_co, cp, expr_lineno = parameters_back(param, vul_nodes, function_params, lineno,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1114, in parameters_back
is_co, cp, expr_lineno = function_back(property_value, function_params, nodes, file_path, isback,
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 409, in function_back
is_co, cp, expr_lineno = parameters_back(param, nodes, function_params, file_path=file_path, isback=isback,
UnboundLocalError: local variable 'param' referenced before assignment

扫描逻辑错误

当目标文件小于5行时,不能检测出漏洞,如

<?php


eval($_GET[123]);

大于5行时正常

cobra-w对比cobra

System and Python Environment

Item Tooltip Value
System uname -a CentOS7
Python python -V Python 3.7.0
Cobra python cobra.py cobra-w v1.1.0

Description

对比cobra v2.0.0-alpha.5,最明显的差异是cobra-w没有扫描出dvwa中的命令注入相关的漏洞,而优势是cobra-w扫描出了2处sqli,分别对应路径为sqli/ sqli_blind/

Steps to Reproduce

cobra-w

  1. python cobra.py -t /root/php/dvwa/vulnerabilities/ -f html -o ./cobra_w_dvwa.html
    ACGLFS.png

cobra

  1. python cobra.py -t /root/php/dvwa/vulnerabilities/ -f json -o ./cobra_dvwa.json
    ACGOJg.png

Expected behavior: 期望cobra-w能包含cobra的关键性漏洞

Actual behavior: 未包含最关键的高危漏洞命令注入

[ BUG ] analysis函数两种报错

[WARNING] [MainThread] [10:26:52] [engine.py:582] Traceback (most recent call last):
  File "/Users/litiezhu/Cobra-W/cobra/engine.py", line 560, in scan
    result = scan_parser(code_contents, rule_match, self.line_number, self.file_path)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 778, in scan_parser
    analysis(all_nodes, func, back_node, int(vul_lineno), file_path, function_params=None)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 756, in analysis
    analysis(node.nodes, vul_function, back_node, vul_lineo, function_params)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 753, in analysis
    analysis(node.nodes, vul_function, function_body, vul_lineo, function_params=function_params, file_path=file_path)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 744, in analysis
    analysis_if_else(node, back_node, vul_function, vul_lineo, function_params, file_path=file_path)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 564, in analysis_if_else
    analysis(node.else_.node.nodes, vul_function, back_node, vul_lineno, function_params, file_path=file_path)
TypeError: analysis() got multiple values for keyword argument 'file_path'

主要是analysis函数的file_path参数位置错误,修改完后还有TypeError: analysis() takes at least 5 arguments (4 given)的错误,详情:

[WARNING] [MainThread] [10:28:06] [engine.py:582] Traceback (most recent call last):
  File "/Users/litiezhu/Cobra-W/cobra/engine.py", line 560, in scan
    result = scan_parser(code_contents, rule_match, self.line_number, self.file_path)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 778, in scan_parser
    analysis(all_nodes, func, back_node, int(vul_lineno), file_path, function_params=None)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 756, in analysis
    analysis(node.nodes, vul_function, back_node, vul_lineo, function_params)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 753, in analysis
    analysis(node.nodes, vul_function, function_body, vul_lineo, function_params=function_params, file_path=file_path)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 728, in analysis
    analysis(buffer_, vul_function, back_node, vul_lineo, function_params)
  File "/Users/litiezhu/Cobra-W/cobra/parser.py", line 735, in analysis
    analysis(nodes, vul_function, back_node, vul_lineo)
TypeError: analysis() takes at least 5 arguments (4 given)

参数回溯到数组、字典后不能正确继续回溯

$show = array ('ip'=> '1', 'country' => $_GET['a']);

$ip = $show['ip'];
$country = $show['country'];
$date = date("m-d-Y, h:i:s a" ,$show['date']);
echo '<tr><td><strong>'.htmlentities($ip).'</strong></td><td>'.htmlentities($country).'</td><td>'.htmlentities($date).'</td></tr>';

eval中伪语法在AST中解释错误

eval('if(' . $matches[1][$i] . '){$flag="if";}else{$flag="else";}');

向上述eval中的伪语法做难以做ast分析。

eval中变量整体作为字符串拼接语句,被解释为多个变量拼接

应对多个拼接变量都判断,回溯其中变量

由读取文件一次5行导致的扫描问题

虽然还不能完全确认问题的来源,不过可以肯定的是

从2b2ef4211c8b4f1c124129e01be62dfaf8eaeb43这个分支开始,我尝试通过一次读取5行来解决一个漏洞出现在多行种的解决办法导致了更大的问题。

现在的扫描会导致在参数匹配扫描时出现无法读取参数的严重问题,获取不到函数的参数就无法进行接下来的参数回溯

回溯类中的私有函数存在问题

类中的很多函数是私有的,可能存在多个类中都有私有函数,但是现在没有针对类专门的定制回溯。

ps: 因为私有函数不是可共享的,所以在回溯的时候会发生一些问题,但是想不到有效的办法区分这些不同的函数。

新生成的函数如果是类的魔术方法,那么他就会把所有的都遍历一遍,互相之间有严重的影响。

get函数已经出现了这个问题。

需要想办法对不同的类做区分。

define变量检测读取警告

System and Python Environment

centos7腾讯云服务器
image

Item Tooltip Value
System uname -a
Python python -V
Cobra python cobra.py

Description

[Description of the bug or feature]
运行报错
image

Steps to Reproduce

  1. [First Step]
  2. [Second Step]
  3. [and so on...]

Expected behavior: [What you expected to happen]

Actual behavior: [What actually happened]

敏感语句封装函数,没有回溯函数

类似于下面这种代码

function get_data($url)
{
	$ch = curl_init();
	$timeout = 5;
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
	$data = curl_exec($ch);
	curl_close($ch);
	return $data;
} 

如果出现AB互相生成函数,出现不可解的递归问题

如果出现AB互相生成函数,出现不可解的递归问题

大概代码如下

function A(){
    B();
}
function B(){
   A();
}

尽管这两个函数生成可能会有诸多的限制条件,但是在静态分析中不考虑这么多的条件,则会出现难以避免的递归问题

TypeError: can only concatenate str (not "int") to str

 [12:02:07][engine.py:1001] Traceback (most recent call last):
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\engine.py", line 970, in scan
    result = js_scan_parser(rule_match, self.line_number, self.file_path,
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1668, in scan_parser
    analysis(all_nodes, func, back_node, int(vul_lineno), file_path, function_params=None)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1607, in analysis
    analysis_expression(node, vul_function, back_node, vul_lineno, file_path, function_params)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1548, in analysis_expression
    expression_node = get_member_data(expression.right)
  File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 107, in get_member_data
    value += get_member_data(i.key, isclean_prototype=isclean_prototype)
TypeError: can only concatenate str (not "int") to str

数组变量传递过程中忽略键值

数组变量传递过程中忽略键值

<?php

$c['a'] = $_GET['a'];

$a = $c['d'];

echo $a;

这个代码会被识别为漏洞,因为数组变量传递过程中忽略了键值,这需要专门的逻辑做处理

AttributeError: 'list' object has no attribute 'body'

[12:01:51][cast.py:323] [AST] Can't get param, check built-in rule
Traceback (most recent call last):
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\cast.py", line 292, in is_controllable_param
_is_co, _cp, expr_lineno, chain = js_analysis_params(param_name, [],
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\core_engine\javascript\parser.py", line 1408, in analysis_params
back_node = ast_object.get_nodes(file_path, vul_lineno=vul_lineno, lan='javascript').body
File "D:\Tools\PenetrationTesting\4.Vulnerability_Analysis\CodeAudit\Kunlun-M\core\pretreatment.py", line 439, in get_nodes
allnodes = self.pre_result[filepath]['ast_nodes'].body
AttributeError: 'list' object has no attribute 'body'

secret 修复函数逻辑有问题

echo htmlentities($_GET['a']);

这句语句会被错误的判定为未修复

因为在判断修复函数逻辑之前,先进行了$_GET的基本判断。

判断为可控参数,则直接跳出逻辑

parser.py

is_co, cp = is_controllable(param_name)

if len(nodes) != 0 and is_co != 1:
        node = nodes[len(nodes) - 1]

        if isinstance(node, php.Assignment):  # 回溯的过程中,对出现赋值情况的节点进行跟踪
            param_node = get_node_name(node.node)  # param_node为被赋值的变量
            param_expr, expr_lineno, is_re = get_expr_name(node.expr)  # param_expr为赋值表达式,param_expr为变量或者列表

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.