The fourth challenge in the “Toddler’s Bottle” series is called “flag.” Here’s our hint, gumshoes:
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
malloc
What is malloc? If we type man malloc, we can learn (among other things) that:
The malloc() function allocates `size` bytes of memory and returns a pointer to the allocated memory.
If we download the file and run it:
$ wget http://pwnable.kr/bin/flag
$ chmod +x ./flag
$ ./flag
I will malloc() and strcpy the flag there. take it.
While messing around the program, it’s unclear whether we need to provide an input or not. Maybe our input could be used as the argument size to malloc? Then the program will strcpy the flag to that allocated memory. Who knows? ¯\_(ツ)_/¯
gdb?
For a while, I was futzing around with gdb, hoping to find something interesting, but wasn’t getting anywhere. Eventually, I found a mention of “file”, which I then ran on flag:
$file flag
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, stripped
Womp womp. After some googling, I found that stripped means exactly what it sounds like. All the debugging info and symbols and otherwise helpful bits have been stripped out.
Packed
The wording of “packed” present seemed kind of strange, so I did some searching around the words “packed” “packing” “binary” and “executable” and found a few things.
From Yet Another InfoSec Blog:
The first thing to know is that not ALL the data/code in a packed executable is compressed. Some of it, namely the unpacking routine, remains unchanged. There are many public packers available on the internet, and most of them leave a very recognizable signature in the unpacking routine. This makes it trivial to determine what packer was used to pack the code.
I followed his example and typed:
$ strings flag
And dealt with a bunch of console output vomit. I saw “UPX” at the bottom. If I run strings again with some filtering:
$ strings flag | grep packed
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
Okay. Time to check out UPX. 😎
UPX
After I downloaded UPX from https://upx.github.io/, I put it in my /usr/path and ran:
$ /usr/bin/upx flag -d
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.
Now if I run file flag, I get:
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!
GDB 2: Electric Boogaloo
Let’s try that again 😅
gdb flag
(gdb) set disassembly-flavor intel
(gdb) disas 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
Here’s a comment with the address of flag:
0x0000000000401184 <+32>: mov rdx,QWORD PTR [rip+0x2c0ee5] # 0x6c2070 <flag>
If print out the value at 0x6c2070:
(gdb) x/1s *0x6c2070
0x496628: "UPX...? sounds like a delivery service :)"
