Reverse Engineering
Paranoia (100 pts)
Description
im baby
Author: miyako
nc 20.80.240.190 1234
Solution
Given ELF 64 bit file, open it using IDA.
int __fastcall main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
int v4; // ebx
int v5; // eax
unsigned __int64 i; // [rsp+8h] [rbp-18h]
v3 = time(0LL);
srand(v3);
for ( i = 0LL; i <= 0x11; ++i )
{
v4 = flag[i];
v5 = rand();
printf("%i ", v4 ^ ((unsigned __int8)(((unsigned int)(v5 >> 31) >> 24) + v5) - ((unsigned int)(v5 >> 31) >> 24)));
}
putchar(10);
return 0;Basically it just do xor with random value with seed current time (time(0)). To get the plaintext we can do the same process. To overcome delay issue, we can do little bruteforce from current time.

Flag: akasec{n0t_t00_m4ny_br41nc3lls_l3ft}
Grip (100 pts)
Description
its...its...Grippy
Author: miyako
Solution
Given ELF 64 bit, open it using IDA.
We can see that there is mmap function called then the address from mmap (v14) used to store value of static value xored with 0xf2. At the end, v14 called in the main function. From those information we can assume that value on address v14 contains valid assembly because it called in the end. So dump the bytecode then open it again using decompiler.
3 null bytes at the end will cause error on decompile process, so put 0xc3 (ret) to overcome the issue.
Now we have the code, then just convert it to python and get the flag.

Flag: akasec{sh1tty_p4ck3d_b1n4ry}
Sperm Rev (100 pts)
Description
before baby rev, there was sperm rev <3
solve it fast to win another race in your life.
Author: Pengolian
Solution
Given ELF 64 bit, open it using IDA. Nothing useful in available function, check on strings.

Flag: AKASEC{strings_b35t_t00l_1n_r3v3r5e_eng1n33r1ng}
Risks (205 pts)
Description
theres this pretty cool isa called riscv it sounds awesome.
Author: miyako
Solution
Given ELF 64 bit RISCV file, open it using ghidra. Rename some known function to make it easily to understand.
So there are 5 custom functions in the program.
FUN_00101ad4, FUN_00101346, FUN_00100c8c, and FUN_00100786 process our input with some operation such as xor and add.
compare_value validate our processed input with static value
From those informations we can get the valid input by utilizing z3. Below is my solution

Flag: akasec{1n_my_b4g_0n3_s3c0nd_0n3}
Packeta (460 pts)
Description
BalanΓ§a o ombrin', vai, vai BalanΓ§a o ombrin', vai, vai
BalanΓ§a o ombrin' Jogadinha do Packeta
Author: Pengolian
Solution
Given 2 ELF 64 bit files which are flag and packeta. First, open packeta using IDA. There are many function in the program, rename each function.
generate_key function
So basically it generate key based on (current time % 500) + 4919. From that information we know that the possibility of the key only 500 (possible to brute).
call_rc4 function
Lets take a look on rc4 function
From above code we can confirm that byte_5020 used as the key for rc4 function. To know the ciphertext values we can debug the executable using GDB.

The ciphertext values start with 0x4d75. Check on flag binary to findout on which section those ciphertext.

From image above we can confirm that the ciphertext section is on .text section. To get the valid key we can do bruteforce and validate manually which plaintext consist of valid assembly instruciton because the first ciphertext is the start function. Below is my script
For the comparison we can use the standard start function, such as from packeta file.


So i == 127 looks like the correct value because it result valid assembly like standard start function. To get the rest plaintext we can debug the program and set the value for the (current_time % 500).

Continue the process then run the new generated ELF named new.

Flag: AKASEC{h4lf_p4ck_h4lf_7h3_fl46}
Mips (477 pts)
Description
check out my 16 star pb (note: you need ares to run the rom properly)
Author: miyako
nc 20.80.240.190 4321
Solution
Given Nintendo 64 ROM image. During the competition i found good reference about nintedo 64 reverse engineering. From the description we know that we can run the rom using ares. In this case i install the emulator on ubuntu. To load the rom we can click Load -> Nintendo -> Nintendo 64.

Setup the input mapping by click Settings -> Input.

Press some random button and it will reflected on screen, to submit the button we can press enter button (start).

Next, we need to decompile the rom. I use ghidra with N64LoaderWV plugin to do that.

Searching for "wrong" string then we will found the validation program.
From above code we got some information
Line 30: Our input mapped to some constant value
Line 33: Input length is 0x1e, we can also confirm through user interface by input more than 30 button then it will reset
Line 34: Our mapped input validated with constant value at (DAT_800270c8)
Now we need to get the valid input mapping, one of the way to do that is by debugging. Click Settings -> Debug then enable debugging with below options.

After that, use gdb-multiarch to connect to gdb server.

Then breakpoint at 0x8000b53c.
Press up button (for example), then the breakpoint will be hitten. Look at v0 register to know the mapped value for up button.

Do the same thing until got all mapped input then create script to get the reflected input on screen.

Flag: akasec{m1ps_1s_c00l_l0l}
Orgalorg (498 pts)
Description
Did you know that Gunter is literally Orgalorg, a primordial cosmic entity, feared as the Breaker of Worlds, disguised as a penguin on earth...
nc 20.80.240.190 1235
Author: pengolian
Solution
Given ELF 64 bit file, open it using IDA.
So in main function there are two user defined function which are func_1 and sub_5950. Lets take a look on func_1. At the time of competition i've renamed some function while debugging.
anti_debug_1
anti debug function, will exit the process if debugging detected
will open /proc/self/status to check debugging status
We can easily bypass the the anti debug by changing the return value
get_string
kind of string obfuscation, the function will return "plaintext" of obfuscated/encrypted string
sub_bbc0
check length of OGP and ensure that it constructed only from digits
prctl
set the process name to sleep
dword_17240
There will be set of dword_17240 variable to 1 if there is valid OGP and debugging not detected
Back to main function, after calling of func_1 there will be validation of dword_17240. If dword_17240 not zero it will call func_2. So lets take a look on func_2.
fork
There is call of fork, so after calling fork the rest flow will be processed by the child process
Set follow fork mode to child on GDB to debug the child process
Next, take a look on func_3
Line 50: initialize socket listening, bind to port 50009
Line 121: sending banner (during the initial connection)
Line 126: process our input
Next lets take a look on process_recv.
Line 235: receive user input
Line 318: process received user input
Take a look on sus_func_1
Line 84: compare "p455" with first value on splitted input
Line 91-94: compare second value on splitted input with some character and hash
all the hash are available on online database because it only a few character
sub_DEB0 == md5
So basically we can find all the valid values by set breakpoint on all cmp instruction. For example
During the competition i create gdb script to automate the repetitive task.
After get the valid input, just send it to the server and got the shell

Flag: AKASEC{Orgalor6_1n_d1sgu1s3_as_d4em0n_p3ngu1n}
Last updated