Return to libc
在典型的栈溢出攻击中,需要把shellcode放在栈内,这样遇到不可执行栈防护的时候就无法成功。
这起源于我们对恶意代码有着自己的想法,想要自己编写一个恶意代码,然后将返回函数地址修改,但是能拿到rootshell,其实应该就大差不错的够了,而这样的功能的实现在动态链接库里有,如system函数这种老生常谈的不安全函数。如果我们能把返回地址修改为system函数所在地址,并且设法把参数成功传递,那我们就不需要自我编写恶意代码且担心栈的不可执行
这是对不可执行栈的绕过,当然我们也可以选用将不可执行栈修改为可执行栈,在编程中,这往往就是一个标志位的值的改变
想要实现return to libc
首先要知道****system****函数的地址,在没有开启地址随机化的前提下
对于同一个程序,函数库总是加载到同一个位置
所以可以通过调试有漏洞的特权程序来确定libc函数的位置
其次是知道要传入命令所在的地址
可以通过直接存在缓冲区中,或者通过存储在环境变量中,使用export指令指明该环境变量会被传递给子进程。
关闭了地址随机化后。一个环境变量在一个进程的不同子进程中是一样的
需要注意的是环境变量的地址在不同程序名下是不一样的,在环境变量被压入栈中首先被压入栈的就是程序的名字,所以程序名字会影响地址
再者是知道system函数调取参数的地址
使用return to libc 攻击,我们只是将返回地址填成了system函数吗,系统没有做好加载它的准备,并没有将它要的参数预加载到栈里。所以我们要自己加载,要猜测地址,而根据栈结构,
ebp+8是放置第一个参数的位置。所以我们要把参数放在这个地方。而ebp的值在函数的开头和末尾有着变化,一个函数的开头末尾称之为函数的序言和后记,为了能准确预测ebp的地址。
我们应该充分了解二者。
ebp+4的地方放上exit()函数的地址是比较好的处理,这样程序可以完美结束
返回导向编程(ROP)
将一些小的指令,这些指令的末尾都是return。通过正确的设置返回地址,可以将这些指令串联起来,借此达到自己的目的