The challenge presents us with the "preview" binary and the `libc.so.6` file.
The binary allow us to view the first 7 lines of any file specified in the
input with the format "HEAD filename", if the file has less than 7 lines, it
will not be printed. That means the flag file is not accessible.
A quick look at the binary in ida, reveals us that the file is behaving like
an unpacker, it loads ld.so.2 at a random address and makes it load the main
binary in another random address. Furthermore we can see that the main
function has a clear stack overflow. But the binary has the canary...
Examining the unpacked behavior we see that the random position where the
binary loads are taken from the `AT_RANDOM` entry of the auxiliary vector. So
if we know where the program is loaded we leak also the canary, since the
loader takes the canary value from the very same bytes.
After some thinking we found that the binary let's us read `/proc/self/maps`:
BINGO! Fortunately the first seven entries printed match with the address of
the binary and ld, that combined correspond with the canary. Now
OVERFLOW+CANARY+PAD+ROPCHAIN_ON_LD gives us the desired shell!
from struct import pack
from pwn import *
host = 'cee810fa.quals2018.oooverflow.io'
port = 31337
def pow_hash(challenge, solution):
return hashlib.sha256(challenge.encode('ascii') + struct.pack('