这几天一直在做csapp里面的3.38,他是让你自己实现一个缓冲区溢出程序.代码如下:
/* Bomb program that is solved using a buffer overflow attack */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
/* Like gets, except that characters are typed as pairs of hex digits.
Nondigit characters are ignored. Stops when encounters newline */
char *getxs(char *dest)
{
int c;
int even = 1; /* Have read even number of digits */
int otherd = 0; /* Other hex digit of pair */
char *sp = dest;
while ((c = getchar()) != EOF && c != '\n') {
if (isxdigit(c)) {
int val;
if ('0' <= c && c <= '9')
val = c - '0';
else if ('A' <= c && c <= 'F')
val = c - 'A' + 10;
else
val = c - 'a' + 10;
if (even) {
otherd = val;
even = 0;
} else {
*sp++ = otherd * 16 + val;
even = 1;
}
}
}
*sp++ = '\0';
return dest;
}
/* $begin getbuf-c */
int getbuf()
{
char buf[12];
getxs(buf);
return 1;
}
void test()
{
int val;
printf("Type Hex string:");
val = getbuf();
printf("getbuf returned 0x%x\n", val);
}
/* $end getbuf-c */
int main()
{
int buf[16];
/* This little hack is an attempt to get the stack to be in a
stable position
*/
int offset = (((int) buf) & 0xFFF);
int *space = (int *) alloca(offset);
*space = 0; /* So that don't get complaint of unused variable */
test();
return 0;
}
这边有几个概念要说一下:
1 在一个函数的栈桢里面,有两个指针,一个是栈指针(存储在%esp),一个是桢指针(存储在%ebp),其中栈指针指向的是栈顶,也就是说它会不断变化,而桢指针指向的是栈低,他是固定的。而栈指针和桢指针之间方得就是,不能存储在寄存器中的一些局部变量.
2所有的寄存器被所有的函数所共享,因此这里IA32对寄存器去有了一个规定,那就是:
%eax,%edx,%ecx是调用者寄存器,%ebx,%edi,%esi是被调用者寄存器,举个例子,假设方法p调用q,则q可以随便覆盖%eax,%edx,%ecx中的而不会破坏p的使用,但是如果他要使用%ebx,%edi,%esi中的值,则必须先将这些寄存器进栈,谈后才能操作.
更详细的有关过程调用的介绍,可以自己去看csapp的第三章.
题目是让你输入一个16进制字符串,从而能使 getbuf返回0xdeadbeef.这个要实现的话,之要实现下面几个目标就可以了:
覆盖函数的返回地址(也就是test调用getbuf时压入栈的地址)。使这个地址指向你自己的执行代码,而你自己的执行代码所要实现的就是就是改变函数的返回值,修改完返回值之后,你要将返回你本该返回的地址,(这边就是函数test的地址)。
这边先看一下,函数调用结束时的汇编代码:
leave
ret
leave指令相当于
movl %ebp,%esp
popl %ebp
也就是说当函数要返回时,会先将栈指针指向桢指针所指的内容,也就是说删除掉了局部变量之类的东西,这时再弹出%ebp,这时的栈顶,也就是调用这个函数的函数地址了,而ret指令则就是弹出这个地址,然后跳转到这个地址。
知道了这个,我们就很容易构造我们的目标程序了,我们的目标程序也就是先将0xdeadbeef付给%eax,然后再将函数test的地址入栈,最后ret.这边假设我们的test的地址是$0x048503bf.
mov $0xdeadbeef ,%eax
push $0x048503bf
ret
然后我们将这段代码先编译,然后反汇编,就能得到我们的目标代码.
所以,我们这边的构造的字符串的结构式这样的:
(目标代码)(当test调用getbuf时的%ebp的内容)(我们的目标代码的地址,也就是我们构造的这个字符串buf的地址,也就是%ebp的地址减去12)
这边为什么没有给出完整的程序呢,这是因为,在linux2.6下他对栈有保护,它使用一种叫做ExecShield的技术,简而言之就是他会使对堆栈内的代码不可执行,并且每次执行的时候会随即的改变堆栈的地址.因此如果我们要尝试缓冲区溢出的话,使用gdb调试,他会报一个segmentation fault的错误..
有关ExecShield的详细信息,可以看这个:
http://www.linuxgoo.com/bbs/archiver/58645.html
虽然没有实践成功,可是自己的理解应该是没有什么错误的.
分享到:
相关推荐
1.理解缓冲区溢出漏洞的定义和危害 2.理解 MS05-039 漏洞的原理 3.掌握利用 MS05-039 漏洞的入侵过程 4.掌握针对 MS05-039 漏洞的防范措施 缓冲区溢出攻击的教学重点和难点包括: 1.MS05-039 漏洞原理 2.MS05-039 ...
1. **缓冲区与内存管理**:了解内存分配、释放以及栈和堆内存的工作原理,这是理解缓冲区溢出的基础。 2. **溢出类型**:包括栈溢出、堆溢出、格式字符串溢出等,每种类型都有其独特的触发机制和利用方式。 3. **...
- 理解缓冲区溢出的原理及其危害。 - 掌握检测和利用缓冲区溢出的方法。 - 学习如何预防和修复缓冲区溢出漏洞。 - 提高安全编程意识,为编写更安全的软件打下基础。 本实验是学习网络安全和软件安全的重要环节,...
除了理论知识,这本教程可能还包含了一些实践性的练习,比如编写简单的溢出示例,使用调试工具(如GDB)来观察溢出过程,甚至可能涉及到逆向工程的基本概念,以帮助读者从实践角度理解缓冲区溢出。 总的来说,《Q版...
**安全编程之缓冲区溢出** ...通过深入理解缓冲区溢出,开发者可以编写更安全的代码,避免潜在的安全风险,保护用户数据和系统的稳定性。同时,对于安全研究人员而言,理解溢出机制也是发现和修复漏洞的关键。
**正文** ...通过学习这个课件,你将能够理解缓冲区溢出的概念,识别潜在的溢出风险,并掌握预防缓冲区溢出的策略,从而提高软件的安全性。对于IT从业者来说,了解并能处理这类安全问题是至关重要的。
本书首先介绍了基础的计算机内存结构和C语言编程知识,这是理解缓冲区溢出现象的关键。书中详细解释了栈、堆、静态和全局变量等内存区域的工作原理,以及如何通过指针操作来访问和修改内存。 接下来,书中深入剖析...
**C++缓冲区溢出实验** 在编程领域,特别是系统安全和逆向工程中,缓冲区溢出是一...通过这次实验,参与者不仅可以理解缓冲区溢出的基本原理,还能掌握利用和防范溢出漏洞的技巧,这对于提升C++编程的安全性至关重要。
通过这个Q版缓冲区溢出教程,读者不仅可以深入理解缓冲区溢出的概念,还能掌握预防和修复这类漏洞的技能,这对于提高软件的安全性具有重要意义。在学习过程中,结合源代码进行实践,可以更直观地看到理论与实际的...
- **基础知识**:包括C语言中的数组、指针、内存管理等,这些都是理解缓冲区溢出的基础。 - **栈溢出原理**:解释了如何通过栈上的缓冲区溢出来控制程序执行流程。 - **Shellcode的构造**:讲解如何编写和编码...
通过阅读《Q版缓冲区溢出教程.doc》,读者不仅可以理解缓冲区溢出的概念,还能掌握相关的攻防技巧,提升对网络安全的理解,这对于软件开发者和网络安全爱好者来说都是非常宝贵的知识。同时,文档的Q版风格也使得学习...
在计算机系统实验中,我们通常会通过编写和分析代码来理解缓冲区溢出的工作原理。"buflab-handout.tar" 文件可能包含了实验指导文档和相关工具,帮助学生模拟和检测溢出情况。实验可能包括以下几个步骤: 1. **理解...
通过对C语言中特定函数的分析,我们可以更好地理解缓冲区溢出的机制,并采取适当的措施来防止这类漏洞。通过使用安全函数、输入验证、编译器安全特性和安全编码实践,可以有效减少缓冲区溢出的风险,提高程序的安全...
**缓冲区溢出基础** 缓冲区溢出是计算机编程中的一种常见安全问题,尤其是在...理解缓冲区溢出并采取适当的预防措施对于保护软件和系统的安全性至关重要。开发者应时刻警惕这一潜在的安全威胁,并采取有效的防御手段。
总的来说,这个教程将帮助学习者全面理解缓冲区溢出的机制,掌握C语言和汇编中的关键知识点,熟悉相关工具的使用,提高安全编程的意识,对于软件开发人员和网络安全爱好者来说是一份宝贵的资源。通过深入学习和实践...
首先,我们需要理解缓冲区溢出的基本概念。缓冲区是程序中用于临时存储数据的一段内存空间,通常具有固定的长度。当程序员没有正确地检查输入数据的长度或者未对缓冲区的边界进行有效控制时,就可能发生溢出。在...
经典缓冲区溢出攻击源代码,包含详细的分析文档,不可多得的 <br>资源,对于理解缓冲区溢出原理以及汇编语言有很好的帮助。《 <br>深入理解计算机系统》一书中使用到的例子,我将这个例子进行 <br>了详细的...