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!