SCU【C】程序设计基础期末安全项目lab2-Deadbeef-writeup(附题目&源码)

项目名称

和lab1一样,此题又是美国卡耐基梅隆大学的平时作业哈哈哈

Lab2-Deadbeef(本质:栈溢出攻击)

项目环境 

表1 项目开发环境

硬件环境

CPU

Intel Core i5,2.4 GHZ

内存

8G

操作系统

Windows

10,Professional版本

开发IDE

VS

2022版本

题面:

项目过程和结果的描述

大家都知道函数返回值要么是int要么是bool类型吧,然而这道题要我们的函数返回值是0xdeadbeef ???

怎么办?我的想法是栈溢出,暴力更改函数返回值。

源码:

/* 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;
//可以看到,不管输入什么到buf数组里面,函数都会返回1,而非0xdeadbeef.
}

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;
}

2023年12月31日&1月1日

核心思路:通过把buf数组填满,继续填满下面的值,栈溢出,一直到给val赋值的地方。暴力破解。    

下面展示思路:

  1. 对题面,程序进行解读,并详细做了注释

       项目要求是把栈溢出,强行更改函数返回值,输出0xdeadbeef。

       2.随便输一个值进去,输出0x1,

而通过源代码可知,

0x1=val的值=getbuf()的值,看到getbuf()函数返回值为1

直接修改函数返回值是对我来说比较困难的,所以我们想让val输出:0xdeadbeef,所以就想通过栈溢出的方式,让value=0xdeadbeef.

核心思路:通过把buf数组填满,继续填满下面的值,栈溢出,一直到给val赋值的地方。暴力破解。    

所以接下来,我们绘制了一个堆栈表:先通过调出寄存器找到栈底RBP地址,看内存得到RBP存的值,取地址:&value= 

名称

类型

&val

0x0073f7f0 {-858993460}

int *

等会我们就要尝试修改&val然后让val的值改变。

查看反汇编代码:call、调用getbuf()函数;

 dword ptr [val],eax把函数返回值赋值给val。

Printf的地址是00411A0A,我们要把00411A07(赋值函数地址)改变成00411A0A(printf的地址)

继续运行到getxs()函数:发现EBP变了

看看存了什么:

看看内存

看看buf数组的地址:

核心思路:通过把buf数组填满,继续填满下面的值,栈溢出,一直到给val赋值的地方。暴力破解。     

三角形部分为要填入程序的东西,中间空的内存值不能随便填,查内存,删空格(我写了一个程序删),原始数据如图,接下来是处理后的数据:

把这一堆输入程序,回显0xdeadbeef:

凌晨2:08,终于对了,我太感动了:

嗷嗷嗷,程序员小姐姐给大家准备了一个彩蛋

有人好奇为什么叫0xDeadbeef吗

刚看到这段代码时,我是比较吃惊的,作者竟然使用了一个英文单词 deadbeef 来定义宏常量!

我本来以为只是一位幽默的程序员的小玩笑,但后来查阅资料才知道,上图的这段代码竟是 C++ 的 hash_map 源码!而作者使用这个特殊的英文单词也是 “别有用心”。

deadbeef 的英文直译是死牛肉,但在编程领域中,它却有更深层的含义。给这个单词加上 0x 、再转换为大写,就得到了一个典型的十六进制数字:0xDEADBEEF。这个数字经常用来标识新分配但是还未初始化的内存;在嵌入式系统中,也常常用它来表示程序崩溃或者出现了死锁,比如运行在 32 位 PowerPC 处理器上的 IBM RS/6000 系统、Mac OS 系统。

那我不禁感到好奇,为什么选择了这样一个单词,而不是 “FishPi” 之类的(开个玩笑,16 进制最多到 F)。

到网上查了一会,得到的结论竟然是:没什么理由,它是一个 “魔数”!

所谓魔数,就是毫无理由、凭空出现、也不需要去解释其含义的常量。就是这么任性!

除了 deadbeef 外,我还百度到了很多魔数,比如:

  • 0xBAADF00D ("bad food" 烂饭) 被微软的 LocalAlloc(LMEM_FIXED)使用,在使用调试堆时指示未初始化的已分配堆内存
  • 0xDEADC0DE ("dead code" 死码) 在 OpenWRT 固件中用作标记,在静态固件的末尾表示要创建的 jffs2 文件系统的开始
  • 0xDEAD10CC ("dead lock" 死锁) 用于表示 iOS 系统的闪退报告

是不是感觉很神奇?也许这就是程序员的浪漫吧。

  • 34
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值