Pwnable.kr - flag

November 26, 2017

In order to keep this challenge streak alive, I decide to play with another one from pwnable.kr called flag. This time our task is purely reverse enginnering, since we’re only given a binary, with no source code, no listening applications or ssh connections.

Papa brought me a packed present! let's open it.

I started analyzing by running a file command on the binary.

[email protected] ~/programming/pwnable.kr % file flag
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped
[email protected] ~/programming/pwnable.kr % ./flag
I will malloc() and strcpy the flag there. take it.

It shows us that it’s a stripped binary. Running it only prints a message for us, telling how the code works using high level interpretation.

[email protected] ~ % strings flag
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.08 Copyright (C) 1996-2011 the UPX Team. All Rights Reserved. $

After running strings tool, I’ve noticed these lines - it’s packed with UPX packer. We can use upx tool to unpack the binary into a more readable one. Let’s take a look.

1 [email protected] ~/programming/pwnable.kr % upx -d flag -o flag_               :(
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2017
UPX 3.94        Markus Oberhumer, Laszlo Molnar & John Reiser   May 12th 2017

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
    883745 <-    335288   37.94%   linux/amd64   flag_

Unpacked 1 file.

Great, now we’re ready to analyze it with gdb.

[email protected] ~/programming/pwnable.kr % gdb flag_
GNU gdb (GDB) 8.0.1
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from flag_...(no debugging symbols found)...done.
(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
   0x0000000000401164 <+0>:	push   rbp
   0x0000000000401165 <+1>:	mov    rbp,rsp
   0x0000000000401168 <+4>:	sub    rsp,0x10
   0x000000000040116c <+8>:	mov    edi,0x496658
   0x0000000000401171 <+13>:	call   0x402080 <puts>
   0x0000000000401176 <+18>:	mov    edi,0x64
   0x000000000040117b <+23>:	call   0x4099d0 <malloc>
   0x0000000000401180 <+28>:	mov    QWORD PTR [rbp-0x8],rax
   0x0000000000401184 <+32>:	mov    rdx,QWORD PTR [rip+0x2c0ee5]        # 0x6c2070 <flag>
   0x000000000040118b <+39>:	mov    rax,QWORD PTR [rbp-0x8]
   0x000000000040118f <+43>:	mov    rsi,rdx
   0x0000000000401192 <+46>:	mov    rdi,rax
   0x0000000000401195 <+49>:	call   0x400320
   0x000000000040119a <+54>:	mov    eax,0x0
   0x000000000040119f <+59>:	leave  
   0x00000000004011a0 <+60>:	ret    
End of assembler dump.

Here we have an assembly code of main function. One particular thing that brought my notice is at main+32, where something is passed into rdx. Let’s set a breakpoint line after, at mov+39 and check what rdx is storing.

(gdb) break *0x000000000040118b
Breakpoint 1 at 0x40118b
(gdb) run
Starting program: /home/w3ndige/programming/pwnable.kr/flag_
I will malloc() and strcpy the flag there. take it.

Breakpoint 1, 0x000000000040118b in main ()
(gdb) x/s $rdx
0x496628:	"UPX...? sounds like a delivery service :)"

Great, a flag! But after a little bit of playing with it, I’ve found another place where it’s possible to find a flag. Take a look at main+49 and see what’s in eax.

(gdb) break *0x000000000040119a
Breakpoint 1 at 0x40119a
(gdb) run
Starting program: /home/w3ndige/programming/pwnable.kr/flag_
I will malloc() and strcpy the flag there. take it.

Breakpoint 1, 0x000000000040119a in main ()
(gdb) x/s $eax
0x6c96b0:	"UPX...? sounds like a delivery service :)"

And here we have the flag, once again.

Contact

If you have any suggestions regarding this post or just want to chat together check out these ways to reach out to me.