|
|
@ -55,34 +55,39 @@ class LLMManager: |
|
|
|
|
|
|
|
# 构建初始提示 初始化messages |
|
|
|
def build_initial_prompt(self,target,know_info="无",node=None): |
|
|
|
# self.messages = [{"role": "system", |
|
|
|
# "content": "你是一位渗透测试专家,需要动态控制整个渗透测试过程,包括信息收集、漏洞扫描、漏洞利用等阶段,最终生成渗透测试报告。由你规划执行的指令,我会根据你的指令执行并提交结果,你再对结果进行分析,规划并生成下一步指令,直到完成渗透测试,生成测试报告。" |
|
|
|
# "生成的指令需满足如下约束:" |
|
|
|
# "1.只返回具体的shell指令或Python代码,不要包含注释和说明;" |
|
|
|
# "2.shell指令以```bash(.*?)```包裹,python代码以```python(.*?)```包裹;" |
|
|
|
# "3.若提供的是shell指令,需要避免用户再次交互;" |
|
|
|
# "4.若提供的是python代码,主函数名为dynamic_fun,需要包含错误处理,执行结束返回两个str(status-'success'或'failure'和output-补充输出信息);" |
|
|
|
# "5.如果认为渗透测试已完成,请生成生成报告的python代码,并返回'complete'和报告文件路径"}] # 一个messages |
|
|
|
#return f"现在开始对目标{target}进行渗透测试,已知信息{know_info},请提供下一步执行的指令。" |
|
|
|
if not node: |
|
|
|
return None |
|
|
|
#根节点初始化message |
|
|
|
node.messages = [{"role": "system", |
|
|
|
"content":''' |
|
|
|
你是一位渗透测试专家,由你动态控制整个渗透测试过程,根据当前测试状态和返回结果,决定下一步的测试指令,推动测试阶段前进,直至完成渗透测试。本地程序会根据你的指令进行执行,然后将执行结果返回给你。 |
|
|
|
整体过程说明: |
|
|
|
1.以目标系统所在IP为根节点,每个渗透测试点(如端口、服务、漏洞点)作为子节点,形成树型结构(测试树); |
|
|
|
总体要求说明: |
|
|
|
1.以目标系统所在IP为根节点,随着信息收集和渗透测试的推进,每个渗透测试点(如端口、服务、漏洞点)作为子节点,形成树型结构(测试树); |
|
|
|
2.测试树整体数据由本地程序存储,你只需要关注当前节点的渗透测试推进,节点状态(未完成、已完成)的更新,和是否有子节点新增; |
|
|
|
3.新增子节点时,同一父节点下的子节点名称不能相同,并提供对该节点的测试指令; |
|
|
|
3.新增节点示例:{\"action\":\"add_node\", \"parent\": \"80端口\", \"node\": \"http://192.168.1.100/index.php?id=1\", \"status\": \"未完成\"}; |
|
|
|
4.完成节点测试且发现漏洞示例:{\"action\": \"update_status\", \"node\": \"21端口\", \"status\": \"已完成\",\"vulnerability\": \"ftp匿名登录\"}; |
|
|
|
5.发现漏洞后,可根据漏洞类型决定是否新增子节点继续测试,如:{\"action\": \"add_node\", \"parent\": \"21端口\", \"node\": \"ftp配置检查\", \"status\": \"未完成\"}; |
|
|
|
6.当本地程序确认所有节点状态均为“已完成”时,生成测试报告。 |
|
|
|
3.你需要返回两类指令:节点指令和测试指令,以空行间隔; |
|
|
|
--示例: |
|
|
|
{\"action\":\"add_node\", \"parent\": \"192.168.1.100\", \"node\": \"21端口\", \"status\": \"未完成\"} |
|
|
|
|
|
|
|
```bash-[目标系统->192.168.1.100->3306端口] |
|
|
|
mysql -u root -p 192.168.1.100``` |
|
|
|
若无节点修改或新增,节点指令可以为空,但测试指令必须对应已有节点; |
|
|
|
决策流程: |
|
|
|
1. 如果当前节点是IP地址,且未进行端口扫描,则执行端口扫描。 |
|
|
|
2. 如果端口扫描发现开放端口,则为每个开放端口新增一个测试节点。 |
|
|
|
3. 如果当前节点是端口,且未进行服务扫描,则执行服务扫描。 |
|
|
|
4. 如果服务扫描发现服务版本或漏洞,则新增对应的漏洞测试节点。 |
|
|
|
5. 如果当前节点是漏洞测试,且漏洞利用成功,则根据利用结果决定是否新增子节点进一步测试。 |
|
|
|
6. 如果当前节点测试未发现新信息,则更新节点状态为“已完成”,并继续测试其他未完成节点。 |
|
|
|
生成的节点指令需要满足如下约束: |
|
|
|
1.新增节点指令示例:{\"action\":\"add_node\", \"parent\": \"80端口\", \"node\": \"http://192.168.1.100/index.php?id=1\", \"status\": \"未完成\"}; |
|
|
|
2.新增子节点时,同一请求返回的子节点名(node)不能相同,且必须同时提供对该节点的测试指令; |
|
|
|
3.若认为该节点已完成测试,修改该节点为“已完成”状态,完成节点测试且发现漏洞示例:{\"action\": \"update_status\", \"node\": \"21端口\", \"status\": \"已完成\",\"vulnerability\": \"ftp匿名登录\"}; |
|
|
|
4.发现漏洞后,可根据漏洞类型决定是否新增子节点继续测试,如:{\"action\": \"add_node\", \"parent\": \"21端口\", \"node\": \"ftp配置检查\", \"status\": \"未完成\"}; |
|
|
|
生成的渗透测试指令需满足如下约束: |
|
|
|
1.只返回具体的shell指令或Python代码,不要包含注释和说明; |
|
|
|
2.shell指令以```bash-[对应节点的路径](.*?)```包裹,python代码以```python-[对应节点的路径](.*?)```包裹; |
|
|
|
2.shell指令以```bash-[对应节点的路径](.*?)```包裹,python代码以```python-[对应节点的路径](.*?)```包裹,[对应节点的路径]为从根节点到目标节点的完整层级描述; |
|
|
|
3.若提供的是shell指令,需要避免用户再次交互; |
|
|
|
4.若提供的是python代码,主函数名为dynamic_fun,需包含错误处理,执行结束后返回一个tuple (status, output),其中status为'success'或'failure',output为补充输出信息; |
|
|
|
4.若提供的是python代码,主函数名为dynamic_fun,需包含错误处理,执行结束后必须返回一个tuple (status, output),其中status为'success'或'failure',output为补充输出信息; |
|
|
|
示例: |
|
|
|
```python-[目标系统->192.168.1.100->3306端口] |
|
|
|
def dynamic_fun(): |
|
|
@ -92,7 +97,8 @@ class LLMManager: |
|
|
|
except Exception as e: |
|
|
|
return ("failure", str(e)) |
|
|
|
``` |
|
|
|
5.如果认为渗透测试已完成,请生成生成报告的python代码,并返回'complete'和报告文件路径。 |
|
|
|
限制条件: |
|
|
|
1.仅在发现高危漏洞或关键测试路径时新增节点 |
|
|
|
'''}] # 一个messages |
|
|
|
user_Prompt = f''' |
|
|
|
当前分支路径:目标系统->{target} |
|
|
@ -100,7 +106,7 @@ class LLMManager: |
|
|
|
- 节点名称:{target} |
|
|
|
- 节点状态:未完成 |
|
|
|
- 漏洞类型:未发现 |
|
|
|
上一步结果:已知信息-{know_info} |
|
|
|
上一步结果:{know_info} |
|
|
|
任务:生成下一步渗透测试指令或结束该节点的渗透测试(修改节点状态为:已完成)。 |
|
|
|
''' |
|
|
|
return user_Prompt |
|
|
@ -126,7 +132,7 @@ class LLMManager: |
|
|
|
post_time = get_local_timestr() |
|
|
|
response = self.client.chat.completions.create( |
|
|
|
model=self.model, |
|
|
|
messages = self.messages |
|
|
|
messages = node.messages |
|
|
|
) |
|
|
|
|
|
|
|
#LLM返回结果处理 |
|
|
@ -156,17 +162,14 @@ class LLMManager: |
|
|
|
self.logger.error(f"{node.name}-llm入库失败!") |
|
|
|
|
|
|
|
#需要对指令进行提取 |
|
|
|
node_list = self.fetch_instruction(content,node) |
|
|
|
node_cmds,commands = self.fetch_instruction(content,node) |
|
|
|
|
|
|
|
#********测试时使用---输出和记录LLM返回指令的message |
|
|
|
print(f"Messages:{self.messages}") |
|
|
|
with open("../test", "w", encoding="utf-8") as f: #输出到文件 |
|
|
|
json.dump(self.messages,f,ensure_ascii=False) |
|
|
|
|
|
|
|
return node_list |
|
|
|
return node_cmds,commands |
|
|
|
|
|
|
|
def fetch_instruction(self,response_text,node): |
|
|
|
''' |
|
|
|
*****该函数很重要,需要一定的容错能力,解析LLM返回内容***** |
|
|
|
处理边界:只格式化分析LLM返回内容,指令和节点操作等交其他模块。 |
|
|
|
节点控制指令 |
|
|
|
渗透测试指令 |
|
|
|
提取命令列表,包括: |
|
|
@ -211,7 +214,7 @@ class LLMManager: |
|
|
|
#其他的认为是节点操作指令 |
|
|
|
node_cmds.append(part) |
|
|
|
|
|
|
|
return node_cmds,commands #?存在一个问题:这样分list返回,执行顺序会丢失 |
|
|
|
return node_cmds,commands |
|
|
|
|
|
|
|
def test_llm(self): |
|
|
|
with open("../test", "r", encoding="utf-8") as f: |
|
|
|