CyberTalents DFIR - RE CTF [writeup]

Description

This CTF is for DFIR Scholarship program to test the participant's technical skills. It will be in a Jeopardy Style where every player will have a list of challenges in Reverse Engineering category. For every challenge solved, the player will get a certain amount of points depending on the difficulty of the challenge.

Challenges


In this writeup I will explain the main steps to solve every challenge without writing the details to save the time...

1. List :

Category| General Information
Level| Basic
Points| 25
Description:
A security mechanism prohibiting the execution of those programs on a known malicious or undesired list of software.

Flag:
Google it :D


2. r0t4t0r :

Category| Malware Reverse Engineering
Level| Easy
Points| 50
Description:
One more rotation please.

writeup:

Checking file type:


Strings:


well, I think it requires a password then it will encrypt or compare it with another value, and if it is correct it will print the flag..

So let's check the code in IDA :


As I said before, it will take a password, encrypt every character and then compare it with a hard coded password, if they are equal to each other, then it will print the flag which stored in v7[8] 

checking sub_401550 function:


the function use left rotation to encrypt the password.

from the main function we can see 6 hex values which the program will rotate them and then compare them with the password:


0xCDD0CCED9D85B199, 0xCCD1D0D1C0C97DE5, 0xCCD1D0D1C0C97DE5,
0xCCD1D0D1C0C97DE5, 0xF5D0, 0

There are different methods to get the flag:

1. writing a script to convert these values from hex and then rotate them to right.

2. bruteforcing password characters, encrypt them, and then compare it with the hard coded password.

So I used Cyberchef to convert each value from hex and then rotate it to right like that:



Nice ! we can reverse them now to get the right one like that:


we got the first one, you can repeat this step with each value to get the full flag and it will be:
flag{34sy_r0t4t3_L3ft_4s_1234}


3. Assembly Master :

Category| Malware Reverse Engineering
Level| Easy
Points| 50
Description:
We all love assembly.

writeup:

the file is assembly code:

x:
.ascii "v\200suizgahMsMa{\177d\200wMl}bMq|s\200\200w~uwo"
.LC0:
.string "Wrong flag "
.LC1:
.string "correct flag :D "
Secret_Checker:
push rbp
mov rbp, rsp
sub rsp, 32
mov QWORD PTR [rbp-24], rdi
mov DWORD PTR [rbp-4], 0
jmp .L2
.L5:
mov eax, DWORD PTR [rbp-4]
movsx rdx, eax
mov rax, QWORD PTR [rbp-24]
add rax, rdx
movzx eax, BYTE PTR [rax]
xor eax, 19
movsx eax, al
lea edx, [rax+1]
mov eax, DWORD PTR [rbp-4]
cdqe
movzx eax, BYTE PTR x[rax]
movzx eax, al
cmp edx, eax
je .L3
mov edi, OFFSET FLAT:.LC0
call puts
mov eax, 1
jmp .L4
.L3:
add DWORD PTR [rbp-4], 1
.L2:
cmp DWORD PTR [rbp-4], 32
jle .L5
mov edi, OFFSET FLAT:.LC1
call puts
mov eax, 1
.L4:
leave
ret
x, .LC0, .LC1, are all strings

Secret_Checker jump to .L2 so .L2 maybe our entrypoint

checking .L2:


after comparing the input with 32 characters it will jump to .L5

checking .L5:


it takes each byte of the input, xor them with 19, jump to .L3 which it will be increment with 1, then compare the result with the hardcoded string if all match it will print .LC1

the code will be like that:

user_input[i]^19 + 1

So we have to write a small script that decrement it with 1,xor with 19, and then print the flag:
x = "v\200suizgahMsMa{\177d\200wMl}bMq|s\200\200w~uwo"
flag=''
for i in x:
flag += chr( (ord(i) - 1) ^ 19 )
print(flag)
Flag:
flag{just_a_simple_xor_challenge}


4. Dumper :

Category| Malware Reverse Engineering
Level| Easy
Points| 50
Description:
Another executable dumped from memory.

writeup:

From the description of the challenge I think that the file is PE file and is dumped from a memory, so it may need a fix.

Using PE-bear to check it:


The file is unmapped and we should fix it by making it follow  the alignment of the partition not the alignment of the file, So we have to change the raw addresses to the virtual addresses and also the Raw Size...
The new one will be like that:


Save and run the program to get the flag:


Flag:
flag{Successfully_Done_123456}


5. PE M0nSt3r :

Category| Malware Reverse Engineering
Level| Hard
Points| 200
Description:
Better recognize art, cause I don’t forget names.

writeup:

I got stuck after solving the entry point after 5 hours in this challenge so I went to sleep xD
This is a writeup for this challenge from our friend Abdelrahman Nasr in his writeup for the Competition here.


6. ezez keygen2 :

Category| Malware Reverse Engineering
Level| Medium
Points| 100
Description:
I want to play this game with the admin account, could you help me?

writeup:
This challenge already solved in CyberTalents Cairo University CTF 2019 and you can find a writeup [here]


7. Kill Joy :

Category| Malware Reverse Engineering
Level| Medium
Points| 100
Description:
Let's focus on the basics again.

writeup:

Strings:

When using IDA I can't find the entry point, so I used a string "Not what i was searching for :(" to search in IDA and I found that:



The function firstly moves a values to the memory, then 
takes the process name which is the executable name 'Kill_Joy.exe' using szExeFile, and the for loop is shifting the name to be like that: lliK yoJ_ exe.
In the last line you can see that the flag will be the name of the executable and it will be 32 characters.

After some hours we got a hint which is :
0x9E3779B9 ??? Google is your friend :D

 When I googled it I noticed that it is XTEA Algorithm, well .

Now I need The algorithm, The key, and we have the encrypted data which the function moved to the memory before. So let's use a debugger to get the key:

Set a breakpoint to the function call which name is sub_140011113 and start debugging:


I got the argument values which is the key:


Checking function sub_7FF739C41850 I found that it is the encryption function:


The value 0x9E3779V9 seems to be the Delta for TEA algorithm but we are dealing with XTEA here (an updated version from it) .

Now I have the key, the encrypted data, the algorithm... So I can write a script to decrypt it:
#include <iostream>
using namespace std;
int main(){
int count = 32;
uint32_t enc_data[4][2] = {
{0xD6F74320, 0x636A7B0A},
{0xEEC58E45, 0x5F1E3AF5},
{0x14D72088, 0x819BF516},
{0x10A4D83A, 0x2C1001E7}
};
uint32_t key[4] = {
0x34561234, 0x111F3423,
0x01333337, 0x34D57910
};
for(int j=0; j < 4; j++){
unsigned int i;
uint32_t v0=enc_data[j][0], v1=enc_data[j][1],
delta=0x9E3779B9, sum=delta*count;

for (i=0; i < count; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^
(sum + key[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^
(sum + key[sum & 3]);
}
enc_data[j][0]=v0;
enc_data[j][1]=v1;
}
int j=0;
while( j < 4 )
{
printf("%x%x", enc_data[j][0], enc_data[j][1]);
j++;
}
return 0;
}
I got this result which is a Hex value:

I used CyberChef to convert it from Hex and this is the result:

Flag is:
flag{th4ts_h0w_y0u_surv1v3_}

 Thanks for reading 💙