题目地址:请看pwn栈溢出基础练习题——1 ;放了本博客的所有练习题目
fmtstr1
文章目录
printf漏洞概述
printf格式化漏洞
%s:将所指空间数据作为地址,输出该地址内的数据
%p:输出地址本身的地址索引
%n:往地址中写入前方打印成功的字符个数,与%s类似,%s是读,%n是写,一次写四字节
print(“%p%p%p”)时的空间调用图:
"%p%p%p"作为printf()的第一个参数,表明输出的格式,由于没给第二个参数,则默认向上依次输出
当我们可以控制printf()函数参数时,则可轻易获取任意数据
tips:
print(“%3$d”,a,b,c) 3$表示直接打印第三个参数,这里为c
通过printf()泄露任意地址流程图:
当我们构造printf(“%p%p%p%p”)时,该地址空间为:
发现将%p%p%p%p存入0xffffd1bc,并且将0xffffd1bc地址存入printf()参数1的位置,因此当我们将%p%p%p%p换成地址时,则可以将该地址值存入0xffffd1bc,那如果我们能用%s格式化参数则可以将0xffffd1bc地址内容当成地址,输出该地址的值,就是说我们可以通过printf(“地址值%s”)类形式输出任意地址所存的内容。
练习题解析
开启了Canary保护,但地址没有随机化
题目放入ida
发现漏洞printf(&buf),并且buf内容由read函数写入,则我们可以控制
- printf(&buf)只有一个参数
- buf可以被控制
综上存在printf()漏洞
明显我们的目的是将x的值设置为4,在printf()漏洞中%n格式化有写入资格
思路:通过printf()漏洞,利用%n将x的值改为4
先通过ida找到x的地址,并发现x值为3
动态调试,输入AAAAAAAA,并在printf()函数处查看栈
我们的目的是让0xffffd070处为x的地址,这样x地址的值会被存入0xffffd09c中,其次要让%n能操控0xffffd09c所存地址的内容。分析一下,0xffffd070为printf()函数第一个参数,后面的为格式化字符串参数,即0xffffd074为格式化字符串第1个参数,0xffffd09c则为第11个参数,并且由于x的地址就为4字节,%n=4,正好符合x=4的要求,因此构造printf(“x_addr%11$n”)
攻击代码:
from pwn import *
io = process("./fmtstr1")
payload = p32(0x0804A02C) + b"%11$n"
io.send(payload)
io.interactive()