9447 CTF 2014 - No Strings Attached (Reversing)
A crack me that decrypts the password into a wide length string in memory.
Challenge Description
Points
25
Description
no strings attached (25pts)
Solution
Running the binary yields the following:
$ ./no_strings_attached
Welcome to cyber malware control software.
Currently tracking 2097550375 bots worldwide
Please enter authentication details: AAAAAAAA
Access denied!
Looks like we have to find the correct input to the binary. For 25 points, it should be pretty easy. Let’s take a look at ltrace first though:
$ ltrace ./no_strings_attached
__libc_start_main(0x804876e, 1, 0xffe0eeb4, 0x80487c0 <unfinished ...>
setlocale(LC_ALL, "") = "en_SG.UTF-8"
time(0) = 1417538944
srand(0x547ded80, 0xf779c500, 0xffe0ee44, 0xf775c000) = 0
wprintf(0x8048890, 0xf779c500, 0xffe0ee44, 0xf775c000Welcome to cyber malware control software.
) = 43
rand(0x8048890, 0xf779c500, 0xffe0ee44, 0xf775c000) = 0x2dc23a13
wprintf(0x8048940, 0x2dc23a13, 0xffe0ee44, 0xf775c000Currently tracking 767703571 bots worldwide
) = 44
wprintf(0x80489d8, 0x2dc23a13, 0xffe0ee44, 0xf775c000) = 37
wcslen(0x8048a88, 0, 0, 0) = 38
wcslen(0x8048a70, 0, 0, 0) = 5
wcslen(0x8048a88, 0, 0, 0) = 38
malloc(39) = 0x96ef978
wcscpy(0x96ef978, 0x8048a88, 0, 0) = 0x96ef978
fgetws(0xffe06dec, 8192, 0xf775cc20, 0Please enter authentication details: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
) = 0xffe06dec
wcslen(0xffe06dec, 8192, 0xf775cc20, 0) = 42
wcscmp(0xffe06dec, 0x96ef978, 0xf775cc20, 0) = 1
wprintf(0x8048b84, 0x96ef978, 0xf775cc20, 0Access denied!
) = 15
wcslen(0x8048a88, 0x80489d8, 0xffe0ede4, 0xf75e3f14) = 38
wcslen(0x8048a70, 0x80489d8, 0xffe0ede4, 0xf75e3f14) = 5
wcslen(0x8048a88, 0x80489d8, 0xffe0ede4, 0xf75e3f14) = 38
malloc(39) = 0x96ef9a8
wcscpy(0x96ef9a8, 0x8048a88, 0xffe0ede4, 0xf75e3f14) = 0x96ef9a8
+++ exited (status 0) +++
Notice that there are library calls to wcscpy, fgetws, wprintf, wcslen, and wcscmp. These calls are the wide character equivalents of the traditional library calls. So we should expect strings with each character taking up more than 1 byte.
Now for a quick overview of the diassembly:
There are two really interesting functions that stand out at this point: authenticate and decrypt. Let’s look at the CFG for authenticate:
Notice that there is also another call to decrypt. The result of the decryption is then wcscmp’d to a string fgetws’d from the user. We want to discover the result of that particular decryption. For information purposes:
Let’s proceed to the dynamic analysis in GDB.
$ gdb no_strings_attached
GNU gdb (GDB) 7.8
...
Reading symbols from no_strings_attached...(no debugging symbols found)...done.
gdb-peda$ break decrypt
Breakpoint 1 at 0x804862c
gdb-peda$ r
Starting program: /home/amon/ctf2014/9447ctf2014/nsa/no_strings_attached
Welcome to cyber malware control software.
Currently tracking 1332758032 bots worldwide
...
Breakpoint 1, 0x0804862c in decrypt ()
gdb-peda$ fin
Run till exit from #0 0x0804862c in decrypt ()
...
0x080486f5 in authenticate ()
Now, the address of the result from decrypt should be stored in eax. Verifying this by looking at the context:
[----------------------------------registers-----------------------------------]
EAX: 0x804b978 --> 0x39 ('9')
EBX: 0xf7fb0000 --> 0x1abda8
ECX: 0x1480
EDX: 0x7d ('}')
ESI: 0x0
EDI: 0x0
EBP: 0xffffcfa8 --> 0xffffcfc8 --> 0x0
ESP: 0xffff4f80 --> 0x8048a88 --> 0x143a
EIP: 0x80486f5 (<authenticate+29>: mov DWORD PTR [ebp-0xc],eax)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x80486e1 <authenticate+9>: mov DWORD PTR [esp+0x4],0x8048a70
0x80486e9 <authenticate+17>: mov DWORD PTR [esp],0x8048a88
0x80486f0 <authenticate+24>: call 0x8048628 <decrypt>
=> 0x80486f5 <authenticate+29>: mov DWORD PTR [ebp-0xc],eax
0x80486f8 <authenticate+32>: mov eax,ds:0x804a038
0x80486fd <authenticate+37>: mov DWORD PTR [esp+0x8],eax
0x8048701 <authenticate+41>: mov DWORD PTR [esp+0x4],0x2000
0x8048709 <authenticate+49>: lea eax,[ebp-0x800c]
[------------------------------------stack-------------------------------------]
0000| 0xffff4f80 --> 0x8048a88 --> 0x143a
0004| 0xffff4f84 --> 0x8048a70 --> 0x1401
0008| 0xffff4f88 --> 0x0
0012| 0xffff4f8c --> 0x0
0016| 0xffff4f90 --> 0x0
0020| 0xffff4f94 --> 0x0
0024| 0xffff4f98 --> 0x0
0028| 0xffff4f9c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
A ‘9’! That looks super promising. Taking a look at the memory:
gdb-peda$ x/32c 0x804b978
0x804b978: 0x39 0x00 0x00 0x00 0x34 0x00 0x00 0x00
0x804b980: 0x34 0x00 0x00 0x00 0x37 0x00 0x00 0x00
0x804b988: 0x7b 0x00 0x00 0x00 0x79 0x00 0x00 0x00
0x804b990: 0x6f 0x00 0x00 0x00 0x75 0x00 0x00 0x00
gdb-peda$ x/16s 0x804b978
0x804b978: "9"
0x804b97a: ""
0x804b97b: ""
0x804b97c: "4"
0x804b97e: ""
0x804b97f: ""
0x804b980: "4"
0x804b982: ""
0x804b983: ""
0x804b984: "7"
0x804b986: ""
0x804b987: ""
0x804b988: "{"
0x804b98a: ""
0x804b98b: ""
0x804b98c: "y"
Each character takes up 4 bytes of space. Our short printing of strings revealed a partial flag. Unfortunately, gdb doesn’t have in-built support for wide character strings but we can utilise a function in libc through call.
gdb-peda$ call wprintf($eax)
...
gdb-peda$ fin
Run till exit from #0 0x080486f5 in authenticate ()
Please enter authentication details: 9447{you_are_an_international_mystery}
In addition to the prompt, we have our flag after the prompt is printed :D
Verifying:
$ ./no_strings_attached
Welcome to cyber malware control software.
Currently tracking 2038332618 bots worldwide
Please enter authentication details: 9447{you_are_an_international_mystery}
Success! Welcome back!
Flag: 9447{you_are_an_international_mystery}
Leave a Comment