ROP-ret2libc基础知识
- 前提知识准备
- Linux延时绑定机制
- Linux演示绑定机制的实现
- 延迟绑定对我们有什么意义
- libc函数在哪?
- ret2libc使用条件
- 如何使用libc
- plt表和got表的关系
- 整体的跟踪
前提知识准备
Linux延时绑定机制
动态连接的程序调用了libc的库函数,但是libc在运行才被加载到内存中,调用libc函数时,才解析出函数在内存中的地址,为了帮助程序更好的利用内存空间,不用每次把所有的函数真实地址都写进去,用到哪个查哪个,之后在使用就会很方便。
Linux演示绑定机制的实现
a、所有程序调用的libc函数都有对应的plt和got表,其位置固定
b、plt表:调用call put@plt plt表中存放的指令:jmp[puts_got]
c、解析函数真实地址放入got表中存储
plt表:
程序联动表(内部函数表)
got表:
全局偏移表(全局函数表)
延迟绑定对我们有什么意义
got表:
一个绝佳的攻击目标
包含libc函数的真实地址,用于泄露地址
覆盖新地址到got表,劫持函数的流程
plt表:
不用知道libc函数真实地址,使用plt地址就可以调用函数
libc就是linux下的c函数库:
libc中包含着各种常用的函数,在程序执行时才被加载到内存中
libc是一定可以执行的,跳转到libc中函数绕过NX保护
libc函数在哪?
ASLR地址随机化
系统开启/proc/sys/kernel/randomize_va_space
0表示关闭ASLR
1表示保留的随机化,共享库、栈、mmap0以及VDSO随机化
2表示完全的随机化 在1的基础上,通过brk()分配的内存空间也将被随机化
回答:被随机化了找不到-.-
ret2libc使用条件
泄露libc函数地址的条件:
程序有输出函数:例如puts/write/printf
实现:
设置好参数为某函数GOT表地址(GOT表中保存已经调用过的函数的真实地址)
eg: puts_plt(puts_got)
栈缓冲区溢出的基础上,寻找以ret结尾的代码片段
实现:
设置参数、持续控制的目的
构造执行write(1,buf2,20)之后再返回main函数
如何使用libc
1、绕过NX ret2libc aslr随机化 泄露libc地址
2、aslr导致ret2libc的技术常常需要配合一个泄露的操作
3、ret2libc = leak libc 地址 + sys(/bin/sh)
简单的说:
1、泄露任意一个函数的真实地址:只有被执行过的函数才能获取地址
2、获取libc的版本
3、根据偏移获取shell和sh的位置:a、求libc的基地址(函数动态地址-函数偏移量)b、求其他函数地址(基地址+函数偏移量)
4、执行程序获取shell
plt表和got表的关系
这个图一定要理解了
每次调试一个函数的时候,我们都会看到一个call puts@plt,它会从plt表中来找一个真实地址,真实地址呢都是在我没的got表中,plt表再去got表来找,函数在第一次运行时这样子操作。延时绑定的意思是,在我们运行完一次之后,plt表中直接就是我们的真实地址了。
整体的跟踪
类似于windows的虚表和跳转表哦
我们举个例子,我这里使用的是之前文章中的一个实例,代码如下:
我们在红框的位置下个断点
这是第一次运行,所以一定会去got表中取地址,我们输入si指令 跟进
所以jmp就是跳转到了got表中
push 2就是去找got表中<got + 2>的位置,下面的jmp就是返回程序了,我们可以看到的是0x4004d0
也就是返回我们上面的地址了
希望大家可以有所收获哦!