ICMT CSC2
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:
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.
analysing the function quickly there is something to take your eye, the two printed messages for both success and failure cases
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
searching for r14 i found the last time it set is movd r14d,xmm1
then or r14 ,dl
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:
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**
passing this to the app it prints the flag: EGCERT{STRU~MHCS@SX~BNSD~@RRDSU}
rest is coming soon …