Skip to content
This repository has been archived by the owner on Nov 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #576 from wufeifei/develop
Browse files Browse the repository at this point in the history
Released v2.0.0-alpha.4
  • Loading branch information
FeeiCN authored Sep 12, 2017
2 parents ce5a5c9 + a60cd60 commit 0ba8a0b
Show file tree
Hide file tree
Showing 66 changed files with 1,112 additions and 147 deletions.
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ Cobra Changelog

Here you can see the full list of changes between each Cobra release.

Version 2.0.0-alpha.4
---------------------

Released on Sep 12 2017

- 增加WebShell规则和测试用例 #571
- 支持FPC模式修复函数 #565 #559
- 其它细节优化和Bug修复

Version 2.0.0-alpha.3
---------------------

Expand Down
2 changes: 1 addition & 1 deletion cobra/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__issue_page__ = 'https://github.com/wufeifei/cobra/issues/new'
__python_version__ = sys.version.split()[0]
__platform__ = platform.platform()
__version__ = '2.0.0-alpha.3'
__version__ = '2.0.0-alpha.4'
__author__ = 'Feei'
__author_email__ = '[email protected]'
__license__ = 'MIT License'
Expand Down
2 changes: 1 addition & 1 deletion cobra/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def __init__(self, level1=None, level2=None):
value = config.get(level1, level2)
except Exception as e:
traceback.print_exc()
logger.critical("./configs file configure failed.\nError: {0}".format(e.message))
logger.critical("./configs file configure failed. {u}\nError: {e}".format(u='https://wufeifei.github.io/cobra/config', e=e.message))
self.value = value

@staticmethod
Expand Down
9 changes: 6 additions & 3 deletions cobra/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def is_annotation(self):
- Java:
:return: boolean
"""
match_result = re.findall(r"(#|\\\*|\/\/)+", self.code_content)
match_result = re.findall(r"^(#|\\\*|\/\/)+", self.code_content)
# Skip detection only on match
if self.is_match_only_rule():
return False
Expand Down Expand Up @@ -620,13 +620,16 @@ def scan(self):
if self.file_path[-3:].lower() == 'php':
try:
ast = CAST(self.rule_match, self.target_directory, self.file_path, self.line_number, self.code_content)
rule_repair = []
if self.rule_match_mode == const.mm_function_param_controllable:
rule_match = self.rule_match.strip('()').split('|')
rule_match = self.rule_match.strip('()').split('|') # 漏洞规则整理为列表
if self.rule_repair is not None:
rule_repair = self.rule_repair.strip('()').split('|') # 修复规则整理为列表
logger.debug('[RULE_MATCH] {r}'.format(r=rule_match))
try:
with open(self.file_path, 'r') as fi:
code_contents = fi.read()
result = scan_parser(code_contents, rule_match, self.line_number)
result = scan_parser(code_contents, rule_match, self.line_number, rule_repair)
logger.debug('[AST] [RET] {c}'.format(c=result))
if len(result) > 0:
if result[0]['code'] == 1: # 函数参数可控
Expand Down
14 changes: 10 additions & 4 deletions cobra/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

with_line = True
scan_results = [] # 结果存放列表初始化
repairs = [] # 用于存放修复函数


def export(items):
Expand Down Expand Up @@ -134,7 +135,7 @@ def get_binaryop_params(node): # 当为BinaryOp类型时,分别对left和righ
if isinstance(node.right, php.Variable):
params.append(node.right.name)

elif not isinstance(node.right, php.Variable) or not isinstance(node.left, php.Variable): # right不为变量时
if not isinstance(node.right, php.Variable) or not isinstance(node.left, php.Variable): # right不为变量时
params_right = get_binaryop_deep_params(node.right, params)
params_left = get_binaryop_deep_params(node.left, params)

Expand Down Expand Up @@ -213,8 +214,10 @@ def is_repair(expr):
:return:
"""
is_re = False # 是否修复,默认值是未修复
if expr == 'escapeshellcmd':
is_re = True
for repair in repairs:
if expr == repair:
is_re = True
return is_re
return is_re


Expand Down Expand Up @@ -661,16 +664,19 @@ def analysis(nodes, vul_function, back_node, vul_lineo, function_params=None):
back_node.append(node)


def scan_parser(code_content, sensitive_func, vul_lineno):
def scan_parser(code_content, sensitive_func, vul_lineno, repair):
"""
开始检测函数
:param code_content: 要检测的文件内容
:param sensitive_func: 要检测的敏感函数,传入的为函数列表
:param vul_lineno: 漏洞函数所在行号
:param repair: 对应漏洞的修复函数列表
:return:
"""
try:
global repairs
global scan_results
repairs = repair
scan_results = []
parser = make_parser()
all_nodes = parser.parse(code_content, debug=False, lexer=lexer.clone(), tracking=with_line)
Expand Down
3 changes: 2 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
| 290 | LB | Logic Bug | 逻辑错误 |
| 320 | VO | Variables Override | 变量覆盖漏洞 |
| 350 | WF | Weak Function | 不安全的函数 |
| 355 | WE |Weak Encryption | 不安全的加密 |
| 355 | WE | Weak Encryption | 不安全的加密 |
| 360 | WS | WebShell | WebShell |
| 970 | AV | Android Vulnerabilities | Android漏洞 |
| 980 | IV | iOS Vulnerabilities | iOS漏洞 |
| 999 | IC | Insecure Components| 引用了存在漏洞的三方组件(Maven/Pods/PIP/NPM) |
Expand Down
1 change: 1 addition & 0 deletions docs/labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
| 320 | VO | Variables Override | 变量覆盖漏洞 |
| 350 | WF | Weak Function | 不安全的函数 |
| 355 | WE |Weak Encryption | 不安全的加密 |
| 360 | WS | WebShell | WebShell |
| 970 | AV | Android Vulnerabilities | Android漏洞 |
| 980 | IV | iOS Vulnerabilities | iOS漏洞 |
| 999 | IC | Insecure Components| 引用了存在漏洞的三方组件(Maven/Pods/PIP/NPM) |
Expand Down
20 changes: 9 additions & 11 deletions rules/CVI-120001.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,19 @@
<level value="6"/>
<test>
<case assert="true"><![CDATA[
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
$url = $_GET['url'];
curl($url);
]]></case>
</test>
<solution>
## 安全风险

SSRF漏洞(Server-Side Request Forgery)

### 形成原理
Expand All @@ -42,7 +41,6 @@
curl_exec($ch);
curl_close($ch);
}

$url = $_GET['url'];
curl($url);
```
Expand Down
8 changes: 4 additions & 4 deletions rules/CVI-120002.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
<level value="7"/>
<test>
<case assert="true"><![CDATA[
$url = $_GET['url'];
echo file_get_contents($url);
$url = $_GET['url'];
echo file_get_contents($url);
]]></case>
<case assert="false"><![CDATA[
$url = "http://www.example.com";
echo file_get_contents($url);
$url = "http://www.example.com";
echo file_get_contents($url);
]]></case>
</test>
<solution>
Expand Down
3 changes: 1 addition & 2 deletions rules/CVI-120003.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<name value="get_headers导致的SSRF"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[get_headers]]></match>
<repair block="in-function-up"><![CDATA[in_array\s*\(\s*{{PARAM}}\s*,|preg_match(?:_all)?\s*\(\s*(?:.+?)\s*,\s*{{PARAM}}\s*[,\)]]]></repair>
<level value="7"/>
<test>
<case assert="true"><![CDATA[
Expand Down Expand Up @@ -41,5 +40,5 @@
```
</solution>
<status value="on"/>
<author name="Lightless" email="[email protected]"/>
<author name="Lightless" email="[email protected]"/>
</cobra>
35 changes: 35 additions & 0 deletions rules/CVI-120004.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<cobra document="https://github.com/wufeifei/cobra">
<name value="fsockopen造成的SSRF"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[fsockopen]]></match>
<level value="7"/>
<test>
<case assert="true"><![CDATA[
$host = $_GET['host'];
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
]]></case>
</test>
<solution>
## 安全风险
SSRF漏洞(Server-Side Request Forgery)

### 形成原理
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

### 风险
1、攻击者可以对外网、服务器所在内网、本地进行端口扫描,获取服务的banner信息。
2、攻击运行在内网或本地的应用程序。
3、对内网web应用进行指纹识别。
4、攻击内外网的web应用。
5、利用file协议读取本地文件等。

## 修复方案
1. 限制协议为HTTP、HTTPS
2. 限制请求域名白名单
3. 禁止30x跳转

</solution>
<status value="on"/>
<author name="JoyChou" email="[email protected]"/>
</cobra>
1 change: 0 additions & 1 deletion rules/CVI-140001.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>

<cobra document="https://github.com/wufeifei/cobra">
<name value="文本框反射型XSS"/>
<language value="jsp"/>
Expand Down
3 changes: 1 addition & 2 deletions rules/CVI-140002.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<cobra document="https://github.com/wufeifei/cobra">
<name value="输出入参"/>
<name value="输出入参可能导致XSS"/>
<language value="java"/>
<match mode="regex-only-match"><![CDATA[out\.println\s*\(\s*request\.get(Parameter|QueryString)\s*\(\s*\"]]></match>
<level value="4"/>
Expand Down
2 changes: 1 addition & 1 deletion rules/CVI-140003.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<name value="直接输出入参可能导致XSS"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[(echo|print|print_r|exit|die|printf|vprintf|trigger_error|user_error|odbc_result_all|ovrimos_result_all|ifx_htmltbl_result)]]></match>
<repair block="in-function"><![CDATA[(htmlspecialchars\s*\(\s*{{PARAM}}\s*)]]></repair>
<repair block="in-function"><![CDATA[(htmlspecialchars]]></repair>
<level value="4"/>
<test>
<case assert="true"><![CDATA[print_r ($_GET['test']);]]></case>
Expand Down
22 changes: 0 additions & 22 deletions rules/CVI-140004.xml

This file was deleted.

1 change: 0 additions & 1 deletion rules/CVI-160001.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>

<cobra document="https://github.com/wufeifei/cobra">
<name value="拼接SQL注入"/>
<language value="java"/>
Expand Down
2 changes: 1 addition & 1 deletion rules/CVI-160002.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<case assert="false"><![CDATA[$query = "SELECT id FROM products LIMIT 20 ;";]]></case>
<case assert="true"><![CDATA[$s = "select" + $v + "from " + $tb + "where id = " + $id;]]></case>
<case assert="true"><![CDATA[
$query = "SELECT id, name, inserted, size FROM products
$query = "SELECT id, name, inserted, size FROM products
WHERE size = '$size'
ORDER BY $order
LIMIT $limit, $offset;";
Expand Down
2 changes: 1 addition & 1 deletion rules/CVI-160003.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<name value="MySQL Execute Functions可能导致SQL注入"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[(mysql_query|mysql_db_query)]]></match>
<repair block="in-function"><![CDATA[(?:mysql_real_escape_string|addslashes)\s*\(\s*{{PARAM}}\s*[\),]]]></repair>
<repair block="in-function"><![CDATA[(mysql_real_escape_string|addslashes)]]></repair>
<level value="8"/>
<test>
<case assert="true"><![CDATA[
Expand Down
2 changes: 1 addition & 1 deletion rules/CVI-160004.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<cobra document="https://github.com/wufeifei/cobra">
<name value="SQL Execute Functions可能导致SQL注入"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[(mysqli_query|pg_execute|pg_insert|pg_query|pg_select|pg_update|sqlite_query|msql_query|mssql_query|odbc_exec|fbsql_query|sybase_query|ibase_query|dbx_query|ingres_query|ifx_query|oci_parse|sqlsrv_query|maxdb_query|db2_exec)\s?\(]]></match>
<match mode="function-param-controllable"><![CDATA[(mysqli_query|pg_execute|pg_insert|pg_query|pg_select|pg_update|sqlite_query|msql_query|mssql_query|odbc_exec|fbsql_query|sybase_query|ibase_query|dbx_query|ingres_query|ifx_query|oci_parse|sqlsrv_query|maxdb_query|db2_exec)]]></match>
<level value="8"/>
<test>
<case assert="true"><![CDATA[
Expand Down
30 changes: 30 additions & 0 deletions rules/CVI-165001.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<cobra document="https://github.com/wufeifei/cobra">
<name value="LDAP注入"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[(ldap_add|ldap_delete|ldap_list|ldap_read|ldap_search|ldap_bind)]]></match>
<repair block="in-function-up"><![CDATA[ldap_escape\s*\(\s*.+?\s*,\s*.+?\s*,\s*LDAP_ESCAPE_FILTER\s*\)]]></repair>
<level value="5"/>
<test>
<case assert="true"><![CDATA[
$surname=$_GET['surname'];
$filter = "(sn=" . $surname . ")";
$sr=ldap_search($ds, "o=My Company, c=US", $filter);
$info = ldap_get_entries($ds, $sr);
]]></case>
</test>
<solution>
## 安全风险

LDAP Injection
允许进行LDAP查询 + 输入未进行过滤 ---> LDAP注入
这种威胁可以让攻击者能够从LADP树中提取到很多很重要的信息

## 修复方案
对用户输入数据中包含的”语言本身的保留字符”进行转义(例如可以使用`ldap_escape`)

</solution>
<status value="on"/>
<author name="Feei" email="[email protected]"/>
</cobra>

9 changes: 1 addition & 8 deletions rules/CVI-167001.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,13 @@
<level value="5"/>
<test>
<case assert="true"><![CDATA[
<?php
$xml = $_POST['xml'];
$data = simplexml_load_string($xml);
?>
]]></case>
<case assert="false"><![CDATA[
<?php
$xml = $_POST['xml'];
libxml_disable_entity_loader(true);
$data = simplexml_load_string($xml);
?>
]]></case>
</test>
<solution>
Expand All @@ -42,18 +38,15 @@

## 举例
```php
<?php
$xml = $_POST['xml'];
$data = simplexml_load_string($xml);
?>
```
修改后代码
```php
<?php
$xml = $_POST['xml'];
libxml_disable_entity_loader(true);
$data = simplexml_load_string($xml);
?>
```
</solution>
<status value="on"/>
<author name="Lightless" email="[email protected] "/>
Expand Down
2 changes: 1 addition & 1 deletion rules/CVI-180001.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<cobra document="https://github.com/wufeifei/cobra">
<name value="远程代码执行"/>
<language value="php"/>
<match mode="function-param-controllable"><![CDATA[(array_map|create_function|call_user_func|call_user_func_array|assert|eval|dl|register_tick_function|register_shutdown_function|preg_replace)]]></match>
<match mode="function-param-controllable"><![CDATA[(array_map|create_function|call_user_func|call_user_func_array|assert|eval|dl|register_tick_function|register_shutdown_function|array_filter|array_reduce|array_diff_ukey|array_udiff|array_walk|array_walk_recursive|uasort|uksort|usort)]]></match>
<level value="10"/>
<test>
<case assert="true"><![CDATA[array_map($_GET['pass'],$array);]]></case>
Expand Down
Loading

0 comments on commit 0ba8a0b

Please sign in to comment.