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.