Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
LoRexxar committed Jan 9, 2018
2 parents ad22f31 + 0eb998a commit 8bab33c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ Cobra-W是从Cobra2.0发展而来的分支,着眼于白帽子使用的白盒
- 2017-12-28
- Cobra-W 0.8.1
- 修复了secret机制对auto rule的支持
- 2018-01-09
- Cobra-W 0.8.2
- 修复了部分bug
- 添加部分debug log用于调试

# 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.8.1'
__version__ = '0.8.2'
__author__ = 'LoRexxar'
__author_email__ = '[email protected]'
__license__ = 'MIT License'
Expand Down
9 changes: 5 additions & 4 deletions cobra/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def parse_match(self, single_match):

class Core(object):
def __init__(self, target_directory, vulnerability_result, single_rule, project_name, white_list, test=False,
index=None, files=None, secret_name=None):
index=0, files=None, secret_name=None):
"""
Initialize
:param: target_directory:
Expand Down Expand Up @@ -672,13 +672,13 @@ def init_match_rule(data):
index += 1

# curl_setopt\s*\(.*,\s*CURLOPT_URL\s*,(.*)\)
match = "\\b" + function_name + "\s*\("
match = "(?:\A|\s)" + function_name + "\s*\("
for i in xrange(len(function_params)):
if i != 0:
match += ","

if function_params[i].default is not None:
match += "?"
if function_params[i].default is not None:
match += "?"

if i == index:
match += "(.*)"
Expand Down Expand Up @@ -762,6 +762,7 @@ def auto_parse_match(single_match, svid, language):
def NewCore(old_single_rule, target_directory, new_rules, files, count=0, secret_name=None):
"""
处理新的规则生成
:param old_single_rule:
:param secret_name:
:param target_directory:
:param new_rules:
Expand Down
44 changes: 41 additions & 3 deletions cobra/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ def is_repair(expr):
is_re = False # 是否修复,默认值是未修复
global is_repair_functions
if expr in is_repair_functions:
logger.debug("[AST] function {} in is_repair_functions, The vulnerability does not exist ")
is_re = True
return is_re

Expand Down Expand Up @@ -542,14 +543,17 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
"""

if isinstance(param, php.FunctionCall) or isinstance(param, php.MethodCall): # 当污点为寻找函数时,递归进入寻找函数
logger.debug("[AST] AST analysis for FunctionCall or MethodCall {} in line {}".format(param.name, param.lineno))
is_co, cp, expr_lineno = function_back(param, nodes, function_params)
return is_co, cp, expr_lineno

if isinstance(param, php.ArrayOffset): # 当污点为数组时,递归进入寻找数组声明或赋值
logger.debug("[AST] AST analysis for ArrayOffset {} in line {}".format(param.name, param.lineno))
is_co, cp, expr_lineno = array_back(param, nodes)
return is_co, cp, expr_lineno

if isinstance(param, php.New) or (hasattr(param, "name") and isinstance(param.name, php.New)): # 当污点为新建类事,进入类中tostring函数分析
logger.debug("[AST] AST analysis for New Class {} in line {}".format(param.name, param.lineno))
is_co, cp, expr_lineno = new_class_back(param, nodes)
return is_co, cp, expr_lineno

Expand All @@ -575,6 +579,9 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
return is_co, cp, expr_lineno

if param_name == param_node and not isinstance(param_expr, list): # 找到变量的来源,开始继续分析变量的赋值表达式是否可控
logger.debug(
"[AST] Find {}={} in line {}, start ast for param {}".format(param_name, param_expr, expr_lineno,
param_expr))
is_co, cp = is_controllable(param_expr) # 开始判断变量是否可控

if is_co != 1 and is_co != 3:
Expand All @@ -589,6 +596,12 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
function_name = node.expr.name
param = node.expr # 如果没找到函数定义,则将函数作为变量回溯

logger.debug(
"[AST] Find {} from FunctionCall for {} in line {}, start ast for function {}".format(param_name,
function_name,
lineno,
function_name))

for node in nodes[::-1]:
if isinstance(node, php.Function):
if node.name == function_name:
Expand All @@ -603,6 +616,11 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
function_params, lineno, function_flag=1, vul_function=vul_function)

if param_name == param_node and isinstance(param_expr, list):
logger.debug(
"[AST] Find {} from list for {} in line {}, start ast for list {}".format(param_name,
param_expr,
lineno,
param_expr))
for expr in param_expr:
param = expr
is_co, cp = is_controllable(expr)
Expand All @@ -624,6 +642,12 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
function_params = node.params
vul_nodes = []

logger.debug(
"[AST] param {} line {} in function {} line {}, start ast in function".format(param_name,
lineno,
node.name,
function_lineno))

for function_node in function_nodes:
if function_node is not None and int(function_lineno) <= function_node.lineno < int(lineno):
vul_nodes.append(function_node)
Expand All @@ -635,8 +659,11 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
if is_co == 3: # 出现新的敏感函数,重新生成新的漏洞结构,进入新的遍历结构
for node_param in node.params:
if node_param.name == cp.name:
logger.debug(
"[AST] param {} line {} in function_params, start new rule for function {}".format(param_name, node.lineno, node.name))

if vul_function is None or node.name != vul_function:
print vul_function
logger.info(
"[Deep AST] Now vulnerability function from function {}() param {}".format(node.name,
cp.name))
Expand All @@ -648,13 +675,18 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
logger.info(
"[Deep AST] Recursive problems may exist in the code, exit the new rules generated..."
)
# 无法解决递归,直接退出
is_co = -1
return is_co, cp, 0

elif isinstance(node, php.Class):
is_co, cp, expr_lineno = class_back(param, node, lineno, vul_function=vul_function)
return is_co, cp, expr_lineno

elif isinstance(node, php.If):
logger.debug(
"[AST] param {} line {} in if/else, start ast in if/else".format(param_name, node.lineno))

if isinstance(node.node, php.Block): # if里可能是代码块,也可能就一句语句
if_nodes = node.node.nodes
if_node_lineno = node.node.lineno
Expand Down Expand Up @@ -720,16 +752,21 @@ def parameters_back(param, nodes, function_params=None, lineno=0,
for_nodes = node.node.nodes
for_node_lineno = node.node.lineno

logger.debug(
"[AST] param {} line {} in for, start ast in for".format(param_name, for_node_lineno))

is_co, cp, expr_lineno = parameters_back(param, for_nodes, function_params, for_node_lineno,
function_flag=1)
function_flag=1, vul_function=vul_function)

if is_co == 3 or int(lineno) == node.lineno: # 当is_co为True时找到可控,停止递归
is_co, cp, expr_lineno = parameters_back(param, nodes[:-1], function_params, lineno,
function_flag=1) # 找到可控的输入时,停止递归
function_flag=1, vul_function=vul_function) # 找到可控的输入时,停止递归

elif len(nodes) == 0 and function_params is not None: # 当敏感函数在函数中时,function_params不为空,这时应进入自定义敏感函数逻辑
for function_param in function_params:
if function_param == param:
logger.debug(
"[AST] param {} in function_params, start new rule".format(param_name))
is_co = 2
cp = function_param

Expand All @@ -752,7 +789,7 @@ def deep_parameters_back(param, back_node, function_params, count, file_path, li
is_co, cp, expr_lineno = parameters_back(param, back_node, function_params, lineno, vul_function=vul_function)

if count > 20:
logger.warning("[Deep AST] depth too big to auto exit...")
logger.warning("[Deep AST] depth too big, auto exit...")
return is_co, cp, expr_lineno

if is_co == 3:
Expand Down Expand Up @@ -849,6 +886,7 @@ def anlysis_params(param, code_content, file_path, lineno, vul_function=None, re
param = php.Variable(param)
parser = make_parser()
all_nodes = parser.parse(code_content, debug=False, lexer=lexer.clone(), tracking=with_line)
logger.debug("[AST] AST to find param {}".format(param))

vul_nodes = []
for node in all_nodes:
Expand Down

0 comments on commit 8bab33c

Please sign in to comment.