Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
LoRexxar committed Dec 22, 2017
2 parents 08698f0 + dda90f8 commit b3adbb9
Show file tree
Hide file tree
Showing 24 changed files with 89 additions and 35 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ Cobra-W是从Cobra2.0发展而来的分支,着眼于白帽子使用的白盒
- 修复处理BinaryOp节点时无法正确处理的bug
- 部分修复了issue#9
- 修复了对for节点以及if\else节点的支持

- 2017-12-22
- Cobra-W 0.7.3
- 修复了部分处理ast的bug
- 完善了cvi-1009

# README(开发文档)

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/LoRexxar/Cobra-W/issues/new'
__python_version__ = sys.version.split()[0]
__platform__ = platform.platform()
__version__ = '0.7.2'
__version__ = '0.7.3'
__author__ = 'LoRexxar'
__author_email__ = 'LoRexxar@gmail.com'
__license__ = 'MIT License'
Expand Down
2 changes: 1 addition & 1 deletion cobra/cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def is_controllable_param(self):

logger.debug("[Deep AST] Start AST for param {param_name}".format(param_name=param_name))

_is_co, _cp, expr_lineno = anlysis_params(param_name, param_content, self.file_path, self.line)
_is_co, _cp, expr_lineno = anlysis_params(param_name, param_content, self.file_path, self.line, self.sr.vul_function)

if _is_co == 1:
logger.debug("[AST] Is assign string: `Yes`")
Expand Down
11 changes: 8 additions & 3 deletions cobra/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,13 @@ def __init__(self, target_directory, vulnerability_result, single_rule, project_

self.file_path = vulnerability_result.file_path.strip()
self.line_number = vulnerability_result.line_number
self.code_content = vulnerability_result.code_content.strip()
# self.code_content = vulnerability_result.code_content.strip()
self.code_content = vulnerability_result.code_content
self.files = files

self.rule_match = single_rule.match
self.rule_match_mode = single_rule.match_mode
self.vul_function = single_rule.vul_function
self.cvi = single_rule.svid
self.single_rule = single_rule

Expand Down Expand Up @@ -662,6 +664,7 @@ def init_match_rule(data):

# 去除定义函数
match2 = "function\s+" + function_name
vul_function = function_name

elif isinstance(object, php.Class):
class_params = data[2]
Expand Down Expand Up @@ -693,6 +696,7 @@ def init_match_rule(data):

# 去除定义类,类定义和调用方式不一样,但是为了不影响结构,依然赋值
match2 = "class\s+" + class_name + "\s*{"
vul_function = class_name

except:
logger.error('[New Rule] Error to unpack function param, Something error')
Expand All @@ -701,7 +705,7 @@ def init_match_rule(data):
match2 = None
index = 0

return match, match2, index
return match, match2, vul_function, index


def auto_parse_match(single_match):
Expand Down Expand Up @@ -749,11 +753,12 @@ def NewCore(target_directory, new_rules, files, count=0):
match_mode = "New rule to Vustomize-Match"
logger.debug('[ENGINE] [ORIGIN] match-mode {m}'.format(m=match_mode))

match, match2, index = init_match_rule(new_rules)
match, match2, vul_function, index = init_match_rule(new_rules)
logger.debug('[ENGINE] [New Rule] new match_rule: {}'.format(match))

sr = autorule()
sr.match = match
sr.vul_function = vul_function

# grep

Expand Down
30 changes: 24 additions & 6 deletions cobra/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ def get_filename(node, file_path): # 获取filename
if len(define_params) == 2 and define_params[0].node == constant_node_name:
filenames[i] = define_params[1].node

if isinstance(filenames[i], php.Constant): # 如果还没找到该常量,暂时退出
logger.warning("[AST] [INCLUDE FOUND] Can't found this constart {}, pass it ".format(filenames[i]))
filenames[i] = "not_found"

return filenames


Expand Down Expand Up @@ -290,7 +294,7 @@ def is_controllable(expr, flag=None): # 获取表达式中的变量,看是否
'$_REQUEST',
'$_COOKIE',
'$_FILES',
'$_SERVER',
# '$_SERVER', # 暂时去掉了,误报率太高了
'$HTTP_POST_FILES',
'$HTTP_COOKIE_VARS',
'$HTTP_REQUEST_VARS',
Expand Down Expand Up @@ -616,7 +620,7 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
for node_param in node.params:
if node_param.name == cp.name:

if node.name != vul_function:
if vul_function is None or node.name != vul_function:
logger.info(
"[Deep AST] Now vulnerability function from function {}() param {}".format(node.name,
cp.name))
Expand All @@ -625,6 +629,9 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
cp = tuple([node, param])
return is_co, cp, 0
else:
logger.info(
"[Deep AST] Recursive problems may exist in the code, exit the new rules generated..."
)
return is_co, cp, 0

elif isinstance(node, php.Class):
Expand All @@ -640,12 +647,14 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
if_nodes = [node.node]
if_node_lineno = node.node.lineno

# 进入分析if内的代码块,如果返回参数不同于进入参数,那么在不同的代码块中,变量值不同,不能统一处理,需要递归进入不同的部分
is_co, cp, expr_lineno = parameters_back(param, if_nodes, function_params, if_node_lineno,
function_flag=1, vul_function=vul_function)

if is_co != 1 and is_co != -1: # 当is_co为True时找到可控,停止递归
if is_co == 3 and cp != param: # 理由如上
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
function_flag=1, vul_function=vul_function) # 找到可控的输入时,停止递归
return is_co, cp, expr_lineno

if is_co is not 1 and node.elseifs != []: # elseif可能有多个,所以需要列表

Expand All @@ -660,9 +669,10 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
is_co, cp, expr_lineno = parameters_back(param, elif_nodes, function_params, elif_node_lineno,
function_flag=1, vul_function=vul_function)

if is_co != 1 and is_co != -1: # 当is_co为True时找到可控,停止递归
if is_co == 3 and cp != param: # 理由如上
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
function_flag=1, vul_function=vul_function) # 找到可控的输入时,停止递归
return is_co, cp, expr_lineno
else:
break

Expand All @@ -677,9 +687,10 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
is_co, cp, expr_lineno = parameters_back(param, else_nodes, function_params, else_node_lineno,
function_flag=1, vul_function=vul_function)

if is_co != 1 and is_co != -1: # 当is_co为True时找到可控,停止递归
if is_co == 3 and cp != param: # 理由如上
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
function_flag=1, vul_function=vul_function) # 找到可控的输入时,停止递归
return is_co, cp, expr_lineno

elif isinstance(node, php.For):
for_nodes = node.node.nodes
Expand Down Expand Up @@ -729,6 +740,8 @@ def deep_parameters_back(param, back_node, function_params, count, file_path, li
file_path_list = re.split(r"[\/\\]", file_path)
file_path_list.pop()
file_path_list += filename
if "not_found" in filename:
continue
file_path_name = "/".join(file_path_list)

try:
Expand All @@ -746,7 +759,6 @@ def deep_parameters_back(param, back_node, function_params, count, file_path, li

is_co, cp, expr_lineno = deep_parameters_back(node, all_nodes, function_params, count, file_path_name,
lineno)

if is_co == -1:
break

Expand Down Expand Up @@ -810,6 +822,8 @@ def anlysis_params(param, code_content, file_path, lineno, vul_function=None):

vul_nodes = []
for node in all_nodes:
if not node:
continue
if node.lineno < int(lineno):
vul_nodes.append(node)

Expand Down Expand Up @@ -1044,10 +1058,14 @@ def analysis_if_else(node, back_node, vul_function, vul_lineno, function_params=
nodes = []
if isinstance(node.node, php.Block): # if语句中的sink点以及变量
analysis(node.node.nodes, vul_function, back_node, vul_lineno, file_path, function_params)
else:
analysis([node.node], vul_function, back_node, vul_lineno, file_path, function_params)

if node.else_ is not None: # else语句中的sink点以及变量
if isinstance(node.else_.node, php.Block):
analysis(node.else_.node.nodes, vul_function, back_node, vul_lineno, file_path, function_params)
else:
analysis([node.node], vul_function, back_node, vul_lineno, file_path, function_params)

if len(node.elseifs) != 0: # elseif语句中的sink点以及变量
for i_node in node.elseifs:
Expand Down
1 change: 1 addition & 0 deletions rules/autorule.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self):
# 部分配置
self.match_mode = "vustomize-match"
self.match = ""
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1000.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "print|print_r|exit|die|printf|vprintf|trigger_error|user_error|odbc_result_all|ovrimos_result_all|ifx_htmltbl_result"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_10001.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self):
# 部分配置
self.match_mode = "vustomize-match"
self.match = "(echo\s?['\"]?(.+?)?\$(.+?)?['\"]?(.+?)?;)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1001.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self):
# 部分配置
self.match_mode = "vustomize-match"
self.match = "curl_setopt\s*\(.*,\s*CURLOPT_URL\s*,(.*)\)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1002.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "file_get_contents"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1003.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "get_headers"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1004.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "vustomize-match"
self.match = "([\"\']+\s*(select|SELECT|insert|INSERT|update|UPDATE)\s+([^;]\s*)(.*)\$(.+?)[\'\"]+(.+?)?;)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1005.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "(mysql_query|mysql_db_query)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1006.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "(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?\(]"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1007.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "include|include_once|require|require_once|parsekit_compile_file|php_check_syntax|runkit_import|virtual"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1008.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "simplexml_load_file|simplexml_load_string"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
3 changes: 2 additions & 1 deletion rules/php/CVI_1009.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def __init__(self):

# 部分配置
self.match_mode = "function-param-regex"
self.match = "(array_map|create_function|call_user_func|call_user_func_array|assert|eval|dl|register_tick_function|register_shutdown_function|preg_replace)"
self.match = "(array_map|create_function|call_user_func|call_user_func_array|assert|eval|dl|register_tick_function|register_shutdown_function|preg_replace|preg_replace_callback)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1011.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "(system|passthru|exec|pcntl_exec|shell_exec|popen|proc_open|ob_start|expect_popen|mb_send_mail|w32api_register_function|w32api_invoke_function|ssh2_exec)"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1012.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "(print_r|var_dump|show_source|highlight_file)\s*\("
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1013.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "header"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1014.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "import_request_variables|parse_str|mb_parse_str"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/CVI_1015.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "is_a|unserialize"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
1 change: 1 addition & 0 deletions rules/php/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self):
# 部分配置
self.match_mode = "function-param-regex"
self.match = "echo|print|print_r|exit|die|printf|vprintf|trigger_error|user_error|odbc_result_all|ovrimos_result_all|ifx_htmltbl_result"
self.vul_function = None

def main(self, regex_string):
"""
Expand Down
Loading

0 comments on commit b3adbb9

Please sign in to comment.