CyberTalents DFIR [RE] CTF

write-up

Featured image

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

Note: 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 xD

2.r0t4t0r

Solve:

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: flag{34sy_r0t4t3_L3ft_4s_1234}

3. Assembly Master

Solve:

the file is the next 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

So, (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.

This is the code i used:

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

Solve:

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

Solve:

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

Solve:

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

7. Kill Joy

Solve:

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 and 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: flag{th4ts_h0w_y0u_surv1v3_}

Thanks for reading 💙