Pentesting Common Gateway Interface (CGI) applications
A Common Gateway Interface (CGI) is used to help a web server render dynamic pages and create a customized response for the user making a request via a web application. CGI applications are primarily used to access other applications running on a web server. CGI is essentially middleware between web servers, external databases, and information sources. CGI scripts and programs are kept in the /CGI-bin
directory on a web server and can be written in C, C++, Java, PERL, etc. CGI scripts run in the security context of the web server.
CGI scripts/applications are typically used for a few reasons:
- If the webserver must dynamically interact with the user
- When a user submits data to the web server by filling out a form. The CGI application would process the data and return the result to the user via the webserver
The CGI program starts a new process for each HTTP request which can take up a lot of server memory.
Attacking Tomcat CGI
The CGI Servlet is a vital component of Apache Tomcat that enables web servers to communicate with external applications beyond the Tomcat JVM. These external applications are typically CGI scripts written in languages like Perl, Python, or Bash. The CGI Servlet receives requests from web browsers and forwards them to CGI scripts for processing.
In a nugshell, a CGI Servlet is a program that runs on a web server, such as Apache2, to support the execution of external applications that conform to the CGI specification.
CVE-2019-0232
is a critical security issue that could result in remote code execution.
- This vulnerability affects Windows systems that have the
enableCmdLineArguments
feature enabled. - Versions
9.0.0.M1
to9.0.17
,8.5.0
to8.5.39
, and7.0.0
to7.0.93
of Tomcat are affected. - The
enableCmdLineArguments
setting for Apache Tomcat's CGI Servlet controls whether command line arguments are created from the query string. If set to true, the CGI Servlet parses the query string and passes it to the CGI script as arguments.
Example:
Suppose you have a CGI script that allows users to search for books in a bookstore's catalogue. The script has two possible actions: "search by title" and "search by author."
For instance, an attacker can append dir
to a valid command using &
as a separator to execute dir
on a Windows system.
Finding an injection endpoint:
Since the operating system is Windows, we aim to fuzz for batch scripts. Although fuzzing for scripts with a .cmd extension is unsuccessful, we successfully uncover the welcome.bat file by fuzzing for files with a .bat extension.
If we find an endpoint named "lala" we can trigger the RCE by browsing to:
We can do a whoami like this:
Attacking Sherlock
The Shellshock vulnerability (CVE-2014-6271) allows an attacker to exploit old versions of Bash that save environment variables incorrectly.
1. Find endpoints:
Let's say we find access.cgi.
2. Next, we can cURL the script and notice that nothing is output to us, so perhaps it is a defunct script but still worth exploring further.
3. Explaining the payload:
When the above variable is assigned, Bash will interpret the y='() { :;};'
portion as a function definition for a variable y
. The function does nothing but returns an exit code 0
, but when it is imported, it will execute the command echo vulnerable-shellshock
if the version of Bash is vulnerable.
Reading /etc/passwd
We can test the user-agent header and see that the contents of the /etc/passwd
file are returned to us, thus confirming the vulnerability via the user-agent field.
The payload:
Exploitation to Reverse Shell Access
Set a listener:
Get the reverse shell with curl:
Get the reverse shell with Burpsuite:
Last update: 2025-02-09 Created: February 9, 2025 20:01:37Shellshock is a legacy vulnerability that is now nearly a decade old. But just because of its age, that does not mean we will not run into it occasionally. If you come across any web applications using CGI scripts during your assessments (especially IoT devices), it is definitely worth digging.