printf 属于可变参数函数,函数调用者可任意指定参数和数量,这也是漏洞产生的原因。
printf()函数的一般形式为:
format参考列表
编译命令
会弹出警告
接着我们尝试运行并输入 AAAA%x,%x,%x,%x,%x,%x,%x,%x,%x
我们可以利用gdb看一下输入的地址
我们可以知道数据在堆栈中是如何储存的并且知道输出的第7位是AAAA的ascll码
为了pwn的利用 我们可以只输出指定的地址
这里利用printf函数的一个特性,$操作符
例如我们现在要输出第7位
发现成功输出第七位AAAA的ascll码
要检测对函数栈的破坏,需要修改函数栈的组织,在缓冲区和控制信息(如 EBP 等)间插入一个 canary word。这样,当缓冲区被溢出时,在返回地址被覆盖之前 canary word 会首先被覆盖。通过检查 canary word 的值是否被修改,就可以判断是否发生了溢出攻击。
为了方式发生信息泄露以及其他漏洞的利用 canary使用\x00对值进行截断
所以canary的最低byte位为\x00
pwn200
程序提供了shell
检查下程序保护
开启了NX以及Canary保护
可以对照源代码 发现多出了变量V5 根据上述canary保护解释应该可以理解 这里的V5应该就是canary保护生成的随机参数 我们也可以在汇编代码处看出
因为v5的地址是esp+3Ch 而这里 mov edx,[esp+3ch]就可以知道edx里面存在的就应该是v5的值了
看到这里利用edx中获取的v5的值与large gs:14h进行 xor判断 如果不相等则 call ___stack_chk_fail 退出程序
一般canary有两种利用方式
1.爆破canary
2.如果存在字符串格式化漏洞可以输出canary并利用溢出覆盖canary从而达到绕过
载入程序到gdb
在printf处下断
尝试运行
这是可在看到我们输入的字符串在堆栈中的位置
尝试打印该地址内存
可以看到输出AAAA的偏移为5
printf打印出的应该是偏移后的下一位地址
我们再运行程序进行测试输出
发现成功输出
这里需要注意 输出的地址都是十进制数 所以在后面地址的利用时 我们应转为16进制使用 或者直接利用pwntools函数p32或者p64直接进行转换
既然canary
我们这xor判断这里下断
输入C 运行到下一断点位置
查看此时的edx的值
我们可以查看之前printf时的内存地址
发现edx 0x68496c00 的偏移为15,所以可以构造打印出当前的canary的值
成功泄露出当前canary
我们应该这样去写exp
既然可以泄露出canary的值,我们就可以通过gets溢出到canary处然后覆盖我们leak处的canary从而达到绕过canary的目的
因为canary的赋值是从v5而来所以这里计算s与v5的偏移即可
得到偏移为40
所以这里的payload可以写为
我们这里的最终目的是为了获取shell
而程序提供了shell
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2018-6-30 19:29
被iosmosis编辑
,原因: