0%

格式化字符串

%数字+$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的地址