Hack The Box.EU - Jail -Buffer Overflow Walkthrough


Today I am going to demonstrate how I got root on this box. This one was hard and long since it involves buffer overflows, Socket re-use due to IP tables preventing a reverse shell, NFS exploitation, SE Linux bypass to get to regular user and cryptography. If you are a sadist, you are going to enjoy it, Otherwise Let's get started.

OS:Linux

IP:10.10.10.34

Enumeration:

We begin with a nmap port scan against all ports (-p-) which shows numerous ports are open.



We visit port 80 using the IP in our browser and find a ascii art of prison cell on the webpage. The html source code (ctrl+u) shows the same picture and is a dead end.



We then bruteforce the directories using dirbuster and find a /jailuser/dev directory which when we browse to gives us a jail.c program file, a binary file and a bash script with instructions on how to compile it.





The Jail.c files seems to point to a buffer overflow as it has a admin username, password, port number and the strcpy function in it. This is the same port we saw in our nmap results with instructions (OK Ready. Send USER command.). Opening the bash compile script we find compiling instructions :gcc -o jail jail.c -m32 -z execstack. Running a file command against jail shows it's a 32 bit ELF binary. When doing buffer overflows, try to mimic the target as close as you can. In this case we will do the testing and compiling on a 32 bit local box.





Next we give the binary executable permissions and connect to it using telnet to see what services are running. The debug functionality seenin the code below will directly print out the address of the vulnerable buffer mitigating issues encountered when performing a remote buffer overflow.



Next we run jail program. We can run it using gdb (gdb -q jail) which disables aslr or you can start the binary and attach the pid ( ./ jail, ps -ef | grep jail then gdb --pid==0000) The jail binary works by forking itself to each server call, and in the event of a crash the primary process will still run. We run the commands below in gdb to make the process debug in forked process.

gdb -q jail

(gdb) set follow-fork-mode child

(gdb) set detach-on-fork off

(gdb) run



After running the binary, we then connect to the program on our local host/local IP and input some junk /A’s to see if we can crash the program and overwrite EIP.



EIP is overwritten with A’s/x41x41x41.. hence we can control it. We then restart the program to find the correct offset.


Next we find EIP in the PASS parameter using pattern_create (/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 50) in metasploit or in gdb (pattern_create 50, gdb -q jail, run).





Restart the program and send the junk to it and we get a segmentation fault.





The segmentation fault shows that EIP was overwritten with 0x62413961. Next we find the offset using metasploit's pattern_create ( /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x62413961) or gdb (pattern_offset 0x62413961 50). The Exact match at offset 28.



With the off-set of 28, we can proceed to create a python exploit using available data to get a shell. We know that we need a 32 bit shellcode to load into memory. We also need to determine where to jump to. Before proceeding we need to check if dep or aslr is enabled and we find that the binary has PIE enabled this is not good as the binary runs at a random addresses every time it starts. We also use 32 bit shellcode from http://shell-storm.org/shellcode/files/shellcode-833.php OR Socket Reuse x32 shellcode (has a smaller code) from https://www.exploit-db.com/exploits/34060/. I used the later. You can google Shellcode Linux reverse tcp x32 x64 to locate them or use msfvemon shellcode.



On our shellcode we add 10 nopsleds for a cushion and use available data and use LITTLE ENDIAN format for the offset.



We compile and run the python exploit and get a shell as user "nobody".



Privilege Escalation:

Since the machine is running NFS share, we will attempt to exploit it. Let's first look for the shared folders of the target machine (showmount -e 10.10.10.34) which we can mount locally. After mounting the shared folder we find that only root user has read, write and execute permissions but a user with GID 1000 can write and execute files inside the folder. If you don't have it, install rpcbind nfs tool to be able to mount the folder to our local machine (apt-get install rpcbind nfs-common)



Opening the /etc/passwd and etc/group folder shows a user ftpgroup owns the nfsshare. We give this user permissions(1000), mount the nfs share, and on our shell test to see if we can see a test file we create on the so as to be able to upload our shell to exploit this weak permission vulnerability.

root@kali:~# showmount -a 10.10.10.34

root@kali:~# mkdir -p /mnt/jail/{opt,nfsshare}

root@kali:~# ls /mnt/jail

root@kali:~# mount -t nfs -o vers=3 10.10.10.34:/opt /mnt/jail/opt

root@kali:~# mount -t nfs -o vers=3 10.10.10.34:/var/nfsshare /mnt/jail/nfsshare



We cd to /mnt/jail and running ls -la and change ftpgroup permissions to 1000 in;

/etc/group

/etc/passwd

And our test file is successfully created.



We give the file -test 4755 permissions and running ls -la againt it on our shell shows it has the set uid permission set





We create a simple c program and give setuid and setgid permissions to 1000, share it using nfsshare,compile and execute it but it doesn't work.



Since we had a selinux restriction, we download a bypass script from https://seclists.org/oss-sec/2016/q3/606 and compile and run it on our shell and get the frank euid.





I also used a c code to set euid to 1000, compiled it with gcc and set permissions to 4755 and executed it on the shell and got user frank and then spawned a tty shell.
v

Privilege Escalation:

using sudo -l command, we see user frank and adm can run commands with no password. We run the admin command and get admin access and use python -c 'import pty; pty.spawn("/bin/sh")' to break out of vim.

(frank) NOPASSWD: /opt/logreader/logreader.sh
(
adm) NOPASSWD: /usr/bin/rvim /var/www/html/jailuser/dev/jail.c


Comments