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

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;
      else
	val = c - 'a' + 10;
      if (even) {
	otherd = val;
	even = 0;
      } else {
	*sp++ = otherd * 16 + val;
	even = 1;
      }
    }
  }
  *sp++ = '\0';
  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%x\n", 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

得到结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值