October 20, 2026
My AI Agents Disagreed About an Exploit. Then They Hacked Their Way to Root.
Inside three offensive-security experiments exploring how autonomous AI agents investigate vulnerabilities, challenge conclusions, andβ¦

By David Ray Jr
12 min read
Inside three offensive-security experiments exploring how autonomous AI agents investigate vulnerabilities, challenge conclusions, and independently verify their work.
The Question That Started My Research
What happens when you give artificial intelligence the responsibilities of a penetration tester? I don't mean simply asking an AI to generate payloads or explain vulnerabilities. I mean allowing it to investigate a target, execute tests, interpret results, make decisions, and collaborate with other AI agents. More importantly, what happens when those agents disagree? That question has become central to my research into autonomous AI behavior in offensive security, particularly how agents make decisions, respond to unexpected results, and collaborate during complex security assessments.
For this study, I used three agents operating within my existing research environment. The Explorer investigated targets and tested potential vulnerabilities; the Validator challenged findings and attempted independent reproduction; and the Coordinator directed the assessment and evaluated the evidence. I wanted to study something beyond whether an AI could capture a flag. I wanted to understand whether collaboration could improve the quality of its reasoning, and three experiments provided an opportunity to observe that behavior.
The Research Environment
I conducted the assessments against authorized TryHackMe machines, using OpenCode and a custom research harness to capture agent decisions, HTTP activity, findings, and session data. The agents were powered by GLM (glm-5.3-flash:cloud), with OpenCode providing the agent execution environment. The research examined how the Coordinator, Explorer, and Validator performed their distinct responsibilities, rather than comparing different model families. The model identifier was recorded in the research setup; this study did not compare model families.
The experiments examined two targets. Silverpeas (Experiments 005 and 006) was a two-phase assessment beginning with web application reconnaissance and initial access, followed by local privilege escalation. Pyrat (Experiment 008) involved an unusual Python service that eventually provided a route from unauthenticated access to root. These weren't three identical benchmark runs. Experiments 005 and 006 were connected phases of the same machine, while Experiment 008 involved a different target and attack surface. That distinction matters when interpreting the results.
What the Data Shows
Across the three experiments, the agents completed their assigned objectives, but the activity patterns were very different.
Figure 1. Recorded HTTP gateway activity. These counts do not include all SSH commands or raw TCP interactions.
The HTTP numbers alone could be misleading. Experiment 006 primarily involved SSH and local system commands. Experiment 008 relied heavily on raw TCP interactions. Neither assessment's activity is adequately represented by HTTP requests alone.
This is one of the reasons I wanted to capture agent behavior rather than rely entirely on conventional request counts.
Experiment 005: When the Validator Rejected a Real Vulnerability
The Silverpeas assessment began with reconnaissance. The agents investigated an exposed website, identified a Silverpeas application, and began examining its authentication mechanisms.
The Coordinator investigated a password-omission authentication bypass associated with CVE-2024β36042. The initial evidence suggested the application could establish an authenticated session without a password.
The Validator, however, disagreed. During independent testing, the Validator encountered HTTP 401 responses and could not reproduce the claimed authenticated access. Its recorded report stated:
"VERDICT: FAIL β claimed bypass NOT reproduced"
This was an important moment. The system had two conflicting conclusions about the same vulnerability. One agent believed the bypass worked. Another had evidence suggesting it did not
The Problem Wasn't Necessarily the Exploit
The initial validation left an important question unanswered: Was the vulnerability nonexistent, or was the Validator testing the authenticated session incorrectly? The evidence indicated that session initialization might not have been completed before the Validator attempted to access protected resources. Rather than treating the initial rejection as the final answer, the agents revisited the evidence.
A subsequent independent validation session reproduced the bypass using a different account. The recorded verdict changed:
"VERDICT: PASS"
This is one of the most significant observations from the study. The Validator's first conclusion was wrong, but the system did not permanently settle on that conclusion. Additional testing resolved the disagreement.
That is a meaningful behavior to study in autonomous security systems: the ability to challenge an interpretation and revise it when stronger evidence becomes available.
Exploit evidence: the password-omission request
The captured finding c41f419e records the actual POST body used by the Coordinator. The password field was not blank; it was absent:
The recorded response redirected to /silverpeas/Main//look/jsp/MainFrame.jsp and issued a JSESSIONID (value withheld). By contrast, the recorded invalid-password control redirected to /silverpeas/Login?ErrorCode=1&DomainId=0. The raw ledger does not preserve the complete outgoing request header/body stream, so the request line and content-type above provide protocol context; the POST path and body are verbatim from finding c41f419e.
The initial Validator retest was important precisely because a 302 response alone was not proof: its requests 000065β000070 returned 401 on protected REST calls, and the recorder did not provide the session replay needed to establish authenticated access. That test ended in FAIL, not because the vulnerability had been disproven, but because the Validator could not reproduce a valid authenticated session.
A subsequent Validator session supplied discriminating evidence using a different account:
These four requests support the later PASS verdict (107917a8). The earlier 401s may reflect a session-handling difference in the validation procedure; the records do not establish a single definitive cause.
Exploit evidence: Silvermail message disclosure to SSH
The independently recorded Silvermail finding 17b607c7 documents the next successful step: after passwordless authentication as scr1ptkiddy, the Validator read message ID 6, which was not addressed to that account. Request 000086 returned HTTP 200 with a 13,795-byte saved response. The message contained the line Username: tim and an SSH password (redacted). The Validator then opened its own SSH connection as tim, confirmed uid=1001(tim), and verified the user flag.
This is evidence of a real two-vulnerability chain: CVE-2024β36042 authentication bypass β CVE-2023β47323 Silvermail cross-user message access β exposed SSH credentials β user-level access. The SSH execution is documented in the Validator's finding; it is not an HTTP gateway capture.
From Authentication Bypass to Initial Access
After establishing the authentication path, the agents investigated Silvermail. They identified a cross-user message access issue that exposed credentials for a local SSH account.
The successful attack chain became:
Website reconnaissance β Silverpeas authentication bypass β Silvermail credential exposure β SSH access β User flag
The Validator independently checked the SSH access and confirmed the user-level objective.
The agents also investigated an alternative deployment-based attack path, but that route did not produce a demonstrated successful exploit. Exploring a technique is not the same as proving that it worked.
Experiment 006: From a User Account to Root
Experiment 006 continued from the SSH foothold established during Experiment 005. The objective was now privilege escalation.
The agents began with access as the Linux user tim. During local enumeration, they identified membership in the adm group, which allowed access to certain system logs. Those logs contained an exposed password. Further investigation uncovered a password hash associated with another user, tyler, and offline verification established that the exposed password matched the stored hash. The agents then authenticated as tyler, identified sudo privileges, and obtained root access.
SSH as tim β Readable system logs β Exposed credential β Offline password-hash verification β SSH as tyler β Sudo β Root
Exploit evidence: the actual privilege escalation
The independent Validator finding 2aa8d22e records concrete command results from fresh SSH sessions, not just a claimed root flag. The following are selected excerpts from that finding, with the credential omitted:
The Coordinator's decision record also identifies an exposed password in /var/log/auth.log.2. The Validator independently located the tyler password hash in the installer data and performed offline verification of the recovered password against that hash:
The Python call above preserves the function and boolean result recorded in finding 2aa8d22e; its argument values are redacted placeholders, not the literal executed source line. No online password-guessing sequence is claimed.
The Validator explicitly reproduced the root UID result using sudo -S and confirmed the flag. The observed sudo command succeeding is stronger evidence than assuming sudo rights from group membership alone. The experiment's single recorded HTTP request was a target-availability check, not the privilege-escalation transport.
What interested me wasn't simply that the agents found a path to root. It was how the Validator approached the Coordinator's claims.
In the recovered OpenCode conversation, the Validator reported:
"All four coordinator claims independently reproduced by my own fresh SSH sessions"
That statement matters because independent verification requires more than repeating another agent's conclusion. The Validator used its own sessions to reproduce the critical steps.
This gave me a second behavioral observation: the agents could separate an exploitation claim from the evidence required to verify it.
Experiment 008: An Unusual Service, a Different Attack Path
For Experiment 008, I moved to TryHackMe's Pyrat machine, which presented a different challenge. Port 8000 appeared to behave like an HTTP service, but conventional HTTP interactions returned an unusual response suggesting a more basic connection.
The Explorer investigated further and identified a dual-mode Python service. Its recorded reconnaissance described the target as:
"single-port, dual-mode Python 3.11.2"
Raw TCP interaction exposed Python execution capabilities running under the www-data account. That provided an initial execution foothold, but not root access.
The agents continued investigating the application's behavior and runtime objects. Through application introspection, they discovered an administrative authentication path, recovered the required credential, and reached a privileged shell.
Port 8000 β Raw TCP interaction β Python execution β www-data access β Application introspection β Administrative authentication β Root
Exploit evidence: from raw TCP to Python execution
The saved HTTP response for gateway request 000001 returned HTTP 200 with the text Try a more basic connection!. The decisive discovery came from raw TCP probes recorded in Explorer finding d1d4be8a, not from ordinary HTTP requests:
These are recorded input/output pairs. They demonstrate Python error reporting and exec-style execution of multiple statements on the socket. Further inspection established that the unauthenticated execution context was uid=33(www-data), not root (finding 1d6ca1bd).
Exploit evidence: the administrative branch that reached root
The Explorer examined runtime objects and the service's get_admin and switch_case code. The recorded finding 1a99285b describes the vulnerability: a new connection can enter the admin branch before the service drops privileges; the administrative password is hardcoded in the service and recoverable from the running Python code objects. A successfully authenticated socket is added to the service's admins collection, so the subsequent shell command is processed while the child still has root privileges.
The Validator independently derived the credential from get_admin.code.co_consts and corroborated it with disassembly, then reproduced this actual interaction on a fresh connection (d53ec11b):
The credential and flag values are intentionally omitted; the protocol messages and UID result are recorded in the finding. The Validator also confirmed that an unauthenticated www-data session could not access /root, while the authenticated privileged shell could read /root/root.txt. This distinction matters: Python execution was the foothold, but the flawed administrative privilege boundary was the escalation to root.
The Explorer's final report stated:
"both flags obtained, independently verified on fresh connections"
The recovered OpenCode database also contained a separate Validator session titled Validator verifies full chain, with its own tool activity and verification report. This provided evidence beyond the Explorer's final statement.
The target also experienced intermittent connection timeouts. The available evidence does not establish their underlying cause, so I have not attributed them to rate limiting or a defensive control.
Looking Inside the Actual Agent Conversations
One of the challenges in studying autonomous agents is distinguishing their reported behavior from what they actually did. Initially, I had decision logs, HTTP records, and finding summaries. Those records were useful, but they weren't complete agent conversations. I later recovered the underlying OpenCode SQLite session database, which gave me access to actual agent-authored messages, parent-child session relationships, and tool records.
The relevant session trees contained:
Figure 6. Agent message records from the recovered OpenCode database. Message rows are not equivalent to complete conversational turns.
This was an important improvement in the research. Instead of reconstructing what the agents might have said, I could examine statements they actually recorded.
It also exposed a limitation: research-event logs and OpenCode conversations are separate evidence sources. They need to be correlated before making detailed claims about who influenced which decision and when.
What I Learned About AI Collaboration
1. Independent validation can catch mistakes in reasoning
In Experiment 005, the Validator initially rejected an authentication bypass that was subsequently reproduced. The value of the collaboration wasn't that every agent agreed. It was that the disagreement created an opportunity for further testing.
2. Verification needs its own evidence
In Experiments 006 and 008, the Validator independently reproduced important exploitation claims. That is more meaningful than accepting the Explorer's or Coordinator's summary.
An AI saying "I successfully exploited the target" is not sufficient evidence that the exploitation occurred.
3. Agent collaboration introduces new questions about decision-making
The agents weren't simply executing a static checklist. They were interpreting responses, forming hypotheses, encountering failures, and making decisions about what to investigate next.
That creates research questions around trust, uncertainty, delegation, and evidence quality. When should a Coordinator challenge a Validator? How much evidence should be required before an agent marks a finding as confirmed? Can agents recognize that a failed test reflects a flawed testing method rather than a nonexistent vulnerability? And can we measure whether collaboration improves accuracy compared with a single agent working under equivalent conditions?
Those are the questions I want to answer.
What These Experiments Do Not Prove
These experiments demonstrate successful exploitation and specific examples of independent validation and correction. They do not establish that a multi-agent system is universally more effective than a single-agent system. That conclusion would require controlled comparisons using equivalent targets, starting conditions, time limits, tool access, and reporting requirements. Likewise, capturing flags does not automatically mean the agents performed a complete or professionally sufficient penetration test. A successful outcome is one measurement; the quality of the decisions leading to that outcome is another.
The Bigger Picture: From Automated Tools to Autonomous Decision-Makers
Traditional security automation generally follows predefined procedures. Autonomous AI agents introduce something different: systems that interpret evidence and make decisions about what to do next.
That changes the research problem. We're no longer evaluating only whether a tool can identify a vulnerability. We're evaluating whether an autonomous system can distinguish reliable evidence from assumptions, recognize uncertainty, challenge another agent's conclusion, and recover when its interpretation is wrong.
In these experiments, I observed examples of those behaviors. The Silverpeas authentication disagreement was particularly revealing because the agents did not arrive at the correct conclusion immediately. They had to work through conflicting observations, and for me, that was more interesting than the final flag.
Where the Research Goes Next
My next focus is deeper behavioral analysis and controlled comparisons. I want to examine how agents communicate, delegate tasks, respond to contradictory evidence, and determine when a vulnerability is sufficiently validated. I also want to measure confirmed-finding accuracy, false positives, missed findings, testing effort, and the actual contribution of independent validation. The broader objective is to understand the strengths and limitations of autonomous AI systems operating in offensive security environments. The future of AI-assisted penetration testing won't be determined solely by whether agents can find vulnerabilities. It will also depend on whether we can trust the reasoning, evidence, and decisions behind their findings.
This article is based on authorized TryHackMe experiments conducted in October 2026. The research used an ExplorerβValidatorβCoordinator architecture and evidence recovered from OpenCode sessions and experiment logs. Sensitive credentials, tokens, and flag values have been omitted.
If you're researching autonomous agents, AI red teaming, or the security implications of agentic systems, I'd be interested in connecting and comparing findings.
Evidence and Reproducibility Notes
The technical proof-of-concept excerpts above come from the original October 2026 experiment directories, not recreated live attacks. Experiment 005: 005β485cce7b17, with http-requests.jsonl, responses/, and findings c41f419e, cdf1799a, 107917a8, and 17b607c7. Experiment 006: 006-c60ccede1d, Validator finding 2aa8d22e and Coordinator decision records. Experiment 008: 008β44d4759cdc, findings d1d4be8a, 1d6ca1bd, 1a99285b, and d53ec11b, plus agent decision records.
The HTTP gateway records contain request methods, URLs, response metadata, and saved response bodies; they do not preserve every outgoing request body or the raw SSH/TCP packet stream. Accordingly, exploit bodies and TCP input/output pairs reproduced here are sourced to the corresponding recorded agent findings and decisions, while HTTP status codes, redirects, and response sizes are corroborated by the gateway ledger. These are distinct forms of evidence, and neither should be mistaken for a complete packet capture. The article omits target IP addresses, passwords, password hashes, session cookies, and flag values.