Insomni’hack 2023 – The Exploit Quest

Insomni’hack 2023 – The Exploit Quest

 

My colleague, Felix Bonningue, and I tackled this challenge, as it seemed quite intriguing.

 

In this challenge, we had to infiltrate a company called Global Corp, represented by a wooden box near the admin table. The objective was to steal their most valuable asset: the Treasure!!

 

Some information about the company was leaked on a forum located at this URL: https://skillroad.insomnihack.ch/

 

Upon accessing the website, we discovered three leaks within the /leaks endpoint. Unfortunately, the first link was unavailable (Sold out). However, by analyzing the indices of the other two links (1338 & 1339), we managed to retrieve the index of the first one (1337) and download the data.

 

The data downloaded consisted of two-channel traces captured with a Saleae logic.

 

The traces looked like this:

 

 

Upon further analysis of the protocol, we noticed it was grouped by four edges, distributed between channel 0 and channel 1.

 

 

We then proceeded to examine the wooden box, where we identified a keypad likely used to open the trap beneath it.

 

 

We hypothesized that channel 0 corresponded to a bit equal to 0 and channel 1 to a bit equal to 1.

 

With this assumption, we identified the following number from the traces:

 

 

This led us to the following code that successfully opened the first trap:

 

`*215968#`

 

Inside the trap, we took an RFID badge and scanned the QR code to gain access to the “QUEST-GUEST” network.

 

Upon accessing the network, we didn’t observe anything significant. So, we decided to return to the underground forum and explore the other leaks.

 

In the second leak page, we identified an input field for a voucher code. Analyzing the web page content, we found a JavaScript function that encrypts plaintext. The expected ciphertext was also provided as a comment.

 

 

Feeling a bit lazy, we asked ChatGPT to give us a function that returns the plaintext from the ciphertext. As the French saying goes, “Il faut vivre avec son temps.”

 

 

Executing it against the given ciphertext returned the following string:

 

 

Entering this voucher code into the input field granted us access to the URL containing a download link for the keypad datasheet. Since we had already reverse-engineered the signal, this information wasn’t useful to us.

 

Next, we attempted to obtain the latest leaks. There was no JavaScript function on the page. However, when we input some invalid data, the following SQL error appeared:

 

 

We opted to run the SQLMap script to exploit it, since we were feeling lazy once again 🙂

 

This allowed us to dump the “voucher” database and obtain the required voucher code.

 

 

Using the code on the latest leak page granted us access to a Swagger JSON definition, which also provided the URL of an API used to manage physical access: http://10.0.100.50.

 

 

We reconnected to the “QUEST-GUEST” network to interact with the HR manager API.

 

According to the Swagger API, we could register a new badge and associate it with an employee without any authentication. Doing so, some data was written to the badge within sector 1.

 

 

“`
76616C69646974793D30312F30312F32
3034323B61646D696E3D302020202020
20202020202020202020202020202020
“`

 

Upon decoding, we obtained the following data:

 

`validity=01/01/2042;admin=0`

 

We then changed `admin=0` to `admin=1` and rewrote the sector using the MIFARE Classic Tool Android application.

 

This enabled us to open the second trap of the wooden box.

 

Inside this trap, another QR code provided access to the “Quest-Internal” WiFi network, along with a message warning that strict network filtering was in place between this network and the server network.

 

The only known server was within the `10.0.100.0/24` range (HR API management server – 10.0.100.50).

 

We then proceeded to scan the entire range of this server network, focusing on the top 100 TCP ports. Our attention was drawn to an SMB server located at `10.0.100.52:445`. By utilizing `smbclient -L \\10.0.100.52`, we identified a share named Confidential. This share permitted anonymous access and contained a Keepass file.

 

 

Unfortunately, JohnTheRipper and Hashcat do not support Keepass version 4. However, a quick online search led us to discover this script: https://github.com/r3nt0n/keepass4brute

 

The script, as is, didn’t work because it always returned the first line of our wordlist as a valid password. It appeared that the `keepassxc-cli` no longer had the `open` argument. To start brute-forcing the Keepass file with the `rockyou.txt` wordlist, we modified the script as follows:

 

#!/bin/bash

# https://github.com/r3nt0n/keepass4brute
# Name: keepass4brute.sh
# Author: r3nt0n
# Version: 1.0 (25/11/2022)
# Modified by ghecko (25/03/2023)


version="1.1"
/bin/echo -e "\nkeepass4brute $version by r3nt0n - modified by ghecko"
/bin/echo -e "https://github.com/r3nt0n/keepass4brute\n"

if [ $# -ne 2 ]
then
  /bin/echo "Usage $0 <kdbx-file> <wordlist>"
  exit 2
fi

dep="keepassxc-cli"
command -v $dep >/dev/null 2>&1 || { /bin/echo >&2 "Error: $dep not installed.  Aborting."; exit 1; }

n_total=$( wc -l < $2 )
n_tested=0

IFS=''
while read -r line; do
  n_tested=$((n_tested + 1))
  /bin/echo -ne "[+] Words tested: $n_tested/$n_total ($line)                                          \r"

  if ! /bin/echo $line | keepassxc-cli ls $1 2>&1 | /bin/grep -q "Error"
  then
    /bin/echo -ne "\n"
    /bin/echo "[*] Password found: $line"; exit 0;
  fi
done < $2

/bin/echo -ne "\n"
/bin/echo "[!] Wordlist exhausted, any match found"; exit 3;

 

In just a few seconds, the script revealed that “rockyou” is the password needed to access the Keepass database.

 

Upon opening the file, we discovered two entries: one containing GPS coordinates and another for the Flag. Excitingly, we secured the first blood for this challenge :D!

 

The GPS coordinates led us to a location near the Insomni’hack conference venue. Here, we encountered four safes, each equipped with a numerical keypad. Attempting to use the same code as in the initial step of the wooden box proved unsuccessful (nice joke 😅). As we persevered in our search, with a bit of anxiety knowing that another team was also on the hunt, we eventually uncovered the true treasure hidden behind a dumpster on the lower level (one for each members of the team):

 

 

This challenge proved to be both intriguing and entertaining :D!

 

Jordan Ovrè – Ghecko