You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
6.0 KiB

2 months ago
from tools.ToolBase import ToolBase
import re
import json
import subprocess
import os
import shutil
from pathlib import Path
2 months ago
class SearchsploitTool(ToolBase):
def validate_instruction(self, instruction):
1 week ago
# 获取当前路径
cur_path = Path(__file__).resolve().parent
payload_dir = cur_path / "../payload"
2 months ago
#指令过滤
timeout = 0
1 week ago
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
2 months ago
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')
2 months ago
"""去除 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 = "下载失败"
1 week ago
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 "该渗透脚本已经复制到当前路径。"
2 months ago
else:
return "暂时不利用该渗透脚本。"