函数原型
|
|
str:目标字符数组,用于储存格式化后的结果
format:格式化字符串,包含普通字符和格式符,如a=%d
…:可变参数,对应格式字符串中的格式符,类型需与格式符匹配。如 若参数format为a=%d则…应为int类型的整数
返回值是向str中输入的字符个数
|
|
比sprintf 多了一个size_t参数,用于限制可写入字符数
demo(这个函数的正常使用方法
|
|
漏洞原理
攻击者通过溢出等手段可修改format参数,完整任意地址读写
PS:snprintf是把格式化字符串的地址记下来,每次要处理一个字符时,先从地址处取格式化字符串,然后再根据格式化字符串来处理字符
demo
|
|
先利用sprintf的格式化字符串漏洞,溢出buf2从而修改buf3(sptintf的格式化字符串参数),这样就可以通过任意地址读来泄露canary,然后利用read(0,buf1,0x1000) re2text.exp如下
|
|
这个demo写的不太合适,修改返回地址的时候用的并不是sprintf的漏洞
可以再看下下面的例题
攻防世界EasyPwn
|
|
read(0, s, 0x438uLL);长度不够rop但vul()函数的snprintf函数可溢出v3,可以利用fmt任意地址读泄露libc和pie地址
随后任意地址写,修改freegot表为system地址(可以使用bss段上fmt的方法)
注意由于延迟绑定机制我们需要先调用一次free完成绑定,exp如下
|
|