关于缓冲区溢出(Buffer Overflow)

接触黑客的同志们经常遇到,使用一些扫描工具扫描的时候,会得到一些缓冲区溢出的漏洞,但是怎么利用自己是一团雾水

网上很少有相关的工具,也很少有相关的文章,下面我们就说说这个“窿西”吧

 [蛋痛]文章丢失了一次,CSDN需要改进暂存机制

 

用VB的便宜不太明白“缓冲区”,当然这一点对熟悉API的朋友有一定改善,缓冲区就是一段内存,通俗这么讲吧。

我们给局部变量或者全局变量赋值时,变量的内存大小不可能是无限的,也很难做到自动适应(否则执行效率会很慢),当

赋值的数据大小超过变量的内存大小时,就会造成溢出,这歌溢出经常看到的描述是:不可意料的结果。

 

我们通过VC6编写一个简单的程序,来说明这个不可意料的结果吧。

// buffer overflow code by cto@renshenguo.com
#include <windows.h>
#include <stdio.h>

void fnHack()	//the host never expect to run this
{	printf("Your computer has been hacked!\n");	//example for hack action
	exit(0);	//exit process
}

int main()
{	int var[4] = {NULL};
	var[5] = (int)fnHack;
	printf("the host is running in normal way.\n");
	return 0;
}


简单吧!有人吐了,这个不就比我在学校时候的那个“helloworld”差不多嘛。不错,你可以这么理解。

在这里我们没有给main函数声明参数如 main(int argc, char **args),但是在WIN32运行时,仍然是传递这些参数的,在VC

下的DASM看不到这些,我们用OllyIce查看其编译后运行的反汇编代码:

函数的调用一般按照这样的方式:返回地址入栈,被调函数入栈,被调函数返回地址入栈,相关参数入栈……

可以看到程序有两个函数,当然这是Debug,OllyIce能够识别相关的源代码文件,如果是发布的Release版本,可能只看到地址

跳转执行,到后面“后进先出”依次出栈,返回原来地址继续执行……

那么,我们看一下,按照C/C++编译后的代码:(因为博客主要不再面向新手,怎么做我就不说了)

注意选中的那一行,本来main函数的返回地址入栈,再到我们声明的4个32位整型变量,其内存范围是【ebp】到【ebp-0x10】

注意堆栈的栈底是高地址,这个可以参考相关的说明,我对汇编代码注释一下,如图:

10:   int main()
11:   {   int var[4] = {NULL};
00401070   push        ebp				;基址指针ebp入栈,寄存器入栈主要是暂存其内容
00401071   mov         ebp,esp				;堆栈指针esp传至基址指针ebp
00401073   sub         esp,50h				;堆栈指针减少0x50,也就是初始化堆栈大小800字节
00401076   push        ebx				;基地址寄存器ebx入栈
00401077   push        esi				;源变址寄存器esi入栈
00401078   push        edi				;目的变址寄存器edi入栈
00401079   lea         edi,[ebp-50h]			;传送[ebp-0x50]偏移的32位内存值到目的变址edi
0040107C   mov         ecx,14h				;将0x14传送到计数寄存器ecx
00401081   mov         eax,0CCCCCCCCh			;将0xCCCCCCCC传送到累加器eax,VC初始化变量
00401086   rep stos    dword ptr [edi]			;填充[edi]指向的内存,串操作
00401088   mov         dword ptr [ebp-10h],0		;初始化[ebp-0x10]的值为0,“高高低低”,var[3] = NULL
0040108F   xor         eax,eax				;eax与自身异或运算,其实就是累加器eax清零
00401091   mov         dword ptr [ebp-0Ch],eax		;初始化[ebp-0x0C]的值为0,var[2] = NULL
00401094   mov         dword ptr [ebp-8],eax		;初始化[ebp-0x08]的值为0,var[1] = NULL
00401097   mov         dword ptr [ebp-4],eax		;初始化[ebp-0x04]的值为0,var[0] = NULL,内容涵盖到ebp,共4字节
12:       var[5] = (int)fnHack;				;注意下面这条,它将fnHack函数地址覆盖main函数返回地址
0040109A   mov         dword ptr [ebp+4],offset @ILT+5(fnHack) (0040100a)
13:       printf("the host is running in normal way.\n");
004010A1   push        offset string "the host is running in normal wa"... (00420044)
004010A6   call        printf (004012b0)
004010AB   add         esp,4
14:       return 0;
004010AE   xor         eax,eax
15:   }

执行到完毕的汇编代码如图

当函数执行到返回后总会调用__chkesp检查堆栈指针,其代码贴出来可以研究,不过跟我们关系不大

__chkesp:
00401330   jne         __chkesp+3 (00401333)
00401332   ret
00401333   push        ebp
00401334   mov         ebp,esp
00401336   sub         esp,0
00401339   push        eax
0040133A   push        edx
0040133B   push        ebx
0040133C   push        esi
0040133D   push        edi
0040133E   push        offset string "The value of ESP was not properl"... (004200a0)
00401343   push        offset string "" (0042009c)
00401348   push        2Ah
0040134A   push        offset string "i386\\chkesp.c" (0042008c)
0040134F   push        1
00401351   call        _CrtDbgReport (004046b0)
00401356   add         esp,14h
00401359   cmp         eax,1
0040135C   jne         __chkesp+2Fh (0040135f)
0040135E   int         3
0040135F   pop         edi
00401360   pop         esi
00401361   pop         ebx
00401362   pop         edx
00401363   pop         eax
00401364   mov         esp,ebp
00401366   pop         ebp
00401367   ret
00401368   int         3

后面它将跳到fnHack函数的地址,而不是main函数的调用处执行fnHack函数,执行结果如图:

这就是缓冲区溢出造成所谓的不可预料的结果,所带来的执行任意代码……

 

一般来说,黑客才回造成这样的结果,而本地溢出没有什么特别大的入侵意义,而远程溢出则还要学习shellcode方面的东西,这个以后再说吧

缓冲区溢出离我们其实并不远,往往我们看到的更多的情况是这样:

很多软件即使全面测试无数次,在特定的条件下,也会造成溢出,不测试的就更多了……

但是这种溢出不是人为的,也就是说溢出后执行的代码是不确定的,最后往往造成内存访问冲突而被操作系统终止。

 

好了,就说这么多吧!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值