概述
原标题:Linux(x86)栈溢出exploit开发技巧“return-to-libc”
序言:
早期的栈溢出是利用溢出点将shellcode(一段实现特定功能的二进制代码)写入栈内,再将函数的返回地址修改为jmpesp的指令地址上去,进而控制eip寄存器执行我们的shellcode。后来linux系统使用不可执行位(NX bit)的加固技术(Windows操作系统与之对应的就是DEP(Data ExecutionPrevention))来保护系统安全,NX bit是一种硬件保护机制,它通过设置页目录表中的相关属性位来表明分配出来的页内存是否可执行。在系统创建进程后可以将栈区间的页设置为不可执行,那么exploit的执行jmpesp后跳到栈区间里但栈不可执行导致出错,进而shellcode无法执行。后来人们为了对抗这种系统加固技术想出来Return-to-libc技术和ROP技术二者原理类似只是ROP技术使用起来相对蛮烦一些(ROP需要在搜索一些小部件gadget)。有兴趣的读者可以搜索一些相关文章。
环境及工具
操作系统:ubuntults14.05
工具:edb,gdb+peda
漏洞程序
一个简单的演示程序,首先程序从main函数的argv环境变量获取字符并拷贝的buffer字符数组里面,由于程序拷贝时没有考虑buffer的大小导致了栈溢出。代码如图1:
图1
首先关闭系统ASLR,并编译程序如图2所示:
图2
从图3我们可以看到开启NXbit后我们的栈区域是不可以执行的:
图3
exploit代码和调试
“Return-to-libc“这种技巧和传统的栈溢出技巧不同的是,它只利用栈来保存我们需要用到的函数的参数给ret指令从栈中去跳转的地址,真正的执行代码则是利用libc库里面的代码,所以就可以过掉NX bit保护了。
在利用写shellcode之前,我们先看一下程序执行的时候栈空间的布局,如图4和图5所示:
图4
图5
从图5可以看到,当程序执行到strcpy函数时,系统给buffer这一字符数组分配地址是0xbffff006,而其后面0xbffff01c地址中保存则是main函数执行完成后ret指令要跳转的地址,程序发生溢出后就可以改变0xbffff01c地址里面的内容,我们只需要写入0xbffff01c-0xbffff006=0x16,22字符再加上sytem函数的地址和参数就可以控制eip寄存器执行我们的shellcode了。
在写exploit之前,我们需要获取一些参数,libc基址,system函数偏移,exit函数偏移,还有”sh”字符的偏移。
libc基址比较好获取从edb的view下memoryregions中,在filter输入libc-如图6:
图6
system函数和exit函数的偏移则是通过读取elf文件的符号表就可以获取的,如图7:
图7
最后就是“sh”字符,我有gdb的peda插件搜索到的,首先gdbretlibc,bmain下断点运行r,搜索字符结果如图8所示:
图8
有了这些我们开始写exploit代码,如图9:
图9
执行结果,如图10:
图10
小结:
以上就是Linux系统的栈溢出Return-to-libc的技巧的用法。目前在突破NX bit保护使用最多的ROP技巧,其利用思想与Returen-to-libc的思想类似,只是ROP的代码利用的并非都是libc库中的代码,而是以ret为结束的指令集,进而完成shellcode的执行。但两者都是利用栈来存储参数和跳转地址的作用进而突破NXbit保护。返回搜狐,查看更多
责任编辑:
最后
以上就是仁爱羽毛为你收集整理的linux进程栈溢出,Linux(x86)栈溢出exploit开发技巧“return-to-libc”的全部内容,希望文章能够帮你解决linux进程栈溢出,Linux(x86)栈溢出exploit开发技巧“return-to-libc”所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复