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.

142 lines
5.6 KiB

2 months ago
# 工具基类
'''
工具基类----工具子类约束
1.一个工具子类一个py文件
2.工具类文件名必须为[指令名]+Tool.py
3.未完成的工具子类以__开头
4.
'''
import abc
import subprocess
import argparse
import sys
from myutils.ReturnParams import ReturnParams
class ToolBase(abc.ABC):
def __init__(self):
#self.res_type = 0 #补充一个结果类型 0-初始状态,1-有安全问题,
#由于工具类会被多个线程调用,不能有全局变量
pass
def create_extparams(self):
ext_params = ReturnParams()
ext_params["is_user"] = False # 是否要提交用户确认 -- 默认False
ext_params["is_vulnerability"] = False # 是否是脆弱点
return ext_params
def parse_sublist3r_command(self,command):
parser = argparse.ArgumentParser(add_help=False) #创建命令行参数解析器对象‌
parser.add_argument("-o ", "--output", type=str) #添加需要解析的参数规则‌
parser.add_argument("-oN ", "--Noutput", type=str) #nmap
parser.add_argument("-output ", "--nikto", type=str) #nikto
args, _ = parser.parse_known_args(command.split()[1:])
return args
def read_output_file(self,filename):
"""
读取 -o 参数指定的文件内容
"""
try:
with open(filename, "r") as f:
return f.read()
except FileNotFoundError:
print(f"错误: 文件 {filename} 不存在")
except PermissionError:
print(f"错误: 无权限读取文件 {filename}")
return ""
def execute_instruction(self, instruction_old):
'''
执行指令验证合法性 -> 执行 -> 分析结果
*****如果指令要做验证只做白名单所有逻辑不是全放开就是白名单*****
:param instruction_old:
:return:
bool:true-正常返回给大模型处理下一步false-结果不返回给大模型,2--需要人工确认的指令
str:执行的指令
str:执行指令的结果-解析过滤后的结果--也是提交给LLM的结果
str:执行指令的结果-原结果
object:补充参数-封装一个对象 0-不知是否攻击成功1-明确存在漏洞2-明确不存在漏洞
'''
ext_params = self.create_extparams()
# 第一步:验证指令合法性
instruction,timeout = self.validate_instruction(instruction_old)
if not instruction:
ext_params.is_user= True
return False,instruction_old,"该指令暂不执行!由用户确认是否要兼容支持","",ext_params #未
#过滤修改后的指令是否需要判重?同样指令再执行结果一致?待定---#?
# 第二步:执行指令
#print(f"执行指令:{instruction}")
output = ""
stdout = ""
stderr = ""
try:
if timeout == 0:
result = subprocess.run(instruction, shell=True, capture_output=True, text=True)
elif timeout >0:
result = subprocess.run(instruction, shell=True, capture_output=True, text=True, timeout=timeout)
else:
print("timeout参数错误")
#output = result.stdout if result.stdout else result.stderr
#-o 的命令需要处理
parsed_arg = self.parse_sublist3r_command(instruction)
if parsed_arg.output:
output = self.read_output_file(parsed_arg.output)
elif parsed_arg.Noutput:
output = self.read_output_file(parsed_arg.Noutput)
elif parsed_arg.nikto:
output = self.read_output_file(parsed_arg.nikto)
else:
stderr = result.stderr
stdout = result.stdout
except subprocess.TimeoutExpired as e:
stdout = e.stdout if e.stdout is not None else ""
stderr = e.stderr if e.stderr is not None else ""
ext_params.is_user = True #对于超时的也需要人工进行确认,是否是预期的超时
except Exception as e:
ext_params.is_user = True
return False,instruction,f"执行失败:{str(e)}","",ext_params #执行失败,提交给人工确认指令的正确性
# 第三步:分析执行结果
output = stdout
if stderr:
output += stderr
analysis = self.analyze_result(output,instruction,stderr,stdout)
#指令和结果入数据库
#?
if not analysis: #analysis为“” 不提交LLM
ext_params.is_user = True
return False,instruction,analysis,output,ext_params
return True,instruction, analysis,output,ext_params
@abc.abstractmethod
def validate_instruction(self, instruction:str):
"""指令合法性分析
:return:
str非空代表合法函数内会涉及修改指令为空代表非法已取消指令
int表示超时时间0不设置超时时间正值具体的超时时间设置单位秒
"""
pass
@abc.abstractmethod
def analyze_result(self, result:str,instruction:str,stderr:str,stdout:str) -> str:
"""分析执行结果"""
pass
def read_output_file_test(filename):
"""
读取 -o 参数指定的文件内容
"""
try:
with open(filename, "r") as f:
return f.read()
except FileNotFoundError:
print(f"错误: 文件 {filename} 不存在")
except PermissionError:
print(f"错误: 无权限读取文件 {filename}")
return ""
if __name__ =="__main__":
pass