栈溢出之ret2libc
前言
本篇接着前几篇的进度介绍另一种基本ROP方法:ret2libc
ret2libc原理
libc是Linux下的ANSI C的函数库,ANSI C是基本的C语言函数库,包含了C语言最基本的库函数。ret2libc类比之前介绍的三种方法,从字面意思看就是控制返回地址找libc中库函数存在的方法。
一般情况下,我们使用ret2libc主要针对动态链接编译的程序,程序动态链接了libc.so等动态链接库,虽然程序本身并没有用到system等危险函数,但是动态链接库中存在大量的可利用函数,就产生了新的攻击方式,从这些动态链接库中找可利用片段,拼接成恶意代码并控制rip跳转执行。
题目描述
题目源码:
1 |
|
关闭掉地址随机化和栈保护进行编译:
1 |
|
ROP过程
问题分析
使用gdb的checksec查看安全机制
分析程序,read buf局部变量时存在栈溢出问题,但是从题目中直接无法找到任何可利用的代码片段,也有NX保护无法直接执行shellcode,根据前面介绍的ret2libc原理,我们应该在程序的动态链接库里面寻找信息。
设想,只要在动态链接库中找到system函数,再找到/bin/sh字符串,然后覆盖返回地址跳转到动态链接库的system函数控制执行/bin/sh指令就可以得到shell。
寻找信息
接下来就按照整理好的思路一步步获取信息,此次需要使用objdump来在动态链接库中寻找信息。
1.ldd查看动态链接库
ldd ret2libc64
可以看到使用了libc.so.6,libc库中存在大量的可利用函数,所以我们需要在它里面寻找。
2.在动态链接库中寻找system地址
objdump -T /lib/x86_64-linux-gnu/libc.so.6 | grep system
3.在动态链接库中寻找”/bin/sh”地址
ROPgadget –binary ret2syscall –only “pop|ret” |grep ebx
4.找到可控局部变量到返回地址的偏移
0xfe290-0xfe210+0x8=0x88
记录一下得到的信息:
- libc.so.6的基准地址是0x7fbf4cfcf000
- libc_system函数的偏移是0x435d0,那么它的实际地址就是0x7FBF4D0125D0
- /bin/sh字符串的偏移是0x17f573,那么它的实际地址就是0x7FBF4D14E573
- 可控变量到返回地址的偏移是0x88
接下来就可以构造payload了
pwn
首先分析payload构成,我们需要使返回地址指向system函数,然后system函数被调用时,rbp后面会紧跟着system的返回地址,然后再跟着system函数的入参,所以payload就是局部变量到返回地址的偏移padding1,然后libc_system的地址覆盖返回地址,后面接着一个8字节随意填充的padding2,再接上入参/bin/sh
payload = padding1+system+padding2+”/bin/sh”
payload =”A”*0x88+p64(system_addr)+p64(123)+p64(binsh_addr)
然后写出exp:
1 |
|
执行exp即可获取shell
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!