ICMT CSC2

2 minute read

rustyapp

rustyapp is a PE32+ executable (console) x86-64, for MS Windows.

first look at strings found a fake flag EGCERT{how_rusty_is_that?}.

running it found a simple message asking for the flag:

dynamic

Tried some random flag, but the screen just closed.

So it’s IDA time ;), now I have only one clue -the printed message we have seen before- so let’s pray it’s not encrypted.

first look

analysing the function quickly there is something to take your eye, the two printed messages for both success and failure cases

s&f

to test that assumption I chose the shortcut which is debugging, I set the breakpoint before the branch led to prints and entered a random flag and as expected the shortcut worked perfectly so now all I need is to find my way to the correct branch.

a simple backwards analysis would solve the problem.

  • to reach our target we need two checks r14 and r8

r14

searching for r14 i found the last time it set is movd r14d,xmm1 then or r14 ,dl

r14_2

now I know that the flag is xord with some value which is maybe 21 in this loop but I just need to debug this loop to trace the regester’s values.

I set the BP after printing the message then followed the app.

I noticed that:

the flag is three chunks, 8bytes length The key operations that contribute to the final value of r14d are:

move xmm4, r10 pxor xmm5, xmm1 with xmm1 initialized to 2121212121212121h pxor xmm4, xmm3 with xmm3 initialized to 2424242424242424h The accumulative bitwise OR operations (por) that combine these results

r10 is set to memory referred to by r8+r9 XORD with rcx+r8 r8+r9 points to the string “rust_library_core_assertEnter the login Key:> \n”. so now all i need is xor the r8+r9 with the mask 2121212121212121 This Python script would save our efforts

def xor_string_with_mask(input_str, mask):
 padded_input = input_str.ljust((len(input_str) + 7) // 8 * 8, '\x00')
    
 mask_int = int(mask, 16)
    
 result = []
    for i in range(0, len(padded_input), 8):
 chunk = padded_input[i:i+8]
 chunk_int = int.from_bytes(chunk.encode(), 'little')
 xor_result = chunk_int ^ mask_int
 result.append(xor_result)
    
    return result

input_str = "rust_library_core_assertEnter the login Key:> \n"
mask = "2121212121212121"

xor_results = xor_string_with_mask(input_str, mask)

for result in xor_results:
    print(f'{result:016x}')

I ran this code and got this:

out

all I need now is to convert the first three chunks from hex representation into text -but don’t forget to take them in a reversed order- and voila here your correct input:**STRU~MHCS@SX~BNSD~@RRDSU**

flag

passing this to the app it prints the flag: EGCERT{STRU~MHCS@SX~BNSD~@RRDSU}

rest is coming soon …

Written by

Karim Gomaa

Categories:

Updated: