首页 > 编程知识 正文

缓冲区溢出攻击实验(C语言 | 汇编语言 | 输出deadbeef)

时间:2023-05-03 05:28:49 阅读:211945 作者:2110

缓冲区溢出攻击实验(输出deadbeef) C语言题目源码尝试运行程序观察 分析栈内部情况决定使用栈溢出 实施使用vs2019打开反汇编使用反汇编构造payload得到结果

C语言题目源码 /* bufbomb.c * * Bomb program that is solved using a buffer overflow attack * * program for CS:APP problem 3.38 * * used for CS 202 HW 8 part 2 * * compile using * gcc -g -O2 -Os -o bufbomb bufbomb.c */#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; elseval = c - 'a' + 10; if (even) {otherd = val;even = 0; } else {*sp++ = otherd * 16 + val;even = 1; } } } *sp++ = ''; return dest;}int getbuf(){ char buf[16]; getxs(buf); return 1;}void test(){ int val; printf("Type Hex string:"); val = getbuf(); printf("getbuf returned 0x%xn", val);}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 *) malloc(offset); *space = 0; /* So that don't get complaint of unused variable */ test(); return 0;} 尝试 运行程序

我们可以看出,无论我们输入什么字符串,我们得到的结果只有0x1

原因在于getbuf函数

所以我们想到需要更改代码按顺序执行的方式,在某一个地方进行跳转,同时对栈中的内容进行覆盖,将getbuf函数的return更改到别处

观察

经过一番对于函数代码的考查,我们发现可以更改其getbuf的返回地址,使其返回到printf函数式的地方 查看调用getbuf函数时的汇编代码,我们可以做出如下的返回地址变换

分析 栈内部情况

我们想象栈getbuf的栈的内部情况

我们知道对于整个程序来说,函数的堆栈情况大致如下:

同时,对于单个函数来说,其堆栈情况应该是

决定使用栈溢出

所以我们想到,要实现程序执行顺序的跳转,需要使用栈溢出。

将char buf[16]的值进行扩写,覆盖掉栈中之前的ebp变量和返回地址。

实施 使用vs2019打开反汇编

注:vs2019针对C语言的汇编会有一些很奇怪的安全限制,我们需要对一些设置进行更改,使我们可以获得比较直观的汇编代码

1) 调试 -> 调试属性 -> C/C++ -> 代码生成

2) 调试 -> 调试属性 -> 链接器 -> 高级

这样保证我们可以使用到对直观的汇编代码

使用反汇编

断点设置在test()函数位置。

从前一节我们知道,我们需要把getbuf函数的返回地址进行修改,之前的返回地址是在004119C5,现在经过了我们的修改后,返回地址应该被我们修改在004119CC的位置

原因如下:

1) 当我们堆栈溢出时,我们对返回地址进行覆盖的同时,也同时输入了我们想要的程序输出,这个输出的地址在返回地址之上。(比如我输入了deadbeef,那么这个deadbeef的地址就是在栈中储存返回地址的前一个地址)

2) 当我们跳转到004119CC后,程序执行push offset string,下一步执行的是call _printf操作,也就是说此时我们覆盖的deadbeef参数此时就是覆盖了printf函数的第一个变量(也就是04119CB中push的eax)

构造payload

开始构造我们要输入的值

我们打开内存界面

可以很清晰地观察到我们的getbuf的栈中的结构是个什么样子

所以我们构造payload:

aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa 48 fe 19 00 cc 19 41 00 ef be ad de

得到结果

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。