利用缓存区漏洞执行shellcode

环境:win10

工具:vc++6

原理介绍:

 栈溢出,C语言中gets()strcpy()等函数未进行数据长度的限定,在栈内写入超出长度限制的数据,从而破坏程序运行甚至获得系统控制权的攻击手段。几个常见的寄存器,ebp栈底指针,esp栈顶指针,eip下一条计算机执行的指令,计算机中真正的存储方式如下图:

  原理介绍:eip寄存器里存储的是CPU下次要执行的指令的地址eip在内存中位于ebp4个字节(如下图,vc的调试)。

  一个函数调用结束时,也就是在退栈过程中,返回地址会被传给eip,这一点非常重要。当返回地址被我们溢出的数据覆盖的时候,就可以控制eip,从而获得计算机的控制权,所以我们只需要让覆盖返回地址的数据恰好为shellcode的地址,就可以执行自己的shellcode了。

 我提前写好了代码,先看主函数,定义了一个字符串shellcode用来溢出,将它传入overflow()函数,在overflow()函数中

利用strcpy()函数进行溢出,对数据进行填充。还有一个从头到尾都没有调用的函数calc()函数,它可以打开电脑的计算器


#include<stdio.h>

#include<string.h>

#include<windows.h>

void calc(){

  system("calc");

  exit(0);//防止程序崩溃

}

int overflow(char *shellcode) 

{ 

char str[4]="";

  strcpy(str,shellcode);

  return 0;

}  

int main() 

 char shellcode[]="aaaaaaaa\x05\x10\x40\x00";

 overflow(shellcode);

 //calc();

 return 0; 

}

第一步,先测试的填充,

  char shellcode[ ]=”aaaaaaaa1234”

  char str[4]="";

  strcpy(str,shellcode);

同样打开vc的调试,调用完overflow()函数后

利用缓存区漏洞执行shellcode


第一行为ebp的值为0x61616161,因为执行strcpy()时,shellcode的长度超过了str[]数组的长度,

原来在栈中的ebp被赋值为aaaaaasii码为61

ebp下面就是返回地址,已经覆盖为31323334

  因为返回地址被覆盖为0x31323334

  在下图可以看到计算机在读取eip的时候是从右往左读取每一个字节里的数据;

  F10一直执行下去,可以看到计算机尝试执行34333231处的指令,但此时是无效的指令,导致计算机报错。


利用缓存区漏洞执行shellcode

想要执行calc()函数,必须先找到该函数的地址

vc++6打开反汇编,直接查看编写的calc()地址,为0x0401005

利用缓存区漏洞执行shellcode

  经过第一步的测试,确定在返回地址之前需要填充8个字节,为什么要填充8个字节呢?

  因为局部变量char[ ]数组占4个字节,在局部变量前压入的ebp4个字节,才到返回地址,因此需要填充8个字节。

  读取地址时的顺序是从右往左的,因此把shellcode的地址按字节,反着填进去

  char shellc[ ]=“aaaaaaaa\x05\x10\x40\x00”

再调试程序(直接运行也可以),调用完overflow()函数后,计算器就弹出来了利用缓存区漏洞执行shellcode