flag
Download: Link to binary
First of all lets download the binary, chmod +x flag
, and check its architecture type and run it.
$ file flag
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, no section header
$ ./flag
I will malloc() and strcpy the flag there. take it.
So as we can see the binary itself doesn’t do much, accepts no input, just ouput exactly what will it be doing.
Lets hop into GDB and see how is it working, you can use Ghidra/IDA as well but lets just stick to GDB as of now, you’ll see in a while why!?!
gef➤ disas main
No symbol table is loaded. Use the "file" command.
gef➤ file flag
Reading symbols from flag...
(No debugging symbols found in flag)
gef➤ info functions
All defined functions:
gef➤ info variables
All defined variables:
There is nothing in the file, this is very odd! No main function, no _entry function, no variables. STRANGE
The only possible explanation of this behavior is, that this binary has been packed with some packer to strip out all the information. We can check which packer has been used using a tool called DetectItEasy
$ bash diec.sh ./flag
ELF64: packer: UPX(3.08)[NRV,brute]
As suspected, this binary has been packed using UPX. We can use the UPX tools to unpack this binary and then see exactly what does it do.
$ ./upx -d ./flag -o ./flag-unpacked-upx
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2018
UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018
File size Ratio Format Name
-------------------- ------ ----------- -----------
883745 <- 335288 37.94% linux/amd64 flag-unpacked-upx
Unpacked 1 file.
$ file ./flag-unpacked-upx
flag-unpacked-upx: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=96ec4cc272aeb383bd9ed26c0d4ac0eb5db41b16, not stripped
As you can see, now we have more information about the binary and it is not stripped and we can not use GDB to analyze it’s behavior.
gef➤ 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
As we can see in the disassembly, at 0x0000000000401184
, some value is being moved into the $rdx register
and is marked with a comment of flag as well. Lets put a breakpoint at *main+39
so that we can inspect $rdx register
and get the value of the flag.
gef➤ b *main+39
Breakpoint 1 at 0x40118b
...
gef➤ x/s $rdx
0x496628: "UPX...? sounds like a delivery service :)" # FLAG
We got our flag. However, we used few tools like GDB and DetectItEasy to understand the binary better, these could have been easily avoided and simple strings
could have been used to solve this challenge.
$ strings flag | grep UPX
UPX!
$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. $
UPX!
UPX!
... Unpack the binary ...
$ string flag-unpacked-upx | grep UPX
UPX...? sounds like a delivery service :)
So, there were multiple ways to solve this binary, however, for the strings
method you’d have to go through the strings output manually and search for interesting strings to understand that it has been packed using UPX and then again go through the strings output of the unpacked binary to get the value of the flag.
Last updated
Was this helpful?