Flare-On 8 2021 Challenge #2: known

Eviatar Gerzi
4 min readOct 26, 2021

After unzip the files we received a folder with the encrypted files and the “ransomware”.

When I run the UnlockYourFiles.exe I received the following message:

When I decrypt the long base64 string I received:

Encoded: KD4wXzApPiBJdCdzIGRhbmdlcm91cyB0byBhZGQrcm9yIGFsb25lISBUYWtlIHRoaXMgPCgwXzA8KQo=Decoded:(>0_0)> It's dangerous to add+ror alone! Take this <(0_0<)

Maybe it is a hint that we will need to use ROR (right rotate instruction).

When I tried to put the decryption key as abcd I received:

This is because I wasn’t in the directory of the Files folder, after changing it I run it again and add the abcd key which generated the decoded algorithm but because it is the wrong key, it had garbage data inside the files:

I thought to reverse the binary, find the decryption algorithm, and tried to find the decryption key.

The decode function starts at 0x401370:

The interesting algorithm starts at 0x4013BE:

There are two calls which I want to understand: sub_401030 and sub_401220.

Understanding 0x401030

It receives two parameters: sub_401030(var_50, FindFileData.cFileName)

In the first file it is: sub_401030(var_50, "capa.png.encrypted")

When I debugged it with x64dbg it seems that it copies the name to var_50 address.

It returns the length of the string to EAX.

Understanding 0x401220

The function is being called with the following arguments:

sub_401220(lpFileName, var_50, decryption_key)

The var_50 is the name of the file without the “.encrypted” extension.

The function starts by opening the encrypted file lpFileName, then creating a new file with the name without the “.encrypted” extension (using the CREATE_ALWAYS disposition).

It then reads the encrypted file content and once it done, it will load push the decryption key and the content to sub_4011F0. This function looks like doing the decoding:

From this function it seems that the decryption key should be in 8 length.

Using an example to understand the algorithm

This is a simple algorithm, let’s see an example how it works on the PNG file capa.png.encrypted which the first char data is 0xC7 and the decryption key starts with a (random char I selected).

I also used the debugger to understand it:

This is what happens:

// al=0xC7, bl=0x61
// xor al, bl -> encrypted ^ decryption_key
0xC7 ^ 0x61 = 166 = 0xA6
// al=0xA6, cl=0
// rol al,cl -> rol(encrypted, index=0) rotate left
rol(0xA6,0) = 0xA6
// sub al, cl
0xA6 - 0 = 0xA6

The result from 0xC7 is 0xA6. Now let’s see an example for reversing this decoded algorithm.

// al=0xA6, cl=0
// Opposite for sub is add
0xA6 + 0 = 0xA6
// opposite for rol is ror
ror(0xA6, 0) = 0xA6
// We know the decryption key 0x61
0xA6 ^ 0x61 = 0xC7

Reversing the decryption key

We understood how it works. The missing piece is the decryption key, but we know what should be the decoded data in a specific formats like PNG because of the header and we also know its length, together we can guess that this is the data that should be figure out after decoding:

// PNG header 8 length
89 50 4E 47 0D 0A 1A 0A 00

The first 8 bytes of the encrypted data of capa.png.encrypted are:

C7 C7 25 1D 63 0D F3 56 4E

I created this script to figure out the decryption key:

https://stackoverflow.com/a/63174981/2153777
def rotate_left(x, n):
return int(f"{x:08b}"[n:] + f"{x:08b}"[:n], 2)
def rotate_right(x, n):
return int(f"{x:08b}"[-n:] + f"{x:08b}"[:-n], 2)
decoded_data = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00]
encrypted_data = [0xC7, 0xC7, 0x25, 0x1D, 0x63, 0x0D, 0xF3, 0x56, 0x4E]
decryption_key_arr = [-1]*8
for i in range(0,8):
result = decoded_data[i] + i
result = rotate_right(result, i)
decryption_key = result ^ encrypted_data[i]
decryption_key_arr[i] = decryption_key

>>> decryption_key_arr
[78, 111, 49, 84, 114, 117, 115, 116]

>>> ''.join([chr(i) for i in decryption_key_arr])
'No1Trust'

We have the decryption key: “No1Trust”.

I entered this key and it successfully decrypted the files, and the flag was inside the critical_data.txt:

Flag: You_Have_Awakened_Me_Too_Soon_EXE@flare-on.com

--

--

Eviatar Gerzi

Security researcher interested in reversing, solving CTFs, malware analysis, penetration testing and DevOps security (docker and Kubernetes)