MalwareTech Challenge - strings2.exe
I have been teaching myself to reverse engineer binary programs so that I can use these skills to reverse engineer malware. I have been learning assembly code, and playing with new tools such as ghidra and radare2/cutter.
I found that @MalwareTech had some great binary analysis challenges on his blog and decided to check them out.
This write up covers the second challenge strings2.exe: ‘https://www.malwaretech.com/strings2’
Lets open this binary in cutter and analyze it with radare2. Once open lets navigate to the entry fucntion:
Right away, just as in the first challenge, it looks like we have the flag. This time it has been initialized as a stack string. Lets take a look at the assembly:
(fcn) entry0 200
| entry0 ();
| ; var int32_t var_28h @ ebp-0x28
| ; var int32_t var_27h @ ebp-0x27
| ; var int32_t var_26h @ ebp-0x26
| ; var int32_t var_25h @ ebp-0x25
| ; var int32_t var_24h @ ebp-0x24
| ; var int32_t var_23h @ ebp-0x23
| ; var int32_t var_22h @ ebp-0x22
| ; var int32_t var_21h @ ebp-0x21
| ; var int32_t var_20h @ ebp-0x20
| ; var int32_t var_1fh @ ebp-0x1f
| ; var int32_t var_1eh @ ebp-0x1e
| ; var int32_t var_1dh @ ebp-0x1d
| ; var int32_t var_1ch @ ebp-0x1c
| ; var int32_t var_1bh @ ebp-0x1b
| ; var int32_t var_1ah @ ebp-0x1a
| ; var int32_t var_19h @ ebp-0x19
| ; var int32_t var_18h @ ebp-0x18
| ; var int32_t var_17h @ ebp-0x17
| ; var int32_t var_16h @ ebp-0x16
| ; var int32_t var_15h @ ebp-0x15
| ; var int32_t var_14h @ ebp-0x14
| ; var int32_t var_13h @ ebp-0x13
| ; var int32_t var_12h @ ebp-0x12
| ; var int32_t var_11h @ ebp-0x11
| ; var int32_t var_10h @ ebp-0x10
| ; var int32_t var_fh @ ebp-0xf
| ; var int32_t var_eh @ ebp-0xe
| ; var int32_t var_dh @ ebp-0xd
| ; var int32_t var_ch @ ebp-0xc
| ; var int32_t var_bh @ ebp-0xb
| ; var int32_t var_ah @ ebp-0xa
| ; var int32_t var_9h @ ebp-0x9
| ; var int32_t var_8h @ ebp-0x8
| ; var int32_t var_7h @ ebp-0x7
| ; var int32_t var_6h @ ebp-0x6
| ; var int32_t var_5h @ ebp-0x5
| ; var LPCSTR lpText @ ebp-0x4
| 0x004022b0 push ebp
| 0x004022b1 mov ebp, esp
| 0x004022b3 sub esp, 0x28 ; '('
| 0x004022b6 mov byte [var_28h], 0x46 ; 'F' ; 70
| 0x004022ba mov byte [var_27h], 0x4c ; 'L' ; 76
| 0x004022be mov byte [var_26h], 0x41 ; 'A' ; 65
| 0x004022c2 mov byte [var_25h], 0x47 ; 'G' ; 71
| 0x004022c6 mov byte [var_24h], 0x7b ; '{' ; 123
| 0x004022ca mov byte [var_23h], 0x53 ; 'S' ; 83
| 0x004022ce mov byte [var_22h], 0x54 ; 'T' ; 84
| 0x004022d2 mov byte [var_21h], 0x41 ; 'A' ; 65
| 0x004022d6 mov byte [var_20h], 0x43 ; 'C' ; 67
| 0x004022da mov byte [var_1fh], 0x4b ; 'K' ; 75
| 0x004022de mov byte [var_1eh], 0x2d ; '-' ; 45
| 0x004022e2 mov byte [var_1dh], 0x53 ; 'S' ; 83
| 0x004022e6 mov byte [var_1ch], 0x54 ; 'T' ; 84
| 0x004022ea mov byte [var_1bh], 0x52 ; 'R' ; 82
| 0x004022ee mov byte [var_1ah], 0x49 ; 'I' ; 73
| 0x004022f2 mov byte [var_19h], 0x4e ; 'N' ; 78
| 0x004022f6 mov byte [var_18h], 0x47 ; 'G' ; 71
| 0x004022fa mov byte [var_17h], 0x53 ; 'S' ; 83
| 0x004022fe mov byte [var_16h], 0x2d ; '-' ; 45
| 0x00402302 mov byte [var_15h], 0x41 ; 'A' ; 65
| 0x00402306 mov byte [var_14h], 0x52 ; 'R' ; 82
| 0x0040230a mov byte [var_13h], 0x45 ; 'E' ; 69
| 0x0040230e mov byte [var_12h], 0x2d ; '-' ; 45
| 0x00402312 mov byte [var_11h], 0x42 ; 'B' ; 66
| 0x00402316 mov byte [var_10h], 0x45 ; 'E' ; 69
| 0x0040231a mov byte [var_fh], 0x53 ; 'S' ; 83
| 0x0040231e mov byte [var_eh], 0x54 ; 'T' ; 84
| 0x00402322 mov byte [var_dh], 0x2d ; '-' ; 45
| 0x00402326 mov byte [var_ch], 0x53 ; 'S' ; 83
| 0x0040232a mov byte [var_bh], 0x54 ; 'T' ; 84
| 0x0040232e mov byte [var_ah], 0x52 ; 'R' ; 82
| 0x00402332 mov byte [var_9h], 0x49 ; 'I' ; 73
| 0x00402336 mov byte [var_8h], 0x4e ; 'N' ; 78
| 0x0040233a mov byte [var_7h], 0x47 ; 'G' ; 71
| 0x0040233e mov byte [var_6h], 0x53 ; 'S' ; 83
| 0x00402342 mov byte [var_5h], 0x7d ; '}' ; 125
| 0x00402346 lea eax, [var_28h]
| 0x00402349 push eax
| 0x0040234a call sym.plaintext2.exe__md5_hash__YAPADPAD_Z
| 0x0040234f add esp, 4
| 0x00402352 mov dword [lpText], eax
| 0x00402355 push 0x30 ; '0' ; 48 ; UINT uType
| 0x00402357 push str.We_ve_been_compromised ; 0x403020 ; "We've been compromised!" ; LPCSTR lpCaption
| 0x0040235c mov ecx, dword [lpText]
| 0x0040235f push ecx ; LPCSTR lpText
| 0x00402360 push 0 ; HWND hWnd
| 0x00402362 call dword [sym.imp.USER32.dll_MessageBoxA] ; 0x403008 ; int MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
| 0x00402368 push 0 ; UINT uExitCode
| 0x0040236a call dword [sym.imp.KERNEL32.dll_ExitProcess] ; 0x403000 ; void ExitProcess(UINT uExitCode)
| 0x00402370 xor eax, eax
| 0x00402372 mov esp, ebp
| 0x00402374 pop ebp
\ 0x00402375 ret 0x10
Here we see the stack being initialized and then we see multiple mov byte...
lines.
This is where the flag is being addressed in memory byte by byte.
We are then loading the address of the first byte into eax lea eax, [var_28h]
and pushing it to the stack.
Next a function is called that seems to compute an MD5 hash.
When ran this binary will hash the flag and spit out the MD5 value.
All we have to do for this one is pull the flag out of the stack string and we have our flag. radare2 automatically converts the hex to ascii in a comment next to the instruction so it is easy to extract. However this could also be done programatically with python if needed:
stack_string = [0x46, 0x4c, 0x41, 0x47, 0x7b, 0x53, 0x54, 0x41, 0x43,
0x4b, 0x2d, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x53,
0x2d, 0x41, 0x52, 0x45, 0x2d, 0x42, 0x45, 0x53, 0x54,
0x2d, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x53, 0x7d]
ascii_string = ''
for byte in stack_string:
ascii_string = ascii_string + chr(byte)
print(ascii_string)
In the above code all we are doing is creating a list of bytes which is effectively just like the stack string in the assembly code. We then iterate through this list and use the chr() method to get the string character from the provided unicode code point (the current byte). That string is then added to the end result “ascii_string” and it is printed to the console when the loop exits. We can then take this flag, plug it into MalwareTech’s site, and voila! strings2.exe complete!