Flare On challenges 1 and 2 2014-2022
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.
Comments