代码生成器在线/排名优化公司哪家靠谱
关于操作系统的ASLR地址随机化
首先我们在实验之前需要了解以下ASLR机制。即linux平台下的地址随机化机制。它将进程中的某些内存空间地址进行随机化来增大入侵者预测目的地址的难度。从而降低被成功入侵的风险。当前Linux、Windows等主流操作系统都已经采用该技术。
linux下的ASLR分为0,1,2三级,用户可以通过一个randomize_va_space进行等级控制。
0:关闭ASLR。
1:保留的随机化。共享栈、库、mmap()、以及VDSO将被随机化。
2:完全的随机化。
现在我们来关闭linux地址随机化:
echo 0 >/proc/sys/kernel/randomize_va_space
不乐意记全路径的小伙伴可以直接使用命令:
find / -name randomize_va_space
关闭随机化后我们就可以直接开始我们的实验啦~
堆溢出实验代码(main.c)
#include #include void hello(){ printf("\rhello\n");} int fun(char *str){ char buf[10]; strcpy(buf, str); printf("%s\n", buf); return 0;} int main(int argc, char **argv){ int i=0; char *str; str=argv[1]; fun(str); return 0;}
代码打好后,我们通过gcc来编译该源文件,使其成为二进制可执行文件(其中-g参数是为了方便我们进行gdb调试,execstack是指允许栈攻击):
gcc -g main.c -o main -z execstack -fno-stack-protector
GDB二进制调试
我们首先使用命令进入gdb调试模式:
gdb main
现在我们先在第12行和第21行下两个断点。
然后我们向内存中写入16个A来判断我们的猜想。
在linux操作系统中,内存的分布是从高地址往低地址扩展的。所以我们这里会先写入高地址,然后再写入低地址。然后我们分析各函数在整个程序中的位置,并分析漏洞产生原因。
我们使用disassemble命令来查看每个函数的反汇编。
通过分析反汇编可知。本机器的栈指针寄存器是64位的,有些电脑是32位的,那么反汇编出来的栈指针寄存器就是esp和ebp。不同电脑的地址和寄存器类型也都不一样。
通过分析main函数的反汇编可以知道:
在地址0x00005555555546f8的位置,调用了fun函数,并且fun函数的返回地址位0x00005555555546fd。
而hello的函数的入口地址为:0x000055555555468a。现在我们可以用hello的首地址覆盖fun函数的返回地址来实现在函数main中调用hello函数。
执行hello函数
我们注入了16个A之后,可以通过栈指针寄存器和明显的看出,我们要溢出的地址就在0x00005555555546fd的位置,我们需要用0x000055555555468a去覆盖0x000055555555468a的地址。
我们可以通过计算得出,18个A然后加上hello的首地址即可实现覆盖0x555546fd。
我们现在向内存中写入数据。
然后进行单步调试,可以发现出现了溢出漏洞。
不过由于堆溢出覆盖了函数的返回地址,所以函数无法正常停止,所以函数无法正常返回。但是hello函数正常执行。