RSS
 

Archive for the ‘Hackvent 2019’ Category

Hackvent 2019: Day 14

14 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 14 December 2019

 

Challenge

HV19.14 Achtung das Flag

 

Solution

We are provided with some Perl code so we decide to run it. We realise we need the Tk module which seems to be some GUI library for Perl.
After running the code we are presented with a game which allows us to control the direction of a line with the letters N and M. We also see letters on the screen which look like parts of the flag!

So we start playing this game for fun but realise its very difficult to win the game ends when we hit the line or borders. Therefore, we give ourselves godmode by replacing  $i->cancel();  with  1. However, even if we cheat at the game there are just too many characters and it all gets too messy so we don’t peruse this avenue any further:

Instead, we try to manually deobfustrate the perl code. We don’t need to deobfustrate the whole program, only the parts that spit the cyan coloured text.
Before we do this we use PerlTidy to clean up our code a little.

We follow the word cyan in the __DATA__ segment which we discover is tied to the $z variable. In the call to createText , we see that $d28Vt03MEbdY0  is variable holding the code reference with the flag text components. We’ll use built in B::Deparse  to deparse this. However, it seems like the code actually mutates data so we cannot simply evaluate $d28Vt03MEbdY0  code twice. Therefore, we replace it with an empty string in the actual text to be displayed and print the text to the console instead. We also replace  $q==$t&&$T->() with  $T->() to ensure that the next component is displayed each frame regardless of any checks (i.e. interception check). Finally, we change the FPS in the repeat loop to 1  so the program executes and ends quickly.

Our new code looks like this (with modified lines highlighted):

We run the perl program again and it prints out an interesting but working flag!

Flag:  HV19{s@@jSfx4gPcvtiwxPCagrtQ@,y^p-za-oPQ^a-z\x20\n^&&s[(.)(..)][\2\1]g;s%4(...)%"p$1t"%ee}

Bonus

This challenge also contained the solution to HV19.H4 Hidden Four.

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 13

13 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 13 December 2019

 

Challenge

HV19.13 TrieMe

Resources:

Solution

We are given a webpage with a form and the java source to the bean that serves that page.

Java source:

Initially, we try a few different approached to get our flag. We try to exploit the JSF Viewstate assuming that the state is stored client side which it is not. This post is a good read on the topic.

We also try to navigate to our flag located in the file /data/flag.txt but this also fails. However, we do manage to access the WEB-INF/web.xml file here:
http://whale.hacking-lab.com:8888/trieme/javax.faces.resource…/WEB-INF/web.xml.jsf

Finally, we notice that the default value for the input text field in the form has the value of getTrie() there which returns “INTRUSION WILL BE REPORTED!” for now. Thus, we correctly assume the value of this text is used as an argument to  setTrie() which is otherwise unused. Here we do some digging into the Apache commons library methods being used. In particular the PatriciaTrie data structure. We have a limited attack vector in the name POST parameter to the form. The only thing we can really do is add more values to the trie and it will always contain the initial value of auth_token_4835989. However, how can we use a PatriciaTrie.put()  call to remove an entry?

After some local debugging and static analysis we discover that the  PatriciaTrie.put() method does not properly compare strings that end with a null terminator character or \x00 with their null free counterpart while the  PatriciaTrie.containsKey() method does correctly distinguish them. That means we can simply pass in  auth_token_4835989\0 to our setTrie() method and have it overwrite the initial value already in the trie while changing the outcome of the  !trie.containsKey(securitytoken) check and thus the  isAdmin(trie) check.

This piece of java code demonstrates the issue:

We pass in the string  auth_token_4835989\0 to our form which gives us a message with the daily flag!

Flag:  HV19{get_th3_chocolateZ}

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 12

13 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 12 December 2019

 

Challenge

HV19.12 back to basic

Resources: HV19.12-BackToBasic.zip

Solution

We download the above zip file and find a Windows PE executable called  BackToBasic.exe.
Upon opening the file we are prompted for some input but our input is always wrong.

Initially, we open this file in IDA Pro and inspect it. Its a smallish executable that was originally written in Visual Basic.
We decide to complete this challenge using only static analysis. We use a combination of IDA Pro and another tool called VB Decompiler.
This decompiler was specifically designed to decompile Visual Basic code so its a good bet!

We get the following decompilation result:

We clean this up a little by working through the variables making sense of it all:

After a while we understand what the code is basically doing.
Our input string is first checked to ensure the first 4 characters equal HV19. If this condition is met, we check that our input string has a length of 33 characters. If this condition is met, we perform a loop from 6 to 32 inclusive. These bounds are interesting as Visual Basic starts indexes at 1 and the first 5 characters of our flag are typically HV19{ and the last character is }. Basically we are looping over the indexes belonging to the flag content. Next, we seem to perform some XOR operation on the ordinal of the character (VB Asc command) and some other unknown value. It took a little time to realise this other value was the current string index (which I named char_counter above). Finally, a check is made with the string  6klzic<=bPBtdvff'yFI~on//N. It is important to note that the string is UTF-16 little endian encoded.

Therefore, we simply have to reverse the operation to get our original flag. In other words, take our comparison string  6klzic<=bPBtdvff'yFI~on//N and XOR it with the corresponding index (6,7,etc).

Psuedocode:

We write a little python script to do this for us which provides us with our flag:

Flag:  HV19{0ldsch00l_Revers1ng_Sess10n}

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Hidden 3

13 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 6 December 2019

 

Challenge

HV19.H1 Hidden Three

Solution

During the Day 11 challenge HV19.11 Frolicsome Santa Jokes API, we decide to do some novice penetration testing on the server whale.hacking-lab.com.

We attempt many things including a port scan with nmap with default settings:

We find some open ports:

Port 17 seems very interesting as it is an uncommon port. We do some research and discover it belongs to the Quote of the Day protocol.

We try to get the quote of the day using this command:

Unfortunately, this spits out a single character r which did not make much sense. However, recall the clue that Not each quote is compl. Thus we have to wait until a new letter is given to us! As it turns out a new letter which belongs to the final flag is given to us every hour. As a result, we write a little cron job which logs the date and QOTD result every 15 minutes (to be safe) and decide to check back on it later.

Cron job:

After waiting a full day and checking back our log file looks like this:

Putting all this together gives us our flag!

Flag:  HV19{an0ther_DAILY_fl4g}

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 11

11 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 11 December 2019

 

Challenge

HV19.11 Frolicsome Santa Jokes API

 

Html file mirror: FSJA API Description

Solution

We have the spec for the FSJA API that the elves have made. We use Postman to play around with the API to get a feel for how it works.

Following the instructions, we are able to register a new user and authenticate to get a token.
We use the following payload for our user data:

Upon logging in with the /fsja/login  endpoint we get a token which looks like this:

The token looks like base64 encoded data. In fact, it happens to be a JWT token.

We finally use the /fsja/random  endpoint to get a joke:

The platinum field stands out to me the most.
As a random hunch, I decide to register a user and provide the  platinum field value in the payload myself like so:

I generate another joke and the API kindly provides us with our flag:

Flag:  HV19{th3_cha1n_1s_0nly_as_str0ng_as_th3_w3ak3st_l1nk}

 

Bonus

This challenge also contained the solution to HV19.H2 Hidden Three

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 10

11 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 11 December 2019

 

Challenge

HV19.10 Guess what

Resources: HV19.10-guess3.zip

Solution

We are provided with an ELF binary so the first thing we do is run in in a Linux virtual machine.

The binary prompts us for some input and then tells us we have failed!

Example with input of test:

We look at the strings in the binary for some clues:

We observe how the string  Your input  and  nooooh. try harder! don’t appear as strings.

It is reasonable to assume obfuscation is used at this point to conceal some strings.
We decide to load up the program in one shell and, while its open waiting for input, check the process status output in another shell:

The original binary essentially delegates to calling execve on /bin/bash with the above command but we abuse the fact that it is all in memory to easily fetch our flag!

Flag:  HV19{Sh3ll_0bfuscat10n_1s_fut1l3}

 

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 9

09 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 9 December 2019

 

Challenge

HV19.09 Santas Quick Response 3.0

Introduction

Visiting the following railway station has left lasting memories.

Santas brand new gifts distribution system is heavily inspired by it. Here is your personal gift, can you extract the destination path of it?

Solution

We know that the QR code system is inspired by the first image so we do a reverse image lookup to try and find out more information about it. We find many articles such as this one discussing a pattern called Rule 30.

After some light research, we discover that rule 30 can be used to generate a pattern downwards starting from a single black pixel (or 1). The algorithm is:

This video does a better job explaining it than I ever could:

Next, we notice that our invalid QR code has two QR alignment patterns in the correct positions (top left and top right corners) but is missing one in the bottom left corner. That, combined with the fact that the Rule 30 algorithm generates a tree like pattern is a very strong indication that we should overlap the rule 30 pattern over the QR code and use it as  mask from the middle of the first row (so that the current QR alignment patterns are left intact).

This was our approach. For illustration purposes, this is the area that would be left intact:

We attempt common boolean operators such as and, or and xor and check to see if the bottom left QR alignment pattern suddenly appears. Unfortunately, it initial does not appear. After some head scratching we later find out that xor is the right boolean operation and we have to shift the rule30 pattern by 1 to the right.

This is what the final Rule 30 mask looked like:

Note that the mask is not perfect as it eventually overlaps with itself but is was large enough to fully cover our 33×33 QR code.

Finally, here is our python script:

Running our Python script gave us the following QR code which scans to give us our flag!

Flag:  HV19{Cha0tic_yet-0rdered}

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 8

08 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 8 December 2019

 

Challenge

HV19.08 SmileNcryptor 4.0

 

Dump-File: dump.zip

Solution

We download the zip file and extract the dump.sql file within.
It contains the database schema for some credit cards as well as our flag.

First we look at the flag insert statement:

The prefix and postfix of the flag is stored explicitly in different fields. We then see our first smile ciphertext which looks like this:  :)SlQRUPXWVo\Vuv_n_\ajjce
We don’t know the plaintext that generated this ciphertext so there isn’t much information we can extract from this. We note that it appears as if all smiley ciphertexts begin with an ASCII smiley face :)

Next we look at the credit card insert statements:

Again we see some smile ciphertext which is in the cc_number field which indicates that the plaintext for these ciphertexts should be valid credit card numbers (why would invalid numbers be stored on a shopping website).

At this point we do some research on credit card number formats and standards. See Payment card number on Wikipedia.
In particular, we wanted to know how long various credit card numbers can be, if they have any hard coded values and how to check if a credit card number is valid.

We find out the following:

When inspecting the lengths of our credit card numbers with the smiley face :)  removed, we observe the following lengths:

Naturally, as these lengths match the required lengths of credit card numbers produced by various vendors, we can assume that a 1 to 1 mapping exists between the ciphertext and plaintext. This is a good indicator that an ASCII rotation/shift cipher should be used. We match each credit card vendor to the ciphertext based on its length. Ciphertext A is matched to American Express and B to Diners Club. For the 16 digit ciphertexts, we don’t know exactly which vendor to use. However, as ciphertext E begins with Q (just like and B) which means that logically Q maps to the digit  3. We take a guess here and assume that the other two 16 digit ciphertexts belong to Mastercard and Visa respectively. As R comes after Q in the alphabet we guess that R maps to the digit  4 and maps to the digit  5.

From this we guess we need to do an ASCII rotation which shifts Q (ASCII 81) to equal 3 (ASCII 51) which is a shift of -30 dec.
We write a script to perform this ASCII rotation decipher on our ciphertexts, throwing the final result in a credit card checksum validator function but the results are not valid credit card numbers.

Finally, we notice that our ciphertexts creep up the ASCII range as we move through the string character by character even though the number space for the credit cards is always 0-9 (digits). This implies the ASCII rotation is offset after each character is encoded or decoded. Ciphertext E (JCB) helped us the most here as we know it has to start with the digits  35. Based on our initial mapping, this suggested the offset simply grew by each character.
After adding this offset to our script, our computed plain texts validate as valid credit card numbers!

Python script:

Output:

Flag:  HV19{5M113-420H4-KK3A1-19801}

 

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Hidden 2

08 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 7 December 2019

 

Challenge

HV19.H2 Hidden Two

For easy download, get it here: HV19-SantaRider.zip

Solution

During the Day 7 challenge HV19.07 Santa Rider, we notice there is a ZIP file available to download.
This ZIP file has the typical guid file name and contains one file called 3DULK2N7DcpXFg8qGo9Z9qEQqvaEDpUCBB1v.mp4.
The inner MP4 file has the same hash as the one shown on the webpage so it is of no particular interest.

We attempt to decode the file name string using base64:

It looks like it may be partially decoding correctly so we instead try to base58 decode this and finally this gives us our flag!

Flag:  HV19{Dont_confuse_0_and_O}

Note: It is painful to note that base32, base64, base85, base91 decoding was attempting on this file name was attempted within the first 15 minutes of the challenge but unfortunately base58 was not attempted until much, much later. In the mean time we attempted many other things such as switching the Day 7 binary to match wire configuration in backdrop and inspecting the videos audio stream. Rough one!

 
No Comments

Posted in Hackvent 2019

 

Hackvent 2019: Day 7

08 Dec 2019
CTF: Hackvent 2019
Link to challenge: https://academy.hacking-lab.com
Date Completed: 7 December 2019

 

Challenge

HV19.07 Santa Rider

Resources:

For easy download, get it here: HV19-SantaRider.zip

Solution

We watch the provided video and notice that about half way through the LEDs light up in an interesting order. There are 8 total LEDs and multiple LEDs light up at once so we think that this may be hidden binary messages that decode to ASCII. As the video moves very fast its necessary to inspect each frame individually. We can do this by extracting each frame using a tool like FFmpeg but in this case it was faster to simply use a video editor like MPC-HC which allows you to navigate the video frame by frame.

It is very cool to note that because the video is stationary and position of LEDs do not move, one could use a computer vision library like OpenCV to extract the hidden binary.

We get the following binary:

We convert this binary to ASCII and get our final flag!

Flag:  HV19{1m_als0_w0rk1ng_0n_a_r3m0t3_c0ntr0l}

Bonus

This challenge also contained the solution to HV19.H2 Hidden Two

 
No Comments

Posted in Hackvent 2019