Resolute HTB
Resolute HTB Box Overview Resolute is a medium Windows Active Directory box that starts with a null SMB session and ends in a nice little DnsAdmins abuse chain. The whole path really comes down to two things people leave lying around: a password in an account description, and an old PowerShell transcript nobody bothered to clean up. Domain is megabank.local, hostname RESOLUTE. Attack Summary Null session access to SMB let me pull the full user list and account descriptions through rpcclient, and one of those descriptions had a password sitting right in it. That password didn't work directly, but with no account lockout policy in place, spraying it across every enumerated user landed a hit on melanie, who also had WinRM rights, so that was initial access. From there, poking around the filesystem turned up C:\PSTranscripts, a leftover PowerShell transcript logging directory, and one of the saved transcripts had a plaintext password for ryan sitting in it. Ryan turned out to be a member of DnsAdmins, which on older Windows Server builds can be abused to load an arbitrary DLL into the DNS service and get code execution as SYSTEM. That's exactly how root was obtained. Enumeration Nmap Scanning Started with a full service and script scan against the target. Nmap Scan Analysis Between the port list and the smb-os-discovery script output, this is clearly a domain controller. | Port | Service | |------|---------| | 53 | DNS | | 88 | Kerberos | | 135 | MSRPC | | 139 | NetBIOS-SSN | | 389 | LDAP | | 445 | SMB | | 464 | kpasswd5 | | 593 | RPC over HTTP | | 636 | LDAPS | | 3268 | LDAP (Global Catalog) | | 3269 | LDAPS (Global Catalog) | | 5985 | WinRM | Domain is megabank.local, computer name RESOLUTE. Adding it to /etc/hosts before going any further. SMB Null Session Enumeration Checked SMB with NetExec first, just to see what it reports about the box. Null Auth:True is the interesting bit here. It means SMB will accept an anonymous, unauthenticated session, which on a DC often gives you enough RPC access to enumerate domain users without any credentials at all. Empty username, -N to skip the password prompt, and it drops straight into an authenticated-as-nobody rpcclient session. From here I can start pulling domain information. Enumerating Domain Users That's a full list of domain users straight from an anonymous session. Next thing worth checking is whether any of them have descriptions set, since admins have a bad habit of leaving notes (or worse, passwords) in that field. That's a hit. The marko account's description field reads: Whoever provisioned that account left the initial password in plaintext right there in the description. Worth trying, though there's a reasonable chance it's already been changed since account creation. Testing the Leaked Password No luck directly against marko. Doesn't mean the password is dead though, it's entirely possible someone else reused it, or marko changed his own password but left the domain-wide default in place for other accounts. Worth spraying it across every user we found. Password Spraying Before spraying, it's worth checking the domain's lockout policy so I don't accidentally lock out a bunch of accounts. Account Lockout Threshold: None is the key line. There's no lockout policy at all, so spraying one password across every user in the domain carries no risk of locking anyone out. Green light to spray. First, saved the raw enumdomusers output into a file: Then stripped it down to just usernames with a quick regex: And sprayed Welcome123! against the full list: Got a hit on melanie. That confirms the password was in fact reused across more than one account, even if marko himself had changed his. Initial Access Before doing anything else, checked whether melanie also has WinRM access, since that's a much cleaner way in than SMB. (Pwn3d!) confirms melanie is in a group with remote shell rights. Logging in directly with evil-winrm: User Flag Privilege Escalation Enumerating from Melanie Started by listing out the other accounts on the box and checking what melanie actually has access to. Nothing in melanie's own groups or privileges stands out as a fast track to admin. Time to look around the filesystem instead. Checked the root of C:\ including hidden and system items. PSTranscripts - Leftover Transcription Logs C:\PSTranscripts isn't something you see by default. It only exists if PowerShell transcription logging was enabled at some point, which records every command and every bit of output from a PowerShell session into a text file. That's exactly the kind of thing that ends up with credentials in it if someone ever typed a password into a session while it was logging. Reading the transcript: There it is. Someone mapped a network drive using net use with the credentials typed directly on the command line, ryan and the password Serv3r4Admin4cc123!, and PowerShell transcription logged the whole thing in plaintext. Pivoting to Ryan Ryan's desktop had a note left behind: Worth translating that clearly: any changes made to the system get automatically rolled back within about a minute, except changes made to the Administrator account itself. That's a real constraint for whatever privesc path comes next, so it's worth keeping in mind while planning the attack. DnsAdmins Group Membership MEGABANK\DnsAdmins immediately stands out. Checked what that group is actually meant to control: DnsAdmins group description Source: Microsoft - Understand Security Groups (DnsAdmins) DnsAdmins is meant to manage the DNS service, but on Windows Server versions before the relevant patch, membership in this group lets you configure the DNS server service to load an arbitrary DLL on startup. Since the DNS service on a domain controller runs as SYSTEM, that turns into code execution as SYSTEM the moment the service restarts. Referenced this write-up on the exact technique: ired.team - From DnsAdmins to SYSTEM to Domain Compromise DnsAdmins to SYSTEM First, generated a reverse shell payload as a DLL: Since dnscmd needs a UNC path to the DLL, hosted it over SMB from the same directory using Impacket's smbserver.py, which stands up a share without needing to write anything to disk on the target: Set up a listener to catch the callback: With that ready, configured the DNS service to load the payload as a plugin DLL: This writes the path into the DNS server's ServerLevelPluginDll registry value. The DLL only actually loads the next time the DNS service starts, so the service needs to be restarted for it to take effect. Given the note about changes reverting within a minute, this needed to happen quickly, stop the service and immediately start it back up: The moment the DNS service started back up, it loaded the malicious DLL and the reverse shell fired. nt authority\system, since the DNS service runs as SYSTEM, that's exactly the privilege level the DLL executed under. Root Flag Final Thoughts Resolute is a good one for practicing the basics that actually matter in AD assessments. Null sessions on SMB still show up more than you'd think, and this box is a perfect example of why they're dangerous, an anonymous rpcclient session gave up the entire user list and, even better, a password sitting right in an account description. The password reuse part was satisfying. It didn't work on the account it was set for, but with no lockout policy in place, spraying it across everyone was basically free and it landed on melanie. From there the PSTranscripts folder was the real find. Somebody had transcription logging turned on at some point and never cleaned it up, and it had ryan's password sitting in plaintext from an old net use command. The DnsAdmins escalation was the highlight for me. I hadn't messed with that abuse before, and figuring out the timing with the change freeze note added a bit of pressure, stop and start the service fast enough before it got reverted. Getting SYSTEM back the second the DNS service restarted felt great. Overall a solid box for practicing enumeration discipline, not skipping the SMB null session check, and understanding how something like DnsAdmins can quietly turn into full domain compromise. See you in the next writeup. Until then, keep enumerating and stay curious. By Madhav ```