diff --git a/cobra/cast.py b/cobra/cast.py index 9e8566de..af3fbf88 100644 --- a/cobra/cast.py +++ b/cobra/cast.py @@ -49,7 +49,8 @@ def __init__(self, rule, target_directory, file_path, line, code, files=None, ru if self.file_path[-len(language):].lower() == language: self.language = self.languages[language] - os.chdir(self.target_directory) + if os.path.isdir(self.target_directory): + os.chdir(self.target_directory) # Parse rule self.regex = { 'java': { diff --git a/cobra/cli.py b/cobra/cli.py index b67999e9..ec789bc8 100644 --- a/cobra/cli.py +++ b/cobra/cli.py @@ -71,7 +71,7 @@ def start(target, formatter, output, special_rules, a_sid=None, language=None, s # target directory try: target_directory = pa.target_directory(target_mode) - logger.info('[CLI] Target directory: {d}'.format(d=target_directory)) + logger.info('[CLI] Target : {d}'.format(d=target_directory)) # static analyse files info files, file_count, time_consume = Directory(target_directory, black_path_list).collect_files() diff --git a/cobra/file.py b/cobra/file.py index ebc3ca1f..ad1285e2 100644 --- a/cobra/file.py +++ b/cobra/file.py @@ -17,6 +17,7 @@ import time import codecs import zipfile +import traceback from .log import logger from .pretreatment import ast_object from .const import ext_dict @@ -103,6 +104,13 @@ def file_grep(file_path, rule_reg): return result +def check_filepath(target, filepath): + if os.path.isfile(target): + return target + else: + return os.path.join(target, filepath) + + class FileParseAll: def __init__(self, filelist, target, language=None): self.filelist = filelist @@ -118,13 +126,15 @@ def grep(self, reg): result = [] for ffile in self.t_filelist: - file = codecs.open(os.path.join(self.target, ffile), "r", encoding='utf-8', errors='ignore') + filepath = check_filepath(self.target, ffile) + + file = codecs.open(filepath, "r", encoding='utf-8', errors='ignore') line_number = 0 for line in file: line_number += 1 # print line, line_number if re.search(reg, line, re.I): - result.append((self.target + ffile, str(line_number), line)) + result.append((filepath, str(line_number), line)) return result @@ -138,7 +148,9 @@ def multi_grep(self, reg): line_number = 0 for ffile in self.t_filelist: - file = codecs.open(os.path.join(self.target, ffile), "r", encoding='utf-8', errors='ignore') + filepath = check_filepath(self.target, ffile) + + file = codecs.open(filepath, "r", encoding='utf-8', errors='ignore') content = file.read() file.close() @@ -147,7 +159,7 @@ def multi_grep(self, reg): if r_con_obj: start_pos = r_con_obj.regs[0][0] line_number = len(content[:start_pos].split('\n')) - result.append((self.target + ffile, str(line_number), r_con_obj.group(0))) + result.append((filepath, str(line_number), r_con_obj.group(0))) return result @@ -178,7 +190,9 @@ def multi_grep_name(self, matchs, unmatchs, matchs_name, black_list): result = [] for ffile in self.t_filelist: - file = codecs.open(os.path.join(self.target, ffile), "r", encoding='utf-8', errors='ignore') + filepath = check_filepath(self.target, ffile) + + file = codecs.open(filepath, "r", encoding='utf-8', errors='ignore') content = file.read() file.close() @@ -240,7 +254,7 @@ def multi_grep_name(self, matchs, unmatchs, matchs_name, black_list): if re_flag: # 例如CVI2100中,没有match,只要不含unmatch即为漏洞的,没有行数 if matchs_tmp == []: - result.append(tuple([self.target+ffile, str(line_number), 'name:<'+n+'>'])) + result.append(tuple([filepath, str(line_number), 'name:<'+n+'>'])) logger.debug('[DEBUG] [MATCH_REGEX_RETURN_REGEX] success match:{0} in line {1}'.format(n, str(line_number))) continue @@ -250,7 +264,7 @@ def multi_grep_name(self, matchs, unmatchs, matchs_name, black_list): if result_list_tmp is not None and result_list_tmp != []: for result_tmp in result_list_tmp: - result.append(tuple([self.target+ffile, str(line_number), 'name:<'+result_tmp[0]+'>, point:<'+result_tmp[1]+'>'])) + result.append(tuple([filepath, str(line_number), 'name:<'+result_tmp[0]+'>, point:<'+result_tmp[1]+'>'])) logger.debug('[DEBUG] [MATCH_REGEX_RETURN_REGEX] success match:{0} in line {1}'.format(n, str(line_number))) else: re_flag = False @@ -268,7 +282,7 @@ def special_crx_keyword_match(self, keyword, match, unmatch): result = [] for ffile in self.t_filelist: - ffile_path = os.path.join(self.target, ffile) + ffile_path = check_filepath(self.target, ffile) ffile_object = ast_object.get_object(ffile_path) @@ -401,6 +415,7 @@ def files(self, absolute_path, level=1): if os.path.isfile(directory): self.file_info(directory, filename) except OSError as e: + logger.error("[PICKUP] {}".format(traceback.format_exc())) logger.critical('[PICKUP] {msg}'.format(msg=e)) exit() diff --git a/cobra/pretreatment.py b/cobra/pretreatment.py index a6c25fc4..c8cdfb84 100644 --- a/cobra/pretreatment.py +++ b/cobra/pretreatment.py @@ -70,6 +70,12 @@ def init_pre(self, target_directory, files): self.target_directory = os.path.normpath(self.target_directory) + def get_path(self, filepath): + if os.path.isfile(self.target_directory): + return self.target_directory + else: + return os.path.join(self.target_directory, filepath) + def pre_ast(self, lan=None): if lan is not None: @@ -86,7 +92,7 @@ def pre_ast(self, lan=None): for filepath in fileext[1]['list']: all_nodes = [] - filepath = os.path.join(self.target_directory, filepath) + filepath = self.get_path(filepath) self.pre_result[filepath] = {} self.pre_result[filepath]['language'] = 'php' self.pre_result[filepath]['ast_nodes'] = [] @@ -126,7 +132,7 @@ def pre_ast(self, lan=None): # 针对chrome 拓展的预处理 # 需要提取其中的js和html? for filepath in fileext[1]['list']: - filepath = os.path.join(self.target_directory, filepath) + filepath = self.get_path(filepath) self.pre_result[filepath] = {} self.pre_result[filepath]['language'] = 'chromeext' @@ -162,7 +168,7 @@ def pre_ast(self, lan=None): # 针对javascript的预处理 # 需要对js做语义分析 for filepath in fileext[1]['list']: - filepath = os.path.join(self.target_directory, filepath) + filepath = self.get_path(filepath) self.pre_result[filepath] = {} self.pre_result[filepath]['language'] = 'javascript' self.pre_result[filepath]['ast_nodes'] = [] @@ -187,7 +193,7 @@ def pre_ast(self, lan=None): except: logger.warning('[AST] something error, {}'.format(traceback.format_exc())) - def get_nodes(self, filepath, vul_lineno=None, lan = None): + def get_nodes(self, filepath, vul_lineno=None, lan=None): filepath = os.path.normpath(filepath) if filepath in self.pre_result: diff --git a/cobra/utils.py b/cobra/utils.py index b43beb50..bfa70bb1 100644 --- a/cobra/utils.py +++ b/cobra/utils.py @@ -159,6 +159,7 @@ def target_directory(self, target_mode): target_directory = self.target elif target_mode == TARGET_MODE_FILE: target_directory = self.target + return target_directory else: logger.critical('[PARSE-ARGS] exception target mode ({mode})'.format(mode=target_mode)) exit() diff --git a/docs/changelog.md b/docs/changelog.md index 541728fb..79d663e1 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -134,4 +134,8 @@ - Cobra-W 1.8.0 - 历时接近3个月,完成了关于javascript的语义分析 - 测试并通过了jsprime其中大多测试样例 - - 重构Cobra底层关于多语言区分的支持,现在可以自由的添加新语言分析 \ No newline at end of file + - 重构Cobra底层关于多语言区分的支持,现在可以自由的添加新语言分析 +- 2019-10-08 + - Cobra-W 1.8.1 + - 修复了不知道什么版本导致的无法针对单个文件的扫描bug + - 现在支持-t后跟随单个文件进行分析 \ No newline at end of file