%数字+$n 在偏移数字处填入之前已输入的字符数
1 | payload = b"%64c%9$hn%1510c%10$hnaaa" + p64(__stack_chk_fail+2) + p64(__stack_chk_fail) |
0X400626—-system地址。
将backdoor函数地址分为高两个字节和低两字节两部分进行写入。
64(0x40):对应backdoor函数地址的高两字节0x0040 (上四下四)
9:由于格式化字符串%64c%9$hn%1510c%10$hnaaa占用了24个字节(字符),根据64位程序,24/8=3,所以偏移是6+3=9,配合上$hn使用构成%9$hn,将64(0x40)写入偏移为9的位置,对应的是__stack_chk_fail+2
c:或许有人会这么构造payload = ‘a’ * backdoor_addr + %偏移$n + p64(__stack_chk_fail),程序中读入的字符屈指可数,所以要换为另一个格式字符%c ,读入的字符屈指可数,但经过格式化漏洞转换后,那就是num个字符的输出同样可以达到相同的修改数据的效果
1510:1510+64=1574=0x626,对应backdoor函数地址的低两字节0x0626
10 :在偏移9的基础上加上p64(__stack_chk_fail+2)地址的一字节,即偏移为10
aaa:填充作用,使之为8的倍数让栈对齐
p64(__ stack_chk_fail+2)【高二字节】 + p64(__stack_chk_fail) 【第二字节】:
一旦我们触发栈溢出漏洞,函数退出的时候必然会通过异或操作检测到canary被修改从而执行stack_chk_fail函数。因此,我们要么想办法获取到canary的值,要么就要防止触发stack_chk_fail,或者利用这个函数。
canary的位置:即format局部变量的地址
的上一个位置,则aa%7$p
即泄露canary的地址