2014 Challenges:

1.CH1:

The file is a .net executable:

Opening the file in dnspy:

We then go to the resources section and get the bytes from dat_secret

Afterwards we decode the payload:

file=open('file','rb').read()
text=[]
for b in file:
	text += [chr((b >> 4 | (b << 4 & 240)) ^ 41)]
 ''.join(text)
'3rmahg3rd.b0b.d0ge@flare-on.com'

The second challenge is a png image:

The image is suspicious because it is fairly low resolution and has data after IEND.

While exploring it with any hex editors we observe that the data is a php script:

We decode the information contained in the php


order=[59, 71, 73, 13, 35, 10, 20, 81, 76, 10, 28, 63, 12, 1, 28, 11, 76, 68, 50, 30, 11, 24, 7, 63, 45, 20, 23, 68, 87, 42, 24, 60, 87, 63, 18, 58, 87, 63, 18, 58, 87, 63, 83, 43, 87, 93, 18, 90, 38, 28, 18, 19, 66, 28, 18, 17, 37, 63, 58, 37, 91, 63, 83, 43, 87, 42, 24, 60, 87, 93, 18, 87, 66, 28, 48, 19, 66, 63, 50, 37, 91, 63, 17, 1, 87, 93, 18, 45, 66, 28, 48, 19, 40, 11, 25, 5, 70, 63, 7, 37, 91, 63, 12, 1, 87, 93, 18, 81, 37, 28, 48, 19, 12, 63, 25, 37, 91, 63, 83, 63, 87, 93, 18, 87, 23, 28, 18, 75, 49, 28, 48, 19, 49, 0, 50, 37, 91, 63, 18, 50, 87, 42, 18, 90, 87, 93, 18, 81, 40, 28, 48, 19, 40, 11, 7, 5, 70, 63, 7, 37, 91, 63, 12, 68, 87, 93, 18, 81, 7, 28, 48, 19, 66, 63, 50, 5, 40, 63, 25, 37, 91, 63, 24, 63, 87, 63, 12, 68, 87, 0, 24, 17, 37, 28, 18, 17, 37, 0, 50, 5, 40, 42, 50, 5, 49, 42, 25, 5, 91, 63, 50, 5, 70, 42, 25, 37, 91, 63, 75, 1, 87, 93, 18, 1, 17, 80, 58, 66, 3, 86, 27, 88, 77, 80, 38, 25, 40, 81, 20, 5, 76, 81, 15, 50, 12, 1, 24, 81, 66, 28, 40, 90, 58, 81, 40, 30, 75, 1, 27, 19, 75, 28, 7, 88, 32, 45, 7, 90, 52, 80, 58, 5, 70, 63, 7, 5, 66, 42, 25, 37, 91, 0, 12, 50, 87, 63, 83, 43, 87, 93, 18, 90, 38, 28, 48, 19, 7, 63, 50, 5, 37, 0, 24, 1, 87, 0, 24, 72, 66, 28, 48, 19, 40, 0, 25, 5, 37, 0, 24, 1, 87, 93, 18, 11, 66, 28, 18, 87, 70, 28, 48, 19, 7, 63, 50, 5, 37, 0, 18, 1, 87, 42, 24, 60, 87, 0, 24, 17, 91, 28, 18, 75, 49, 28, 18, 45, 12, 28, 48, 19, 40, 0, 7, 5, 37, 0, 24, 90, 87, 93, 18, 81, 37, 28, 48, 19, 49, 0, 50, 5, 40, 63, 25, 5, 91, 63, 50, 5, 37, 0, 18, 68, 87, 93, 18, 1, 18, 28, 48, 19, 40, 0, 25, 5, 37, 0, 24, 90, 87, 0, 24, 72, 37, 28, 48, 19, 66, 63, 50, 5, 40, 63, 25, 37, 91, 63, 24, 63, 87, 63, 12, 68, 87, 0, 24, 17, 37, 28, 48, 19, 40, 90, 25, 37, 91, 63, 18, 90, 87, 93, 18, 90, 38, 28, 18, 19, 66, 28, 18, 75, 70, 28, 48, 19, 40, 90, 58, 37, 91, 63, 75, 11, 79, 28, 27, 75, 3, 42, 23, 88, 30, 35, 47, 59, 71, 71, 73, 35, 68, 38, 63, 8, 1, 38, 45, 30, 81, 15, 50, 12, 1, 24, 81, 66, 28, 40, 90, 58, 81, 40, 30, 75, 1, 27, 19, 75, 28, 23, 75, 77, 1, 28, 1, 43, 52, 31, 19, 75, 81, 40, 30, 75, 1, 27, 75, 77, 35, 47, 59, 71, 71, 71, 73, 21, 4, 37, 51, 40, 4, 7, 91, 7, 4, 37, 77, 49, 4, 7, 91, 70, 4, 37, 49, 51, 4, 51, 91, 4, 37, 70, 6, 4, 7, 91, 91, 4, 37, 51, 70, 4, 7, 91, 49, 4, 37, 51, 6, 4, 7, 91, 91, 4, 37, 51, 70, 21, 47, 93, 8, 10, 58, 82, 59, 71, 71, 71, 82, 59, 71, 71, 29, 29, 47]
trm_list=["M", "Z", "]", "p", "\\", "w", "f", "1", "v", "<", "a", "Q", "z", " ", "s", "m", "+", "E", "D", "g", "W", "\"", "q", "y", "T", "V", "n", "S", "X", ")", "9", "C", "P", "r", "&", "\'", "!", "x", "G", ":", "2", "~", "O", "h", "u", "U", "@", ";", "H", "3", "F", "6", "b", "L", ">", "^", ",", ".", "l", "$", "d", "`", "%", "N", "*", "[", "0", "}", "J", "-", "5", "_", "A", "=", "{", "k", "o", "7", "#", "i", "I", "Y", "(", "j", "/", "?", "K", "c", "B", "t", "R", "4", "8", "e", "|"]

decoded=[]
for i in order:
    decoded.append(ord(trm_list[i]))

bytes(decoded)


Afterwards we decode the streams further in cyberchef:

decoding the one of the character streams yields the flag:

decoded=[]
for i in r'\97\49\49\68\x4F\84\116\x68\97\x74\x44\x4F\x54\x6A\97\x76\x61\x35\x63\x72\97\x70\x41\84\x66\x6C\97\x72\x65\x44\65\x53\72\111\110\68\79\84\99\x6F\x6D'.split('\\')[1:]:
    if i[0]=='x':
        decoded.append(chr(int('0'+i,16)))
    else:
        decoded.append(chr(int(i)))

‘a11DOTthatDOTjava5crapATflareDASHonDOTcom’

Flare on 2015:

Challenge 1:

This challenge is easy, it reads a string and then compares it with its memory block:

We can see in this screenshot that the input is xored with 7d before being compared. This is done in order to hide the flag as unreadable chars.

If we xor the hard-coded chars with the same key we get the flag:

After decoding we get the flag:

Challenge 2 2015:

The second file is as well a windows executable even if it does not have the extension.

After we open it up in ida we see the same structure:

The encrypted flag can be found at:

We can find it because the program loads it before doing the encryption operations on our input in order to compare it with the flag:

There is another hard coded entry that we need in order to decrypt the flag:

The way it works is it gets your input string, then it does some arithmetic operations summarised as the following python script:

        bx=prev_dx
        eax=0x1901c7
        eax=eax&0xffffff00
        eax=eax|i
        eax=eax^pasw[0]
        al=eax&0xff
        ah=(eax&0xff00)>>8
        ah=rol(ah,dx,8)
        eax=(al+1+ah)&0xff
        bx=bx+eax&0xffff

Having the rol function defined as:

rol = lambda val, r_bits, max_bits: \
    (val << r_bits%max_bits) & (2**max_bits-1) | \
    ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))

Keep in mind that the encoded flag is inverted.

The flag can be decrypted by the following script:



rev_flag=[0x0AF,0x0AE,0x0AA,0x8A,0x0C0,0x0A7,0x0B0,0x0BC,0x9A,0x0BA,0x0A5,0x0A5,0x0BA,0x0AF,0x0B8,0x9D,0x0B8,0x0F9,0x0AE,0x9D,0x0AB,0x0B4,0x0BC,0x0B6,0x0B3,0x90,0x9A,0xA8]
pasw=[0xC7]

rev_flag=rev_flag[::-1]

rol = lambda val, r_bits, max_bits: \
    (val << r_bits%max_bits) & (2**max_bits-1) | \
    ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))

def guess(prev_dx,pos):
    dx=prev_dx&3
    for i in range(29,255):
        bx=prev_dx
        eax=0x1901c7
        eax=eax&0xffffff00
        eax=eax|i
        eax=eax^pasw[0]
        al=eax&0xff
        ah=(eax&0xff00)>>8
        ah=rol(ah,dx,8)
        eax=(al+1+ah)&0xff
        bx=bx+eax&0xffff
        if eax==rev_flag[pos]:
            return chr(i),bx


prv=0
for i in range(36):
    cr,prv=guess(prv,i)
    print(cr,hex(prv))

We get the following output:

The encryption function from which this was derived is :

Challenge 1 2016:

This challenge looks to be a little bit trickier than the ones before because it looks to be using an encoding scheme to our input before comparing it to the string that it has hardcoded:

The input process:

The hardcoded flag is in the picture.

After taking out input we see the program calling a function and comparing our input to the result of that function. This is probably where our input string is transformed into something looking more like the flag.

The encoding function takes our input and it then procedes to allocate more space, take 3 letters at a time and encode them:

We realise the algorithm is like the base64 algorithm so we test the hardcoded alphabet stored in the exe:

And we obtain the flag:

Challenge 2 2016:

This challenge impersonates a ransomware and we have to find the key,iv and algorithm that decrypts the data.

During debug you will have to create a folder named briefcase and to modify the flow of the program as to think you have a volume serial number hardcoded in the exe:

We grab the hash that is used to make the key:

This is hashed with the hashing algorithm 0x8004 (sha1):

CALG_SHA 	0x00008004 	SHA hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_SHA1 	0x00008004 	Same as CALG_SHA. This algorithm is supported by the Microsoft Base Cryptographic Provider.

And it’s length is 0x25 as per DataLen parameter.

Next we look for a way of determining the algorithm

Getting the algorithm from the algid is easy, we just look for the parameter list on msdn:

Identifier 	Value 	Description
CALG_3DES 	0x00006603 	Triple DES encryption algorithm.
CALG_3DES_112 	0x00006609 	Two-key triple DES encryption with effective key length equal to 112 bits.
CALG_AES 	0x00006611 	Advanced Encryption Standard (AES). This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_128 	0x0000660e 	128 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_192 	0x0000660f 	192 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AES_256 	0x00006610 	256 bit AES. This algorithm is supported by the Microsoft AES Cryptographic Provider.
CALG_AGREEDKEY_ANY 	0x0000aa03 	Temporary algorithm identifier for handles of Diffie-Hellman–agreed keys.
CALG_CYLINK_MEK 	0x0000660c 	An algorithm to create a 40-bit DES key that has parity bits and zeroed key bits to make its key length 64 bits. This algorithm is supported by the Microsoft Base Cryptographic Provider.
CALG_DES 	0x00006601 	DES encryption algorithm.
CALG_DESX 	0x00006604 	DESX encryption algorithm.
CALG_DH_EPHEM 	0x0000aa02 	Diffie-Hellman ephemeral key exchange algorithm.
CALG_DH_SF 	0x0000aa01 	Diffie-Hellman store and forward key exchange algorithm.
CALG_DSS_SIGN 	0x00002200 	DSA public key signature algorithm.

Afterwards we need a way of seeing the algorithm mode :

KP_MODE

pbData points to a DWORD value that specifies the cipher mode to be used. For a list of the defined cipher modes, see CryptGetKeyParam. The cipher mode is set to CRYPT_MODE_CBC by default for the Microsoft Base Cryptographic Provider

The KP_MODE corresponds to CBC.

The next step is finding out what is the second hashing algorithm, and input:

The algorithm is 0x8003 (md5) as per ALGID:

CALG_MD4 	0x00008002 	MD4 hashing algorithm.
CALG_MD5 	0x00008003 	MD5 hashing algorithm. This algorithm is supported by the Microsoft Base Cryptographic Provider.

We see that file_name is used to generate the IV.

Having all these information, we can decrypt the file using python3 and a little trick:


from wincrypto.constants import CALG_SHA1, CALG_AES_256, bType_SIMPLEBLOB
from binascii import unhexlify
from wincrypto import *
sha1_hasher = CryptCreateHash(CALG_SHA1)
CryptHashData(sha1_hasher, b'thosefilesreallytiedthefoldertogether')
aes_key = CryptDeriveKey(sha1_hasher, CALG_AES_256)
key=aes_key.key

The IV is made using cyberchef

Afterwards we can decrypt the file using cyberchef:

This produces a jpeg file as per the magic number in the picture whish produces the flag:

Challenge 1 2017

The file is a webpage:

After seeing the script, and the hint when you input the wrong flag (rot again)

We put the hardcoded string in cyberchef and get the flag:

Challenge 2 2017

This is an easier challenge than the ones before. It is comprised by an executable that asks us for a flag and then encodes it and compares to a hardcoded hex list that is the encrypted flag.

The flow is:

Afterwards, the reading function strips the input of the endline symbols:

And the encoding function looks like the following:

The first key generation algorithm is easy to reproduce in python:

We only take the one byte because the operation is on a byte level.

Afterwards we make a script to decrypt the flag as follows:

code=[0x0D,0x26,0x49,0x45,0x2A,0x17,0x78,0x44,0x2B,0x6C,0x5D,0x5E,0x45,0x12,0x2F,0x17,0x2B,0x44,0x6F,0x6E,0x56,0x9,0x5F,0x45,0x47,0x73,0x26,0x0A,0x0D,0x13,0x17,0x48,0x42,0x1,0x40,0x4D,0x0C,0x2,0x69,0x0]

past=0x4 for i in code[::-1]: past=past^i print(chr(past))

Which gets us the flag:

R_y0u_H0t_3n0ugH_t0_1gn1t3@flare-on.com

Challenge 1 2018

There is a jar file which asks us for an invitation code:

Opening the file in jdgui yields the flag:

Challenge 2 2018

This appears to be a minesweeper game, we look at the flag generation algorithm in dnspy:

Now we need to figure out where the bomb tiles are set so we look at the getter for the mine field:

Putting a breakpoint here will guarantee us to know where the cells are set.

Furthermore we will put flags on the cells using the watch and setting the variables as true:

We select the flagged mines:

Afterwards we win

Challenge 1 2019

This challenge is made in .NET

The visuals are good:

And the purpose is to input 2 codes into the field, and a flag will be generated.

The first flag is clear text in the :

And the second flag can be seen xored in the second form:

Afterwards we input the password decoded (Bagel_Cannon):

And we get the victory screen

Challenge 2 2019:

The second challenge is simple as well, we have an executable that produces the following message when opened:

The two dots are an indicator that the string does not stop there. We modify the length parameter int the decrypt function and get the flag:

The lenght parameter is the third argument passed to the function.

Otherwise there is a very simple encoding scheme in the decoding function that we can imitate in python and use the hardcoded flag present in the exe:

Challenge 1 2020

The first screen prompts us for a password. As this is a python file, we quickly find the formula:

    altered_key = 'hiptu'
    key = ''.join([chr(ord(x) - 1) for x in altered_key])
    return input == key

Leading us to input ghost

After we can just play the game and we get the flag:

There are many approaches to find the flag, we can play, augment the coin mechanism to give us half the ammount every time so we win faster, we can decode the flag ourselves.

If we want to decode the flag ourselves we will copy the sequences that compute the flag in the game and execute them in python:

Challenge 2 2020:

This challenge is the hardest 2nd challenge so far, it gives you a broken binary and tells you to get the flag.

We see that the file is packed with UPX:

So we get another file, pack it with UPX and copy the bottom part from it so it matches the xml left at the end of this one.

We use upx to unpack the exe:

Afterwards we analyse in ida because it cannot run:

We see that it uses 2 packs of 2 strings in some suspicious functions that turn out to be decryption related:

where this[3] is the password length, this[2] is the password and this [0] is the encrypted string.

We use cyberchef and decrypt the strings:

Challenge 1 2021

The first challenge is a web form that contains an encoded password and asks us for an username and a password:

The password should be the base64 encoded form of goldenticket.

We either fill the form or decode the hardcoded flag on our own:

Or input the base64 encoding as password and Admin as user:

Challenge 2 2021:

Ransomware again

The functioning logic is incapsulated in the following picture

When opening the executable we can see the following message:

The algo is xor with a key. We can see the algorithm at work in the following function:

In order to get the key we need to get a file we know some bytes to, fortunately for us we know the magic numbers for both jpg and png.

We break the password using the following script:

Afterwards we decrypt the files and get the password.

(>0_0)> You_Have_Awakened_Me_Too_Soon_EXE@flare-on.com <(0_0<)

Challenge 1 2022

The first challenge is simple enough, it is another wordle game.

In order to run it we need to start a server in the folder with the files python -m http.server should do it .

Afterwards we need to look at the script.js file:

And we can even test it in the browser:

Challenge 2 2022

This challenge is about clicking a pixel at a specified position:

The pixel is then compared with some hard coded values and if you are correct, it generates the flag. You have 10 chances to get it right.

We observe that the correct positions are 95 and 313 respectively by putting a breakpoint and letting the program reach that point.

We then click in the spot and get the flag.