from tools.ToolBase import ToolBase import re import json import subprocess import os import shutil from pathlib import Path class SearchsploitTool(ToolBase): def validate_instruction(self, instruction): # 获取当前路径 cur_path = Path(__file__).resolve().parent payload_dir = cur_path / "../payload" #指令过滤 timeout = 0 parts = instruction.split("&&") if len(parts) ==2: searchsploit_cmd = parts[0].strip() python_cmd = parts[1].strip() # 提取 -m 后面的文件名 tokens = searchsploit_cmd.split() if "-m" in tokens: m_index = tokens.index("-m") if m_index + 1 < len(tokens): filename = tokens[m_index + 1] else: return instruction,timeout # -m 后面没有东西,直接返回 else: return instruction,timeout # 没有-m选项,直接返回 if self.find_file_in_directory(filename,payload_dir): return python_cmd,timeout else: timeout = 60*2 return instruction,timeout else: if "-m " in instruction: # 下载利用代码 timeout = 60*2 return instruction,timeout def analyze_result(self, result,instruction,stderr,stdout): #获取当前路径 cur_path = Path(__file__).resolve().parent payload_dir = cur_path / "../payload" #if instruction(result,bytes): if type(result) is bytes: result = result.decode('utf-8',errors='ignore') """去除 ANSI 颜色码""" ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') clean_result = ansi_escape.sub('', result) # 指令结果分析 if "-m " in instruction:#下载利用代码 if "Copied to:" in clean_result or "cp: overwrite " in clean_result: result = "下载完成" else: result = "下载失败" elif instruction.startswith("python"): #针对searchsploit -m 42745.py && python3 42745.py -u http://192.168.204.137 这样的情况searchsploit会先执行掉,剩余python代码 return result else: #目前只遇到两种searchsploit命令格式: lines = clean_result.split("\n") exploits = [] for line in lines: match = re.match(r"(.+?)\s+\|\s+(\S+)", line) if match: title = match.group(1).strip() path = match.group(2).strip() if "Path" not in path: #下载渗透脚本--进一步推进 ext_str = self.do_ext(path,payload_dir) exploits.append({"title": title, "path": path,"补充信息":ext_str}) if len(exploits) > 0: result = json.dumps(exploits,ensure_ascii=False) #输出原始的中文字符 else: result = "没有检索到漏洞利用脚本" return result def find_file_in_directory(self,target_file, dir_path, case_sensitive=True, recursive=False): """ 在指定目录中查找文件是否存在 :param target_file: 要查找的目标文件名(含扩展名) :param search_dir: 要搜索的目录路径 :param case_sensitive: 是否区分大小写(默认True) :param recursive: 是否递归搜索子目录(默认False) :return: (bool, str) 是否存在,完整路径(如果找到) """ try: #dir_path = Path(search_dir) # 验证目录是否存在 if not dir_path.is_dir(): return False, None # 根据是否递归选择遍历方式 iterator = dir_path.rglob('*') if recursive else dir_path.iterdir() for entry in iterator: # 跳过目录只处理文件 if entry.is_file(): # 根据是否区分大小写进行比较 if case_sensitive: match = entry.name == target_file else: match = entry.name.lower() == target_file.lower() if match: return True, str(entry.resolve()) return False, None except Exception as e: print(f"查找出错: {str(e)}") return False, None def do_download(self,filepath,dirpath): ''' 下载渗透脚本 :return: ''' filename = filepath.split("/")[-1] if ".py" in filename: #对应payload库中是否存在该脚本 bfind,_ = self.find_file_in_directory(filename,dirpath) if bfind: return True else:#下载 instruction = f"searchsploit -m {filepath}" try: subprocess.run(instruction, shell=True, check=True,timeout=60) #print("命令执行成功,文件下载完成。") except subprocess.CalledProcessError as e: #超时暂不处理--后续补充 #print(f"命令执行失败: {e}") return False if not os.path.exists(filename): return False # 移动文件到目标目录 try: shutil.move(filename, os.path.join(dirpath, filename)) #print(f"文件已成功移动到 {dirpath}") return True except Exception as e: #print(f"移动文件失败: {e}") return False else: #暂时只利用python脚本 return False def do_ext(self,filepath,payload_dir) -> str: bdownload = self.do_download(filepath,payload_dir) if bdownload: return "该渗透脚本已经复制到当前路径。" else: return "暂时不利用该渗透脚本。"