Write up of bSidesLisbon CTF

David Magalhães
AdamantSec
Published in
10 min readNov 23, 2018

--

This year we (David Magalhães, Luís Catarino, Paulo Pinto and Pedro Rodrigues) will attend probably the best security conference in Portugal again. Last year we decided to participate in the online CTF and got qualified for the onsite CTF, although we didn’t finish all the challenges.

This year we got our mind focused and decided that we wanted to compete again and be one of 10 teams to be on the onsite CTF. This is our write up about how we solved the 5 challenges.

Recon 100, 9

Which username did nine ball brute force?

Searching for “nine ball brute force” didn’t produce any results, but if you add the word “hacker” we got this link. Nine ball is the name of a female hacker in the Ocean 8 movie, so we checked some trailers / scenes available on YouTube until we found the right video.

Flag: p_damanian

Trivia 200, Message Request

Peter’s Suppression Subtractive Hybridization is asking for a password.

The name Suppression Subtractive Hybridization took us quite a bit of time on some research about it. We always ended up learning more on CTFs, even on subjects that we don’t need to.

We even tried searching about Peter Parker and SpiderMan, but nothing except this video.

We got several passwords from SSH books and users over the StackOverflow, even watched some random videos on YouTube about a guy explaining how to connect to a server via SSH to check if there was any plaintext password there.

After a while we decided that Suppression Subtractive Hybridization meant 100% SSH, and the title of the challenge was “Message Request” so we needed to look into the RFC. After some attempts, like SSH_MSG_USERAUTH_SUCCESS, we finally submitted the right one, SSH2_MSG_USERAUTH_SUCCESS found on this link. We were missing the 2!

Forensics 300, USB

At the bSidesLisbon 2017 an attendee lost an usb drive. We found it but we couldn’t do much with it.

It was provided a VHD file, so a Virtual Hard Disk image. The first thing you think of was to mount this in Linux. We could check more information using the fdisk command.

$ fdisk -l USB.vhd 
Disk USB.vhd: 50 MiB, 52429312 bytes, 102401 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xb35e8e15
Device Boot Start End Sectors Size Id Type
USB.vhd1 128 96383 96256 47M 7 HPFS/NTFS/exFAT

This type of filesystem (HPFS/NTFS/exFAT) is uncommon, and using other software to open the image, like for example using Windows Disk Manager to load the VHD file, we quickly found out that this was encrypted with Bitlocker. If you open this file with GParted this is the information displayed.

Although we had previously researched about Bitlocker, we only got to the solution after the hint was given.

The news about some SSDs that can cripple the encryption on Bitlocker took us some time into reading that research, but in the end we were confident that only a password could open this.

To open Bitlocker drives in Linux/OSX you have dislocker. This tool allows you to open the volume with a password or a recovery key. One of our attempts was to run a password list. SecList is a very famous repository that has a lot of common password list, and we ran some.

To allow us to automate this process we found this page. There exists a script that allows you to run a dictionary list against a Bitlocker image in order to find the right password. We needed to modify the script to use the right offset 65536 (128*512 bytes).

...
hack()
{
echo_item $*
if dislocker-fuse -O 65536 -V $VOLUME — user-password=$* $MOUNT 1> ...

After this we tried some password lists but without success. By default this script when you reach the end of the list, it will run again appending the first password to the next, and so on. We disabled that functionality to run more quickly, but without success.

We started to check what other CTF had been done with Bitlocker. One of them hidden the flag inside the volume name. There are certain informations that aren’t encrypted, and some of the software that handles Bitlocker doesn’t show them. You can find out more here.

One of them was the computer name when the drive was encrypted. In this case was DESKTOP-QLELILI. The next information was the disk name, bSidesLisbon. And the last piece of information is when the drive was encrypted, 15/11/2018.

After some attempts, we still got nothing.

We tried to run every command we could find, like manage-bde.

C:\Windows\system32>manage-bde -protectors -get f:
Encriptação de Unidade BitLocker: Ferramenta de Configuração versão 6.1.7601
Copyright © Microsoft Corporation. Todos os direitos reservados.
Volume F: [Etiqueta Desconhecida]
Todos os Protectores de Chave
Palavra-passe:
ID: {74C697FD-D567–4ACB-979D-D1C529FA1DDC}
Palavra-passe Numérica:
ID: {276469DC-ABD2–4000–9567–50413FE6EDD7}

But without success.

It’s over 9000

The first reaction was, does the password has some kind of reference to Dragon Ball ? Do we need to type dragon ball characters names ?

A couple of hours after this hint, I’ve decided to search on SecList for list over 9000! And then I found 10-million-password-list-top-10000.txt.

I decided to leave the software running the list and head to the gym. After I got back I even tried to search more about Bitlocker when I realized that I leaved this thing running, and then it stopped right on the password.

It took some time to reach the end, I think it was around 1 second for each password, so less than 3 hours to reach to the right password, PolniyPizdec0211.

To create a dislocker-file we needed to run:

dislocker -V USB.vhd -O 65536 -v -uPolniyPizdec0211 /mnt/bsides1

Then mount the partition:

mount ro,loop /mnt/bsides1/dislocker-file /mnt/bitlocker

And then we could access the content inside. There was a text file with the flag, flag{Any_System_Is_As_Strong_As_Its_Weakest_Link_Even_With_FDE}.

Web 400, Hidden in plain sight

Elliot is missing. You now work for the DarkArmy. You didn’t want to ? Well, wh1t3r0s3 isn’t asking. Before his disappearance Elliot inserted a very subtle and stealth backdoor back into E-Corps HR web application, to maintain access. Find your way in, as your life depended on it.

https://quals.bsideslisbon.org/4D4DA3EE778A4170D336DED21FCB1DAA/

In this challenge, we very quickly decided that only two options were on the table. Something inside the E logo PNG file or something about ECDSA auth system hidden in the cookies.

We tried to run binwalk on the PNG file, and that ZLIB took us a bit of time to understand why there was MySQL table inside! But nothing more than false positive, so we headed right down to ECDSA.

We also noticed that admin:admin gave us a different answer than other user and password combination:

Due to the 5/9 events, login via INTERNET has been disabled

In the cookies there were 2 keys: auth and sessid. In the first cookie we had a BASE64 string. The second one a 224 bit hash, like 1d28ca0ac8799b0cf44fbf2fef524d7a42c4a28b7de9f20f28621ae0.

In the auth the values were similar to this:

eyJhdXRoIjogeyJzZXNzaWQiOiAiMWQyOGNhMGFjODc5OWIwY2Y0NGZiZjJmZWY1MjRkN2E0MmM0YTI4YjdkZTlmMjBmMjg2MjFhZTAiLCAidXNlciI6ICJhbm9ueW1vdXMifSwgInNpZ24iOiB7IkVDRFNBIjogInlrbmxQYURoa2l1ZnF6VTVmaWdyWjRjWjFuSTg3ckgvYmxvaWg1YmVkMUlqZ0JuajBuTkdMc1JNMCsyRVBUWFcifX0=

Using base64 -d in the command line we could decode the information:

{“auth”: {“sessid”: “1d28ca0ac8799b0cf44fbf2fef524d7a42c4a28b7de9f20f28621ae0”, “user”: “anonymous”}, “sign”: {“ECDSA”: “yknlPaDhkiufqzU5figrZ4cZ1nI87rH/bloih5bed1IjgBnj0nNGLsRM0+2EPTXW”}}

If we modified the sessid, the user or the sign it led to 403 Forbidden. If we cleaned the cookies and check again we noticed that a new sessid and sign was generated. We also noticed that the first half of the sign was always the same, and with a bit of research we found this video from LiveOverflow (check out the channel, it have great videos about security) talking about ECDSA vulnerability in other CTF and this write up.

The most confusing part of using the python script provided by the write up was:

  • It provided a public key hash. We needed to use ecdsa.curve.NIST192p.order as the n for our equation. And why 192 bit? You have have a finite number of Elliptic Curves (EC) implemented in Python: prime192v1, secp224r1, prime256v1, secp256k, 1secp384r1 and secp521r1. If you try to create an hash with these, you will notice that the hash get larger as the bits go on, so 192 bits matched our sign.
  • The message structure. Not sure why, but in the beginning we were trying to do user:ssid as the message structure. We knew that we needed admin as the user, but we were always unsure what was the right structure. As the time goes on, I’ve decided in the final test have it the same as the auth field, with JSON structure.

After various attempts to make it work with this challenge, I ended up creating a post in the Cryptography Stack Exchange to have an outside person confirm that this was a vulnerability and we weren’t on a path without an exit, when in reality we were very close to find the solution.

The missing part was that we needed to make a POST request with the credentials admin:admin to access the flag in the HTML response:

flag{s3t3c_45tr0n0my_1s_d4_sh1t_4nd_y0u_kn0w_1t}

Reverse 500, You shall not pass!

This file was leaked in a recent Vault9 leak. It may or may not contain Trump’s tax returns.

At this time we knew that this was the last challenge, so a little bit of more pushing to guarantee the presence at the onsite CTF.

It was given to us a file named trump. The first thing to try wasbinwalk.

DECIMAL HEXADECIMAL DESCRIPTION
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
0 0x0 ELF, 32-bit MSB MIPS-I executable, MIPS, version 1 (SYSV)
148316 0x2435C Unix path: /libdl/../ldso/dl-hash.c
152742 0x254A6 Unix path: /nptl/sysdeps/generic/dl-tls.c

As the challenge name says, it’s a reverse challenge, so we need to pick the right tool for the job. I only have experience with IDA, but the free version doesn’t allow to reverse a file compiled in MIPS architecture.

The next tools that came into my mind was Hopper (commercial) and Radare2 (opensource). Hopper doesn’t also support MIPS, but there is a plugin to allow it.

Radare2 is a opensource command line reverse tool. I don’t have experience with command line reverse tools, so I’ve tried to use a front-end for Radare2, Cutter. I end up not getting along with Cutter, and tried to find another tool.

To successfully reverse this file, I had to be able to run the executable and add some break points along the way, so I could snoop around and understand what it was doing.

To run the executable, we found out this link that explains what package you need to install on Linux in order to run and debug a MIPS ELF. Now we could run it, although I still couldn’t debug it:

./trump 
Enter Password:

We tried some strings to know how the software behaved, but we knew that we need to dive into the assembly code in order to extract the password.

Searching google for “mips decompiler” the first result was JEB Decompiler. This is only a decompiler and not a debugger, but supports MIPS and has a great tool to convert assembly code to C.

In JEB, I saw the C code for two main functions:

  • The first one, that took our input (password) and compare it to a char generated by a lot of bitwise operations on a non-ASCII string stored in the file. We clearly understand that the password was 8 characters long (it compares to 9 because on the loop exit it will increment one more time).
Function that read the user input (password) and apply bitwise operations to the values stored in the 4359B0 position.
  • The second function, that took the result and used XOR to reveal the flag. On the image bellow you can see the C code. gvar_435A00 have the position where the encrypted flag is stored.
Function that decrypted (using XOR) the flag with the password provided by user input.
435A00 position, where encrypted flag is stored

We even thought about brute-force, but a 8 character password, with a certain that existed some special character there, could take us probably one week to crack it.

For some reason (maybe because I haven’t touched C, apart from Arduino simple stuff, for a long time ago) I decided to implement the code in PHP, but we all know C with all the pointers and references it was a dead end.

We end up typing all the C code of the first function (because the trial version of JEB doesn’t allow us to copy/paste) into a online C compiler and run it from there. And then voila, the password we wanted: sr"b.*JNZ. which gave us the flag: flag{M1ps_1s_N0t_H4rd_4ft3r_411}.

Wrap Up

After last year’s online and onsite CTF on bSidesLisbon, this was my only first attempt again in a CTF. Really enjoyed these two CTF, and I cannot wait for the two awesome days ahead.

--

--