动态连接的程序调用了libc的库函数,但是libc在运行才被加载到内存中,调用libc函数时,才解析出函数在内存中的地址,为了帮助程序更好的利用内存空间,不用每次把所有的函数真实地址都写进去,用到哪个查哪个,之后在使用就会很方便。
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保护
ASLR地址随机化 系统开启/proc/sys/kernel/randomize_va_space 0表示关闭ASLR 1表示保留的随机化,共享库、栈、mmap0以及VDSO随机化 2表示完全的随机化 在1的基础上,通过brk()分配的内存空间也将被随机化 回答:被随机化了找不到-.-
泄露libc函数地址的条件: 程序有输出函数:例如puts/write/printf 实现: 设置好参数为某函数GOT表地址(GOT表中保存已经调用过的函数的真实地址) eg: puts_plt(puts_got) 栈缓冲区溢出的基础上,寻找以ret结尾的代码片段 实现: 设置参数、持续控制的目的 构造执行write(1,buf2,20)之后再返回main函数
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
这个图一定要理解了 每次调试一个函数的时候,我们都会看到一个call puts@plt,它会从plt表中来找一个真实地址,真实地址呢都是在我没的got表中,plt表再去got表来找,函数在第一次运行时这样子操作。延时绑定的意思是,在我们运行完一次之后,plt表中直接就是我们的真实地址了。
类似于windows的虚表和跳转表哦 我们举个例子,我这里使用的是之前文章中的一个实例,代码如下:
我们在红框的位置下个断点
这是第一次运行,所以一定会去got表中取地址,我们输入si指令 跟进
所以jmp就是跳转到了got表中
push 2就是去找got表中<got + 2>的位置,下面的jmp就是返回程序了,我们可以看到的是0x4004d0
也就是返回我们上面的地址了
希望大家可以有所收获哦!