|
|
@ -57,39 +57,45 @@ class LLMManager: |
|
|
|
def build_initial_prompt(self,target,know_info="无",node=None): |
|
|
|
if not node: |
|
|
|
return None |
|
|
|
'''暂时未添加到提示词 |
|
|
|
**核心要求**: |
|
|
|
- 每次新增节点时,必须在同一响应中为该节点提供测试指令。 |
|
|
|
- 分批新增节点,每次响应中新增节点不超过3个,确保指令完整。 |
|
|
|
''' |
|
|
|
#根节点初始化message |
|
|
|
node.messages = [{"role": "system", |
|
|
|
"content":''' |
|
|
|
你是一位渗透测试专家,由你动态控制整个渗透测试过程,根据当前测试状态和返回结果,决定下一步的测试指令,推动测试阶段前进,直至完成渗透测试。本地程序会根据你的指令进行执行,然后将执行结果返回给你。 |
|
|
|
总体要求说明: |
|
|
|
1.以目标系统所在IP为根节点,随着信息收集和渗透测试的推进,每个渗透测试点(如端口、服务、漏洞点)作为子节点,形成树型结构(测试树); |
|
|
|
2.测试树整体数据由本地程序存储,你只需要关注当前节点的渗透测试推进,节点状态(未完成、已完成)的更新,和是否有子节点新增; |
|
|
|
3.你需要返回两类指令:节点指令和测试指令,以空行间隔; |
|
|
|
--示例: |
|
|
|
{\"action\":\"add_node\", \"parent\": \"192.168.1.100\", \"node\": \"21端口\", \"status\": \"未完成\"} |
|
|
|
你是一位渗透测试专家,负责动态控制整个渗透测试过程,根据当前测试状态和返回结果,决定下一步测试指令,推动测试前进,直至完成渗透测试。本地程序会执行你的指令进并返回结果。 |
|
|
|
**总体要求** |
|
|
|
1.以目标系统IP为根节点,每个渗透测试点(如端口、服务、漏洞点)作为子节点,形成树型结构(测试树); |
|
|
|
2.测试树整体数据由本地程序存储,你只需要关注当前节点的测试推进、状态更新(未完成/已完成)及子节点新增; |
|
|
|
3.返回两类指令:节点指令和测试指令,以空行间隔,不要包含注释和说明; |
|
|
|
4.若无节点修改或新增,节点指令可以为空,但测试指令必须对应已有节点。 |
|
|
|
**决策流程** |
|
|
|
1. 若当前节点是IP且未进行端口扫描,则执行端口扫描; |
|
|
|
2. 若端口扫描发现开放端口,为每个端口新增节点并提供测试指令; |
|
|
|
3. 若当前节点是端口且未进行服务扫描,则执行服务扫描; |
|
|
|
4. 若服务扫描发现服务版本或漏洞,则新增漏洞测试节点并提供测试指令; |
|
|
|
5. 若漏洞利用成功,则根据结果决定是否新增子节点并提供测试指令; |
|
|
|
6. 若节点测试无新信息,则更新状态为“已完成”。 |
|
|
|
**节点指令格式** |
|
|
|
- 新增节点:{\"action\":\"add_node\", \"parent\": \"80端口\", \"node\": \"http://192.168.1.100/index.php?id=1\", \"status\": \"未完成\"}; |
|
|
|
- 更新节点未发现漏洞:{\"action\": \"update_status\", \"node\": \"21端口\", \"status\": \"已完成\"}; |
|
|
|
- 更新节点发现漏洞:{\"action\": \"update_status\", \"node\": \"21端口\", \"status\": \"已完成\",\"vulnerability\": {\"name\":\"ftp匿名登录\",\"risk\":\"高\"}}; |
|
|
|
**测试指令格式** |
|
|
|
- shell指令:```bash-[节点路径](.*?)```包裹,需要避免用户交互; |
|
|
|
- python指令:```python-[节点路径](.*?)```包裹,主函数名为dynamic_fun,需包含错误处理,执行结束后必须返回一个tuple (status, output),其中status为'success'或'failure',output为补充输出信息; |
|
|
|
- [节点路径]为从根节点到目标节点的完整层级描述。 |
|
|
|
**响应示例** |
|
|
|
{\"action\":\"add_node\", \"parent\": \"192.168.1.100\", \"node\": \"3306端口\", \"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-[对应节点的路径](.*?)```包裹,[对应节点的路径]为从根节点到目标节点的完整层级描述; |
|
|
|
3.若提供的是shell指令,需要避免用户再次交互; |
|
|
|
4.若提供的是python代码,主函数名为dynamic_fun,需包含错误处理,执行结束后必须返回一个tuple (status, output),其中status为'success'或'failure',output为补充输出信息; |
|
|
|
示例: |
|
|
|
```python-[目标系统->192.168.1.100->3306端口] |
|
|
|
mysql -u root -p 192.168.1.100 |
|
|
|
``` |
|
|
|
|
|
|
|
{\"action\":\"add_node\", \"parent\": \"192.168.1.100\", \"node\": \"22端口\", \"status\": \"未完成\"} |
|
|
|
|
|
|
|
```python-[目标系统->192.168.1.100->22端口] |
|
|
|
def dynamic_fun(): |
|
|
|
try: |
|
|
|
result = "扫描完成" |
|
|
@ -97,8 +103,6 @@ def dynamic_fun(): |
|
|
|
except Exception as e: |
|
|
|
return ("failure", str(e)) |
|
|
|
``` |
|
|
|
限制条件: |
|
|
|
1.仅在发现高危漏洞或关键测试路径时新增节点 |
|
|
|
'''}] # 一个messages |
|
|
|
user_Prompt = f''' |
|
|
|
当前分支路径:目标系统->{target} |
|
|
@ -211,11 +215,23 @@ def dynamic_fun(): |
|
|
|
commands.append(shell_blocks[shell_index]) |
|
|
|
shell_index +=1 |
|
|
|
else: |
|
|
|
#其他的认为是节点操作指令 |
|
|
|
node_cmds.append(part) |
|
|
|
|
|
|
|
#其他的认为是节点操作指令--指令格式还存在不确定性,需要正则匹配 |
|
|
|
pattern = re.compile(r'\{.*?\}', re.DOTALL) |
|
|
|
# 遍历所有匹配到的 JSON 结构 |
|
|
|
for match in pattern.findall(part): |
|
|
|
try: |
|
|
|
node_cmds.append(json.loads(match)) # 解析 JSON 并添加到列表 |
|
|
|
except json.JSONDecodeError as e:#解析不了的不入队列 |
|
|
|
print(f"JSON 解析错误: {e}") |
|
|
|
return node_cmds,commands |
|
|
|
|
|
|
|
def llm_error_feedback(self,response_text,node): |
|
|
|
'''验证llm返回--错误反馈机制--兼容LLM的不稳定性,需要持续补充 |
|
|
|
1.验证节点是否都有测试指令返回 |
|
|
|
''' |
|
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
def test_llm(self): |
|
|
|
with open("../test", "r", encoding="utf-8") as f: |
|
|
|
messages = json.load(f) |
|
|
@ -227,7 +243,15 @@ def dynamic_fun(): |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
LM = LLMManager(1) |
|
|
|
LM.test_llm() |
|
|
|
|
|
|
|
# LM = LLMManager(1) |
|
|
|
# LM.test_llm() |
|
|
|
tlist1 = [] |
|
|
|
tlist2 = [] |
|
|
|
tlist2.append(1) |
|
|
|
if not tlist1: |
|
|
|
print("list1空") |
|
|
|
if not tlist2: |
|
|
|
print("list2空") |
|
|
|
if tlist2: |
|
|
|
print("list2不为空") |
|
|
|
|
|
|
|