Pwnable.kr is not exactly easy even when they say it is. Despite this scary introduction, this specifically challenge is not that hard.

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

Download : http://pwnable.kr/bin/flag

This is reversing task. all you need is binary

Please note the first sentence of the text: “Papa brought me a packed present!”. Here lies the key to solve it. After downloading the binary, let’s do a sanity check:

$ file flag
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped

Since the file is a stripped ELF, there is no use in running gdb in order to disassemble main() or anything like that. After all, our symbol table is far gone.

One hint was given in the statement of the chall. Packing. Packing is used, among other things, to obfuscate a binary. It basically compresses the binary and adds a decompression routine, so you get your full binary in memory only when you run it. Let’s search for compression signs:

$ strings flag | grep pack
$Info: This file is packed with the UPX executable packer http://upx.sf.net $

I think this answers our question :) UPX is one of the most commonly used packer for executables. in order to unpack it I had to first get UPX:

$ wget -q https://github.com/upx/upx/releases/download/v3.92/upx-3.92-amd64_linux.tar.xz
$ unxz -d upx-3.92-amd64_linux.tar.xz
$ tar -xvf upx-3.92-amd64_linux.tar
$ cd upx-3.92-amd64_linux.tar
$ ./upx -d /PATH_TO/flag
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2016
UPX 3.92        Markus Oberhumer, Laszlo Molnar & John Reiser   Dec 11th 2016

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
    887219 <-    313220   35.30%   linux/amd64   flag

Unpacked 1 file.

And now:

file flag 
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=96ec4cc272aeb383bd9ed26c0d4ac0eb5db41b16, not stripped

Not stripped! Fire up your gdb :D

$ gdb -q ./flag
gdb-peda$ disassemble 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.

So it is basically giving us the flag at address 0x6c2070. Ok, then…

gdb-peda$ x/s \*0x6c2070
0x496628:   "UPX...? sounds like a delivery service :)"

There you go!


Marcos Valle

Born to kill bugs. Live by them.