【C语言】SCU安全项目2-BufBomb

2023-12-21 00:01
文章标签 语言 项目 安全 scu bufbomb

本文主要是介绍【C语言】SCU安全项目2-BufBomb,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

关键代码解读:

getxs()

getbuf()

test()

核心思路

具体操作1

具体操作2


前段时间忙于强网杯、英语4级和一些其他支线,有点摸不清头绪了,特别是qwb只有一个输出,太过坐牢,决定这个安全项目做完后就继续投身web的修炼,向C语言暂时说拜拜!!!

前置知识:

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++ = '\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 astable 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;
}

关键代码解读:

getxs()

这段代码定义了一个函数 getxs,它接受一个参数 dest,类型为 char*。函数的作用是从标准输入中读取一串十六进制数字,并将其转换为对应的字符序列,最后将结果存储在 dest 指向的内存空间中。

代码中使用了一个 while 循环来逐个读取输入的字符,直到遇到文件结束符(EOF)或换行符('\n')为止。在循环体内部,首先判断当前字符是否是一个十六进制数字,这由 isxdigit 函数来判断。

如果是十六进制数字,根据其值计算出对应的十进制数。如果当前已经读取了偶数个数字,则将该数字保存在 otherd 变量中,并将 even 标志位设置为 0,表示下一个数字是一个新的十六进制数字的开始。如果当前已经读取了奇数个数字,则将 otherd 乘以 16 并加上当前数字的值,将结果存储在 sp指向的内存空间中,sp指向地址增加一个字节,并将 even 标志位设置为 1。

循环结束后,将字符串的终止符 '\0' 存储在sp 指向的内存空间中,并返回指向 dest 的指针作为函数的返回值。

总而言之,这段代码实现了将输入的十六进制数字转换为字符序列的功能。

比如想输入deadbeef,则要输入efbeadde(小端存储,不解释)

getbuf()

 先是定义一个16个字节长度的字符型数组,讲数组首地址传入getxs函数,最后返回一个1。

这里就存在一些栈溢出的手段,暂按不表。

test()

定义了一个整形变量val,打印"Type Hex string",将val赋值为getbuf()的返回值(这里为1),最后将val的16进制型打印出。如果我们放任不管的话,无论输入什么值,因为无法改变getbuf()的返回值,所以回显一定如下。

但实验要求是让我们输出getbuf returned 0xdeadbeef,我们该怎么入手呢?

核心思路

以我浅薄的C语言能力应该无法修改getbuf的返回值为deadbeef,所以想到可以利用栈溢出的方式跳过val的赋值语句,直接运行第二个printf函数,而val的值也通过溢出覆盖为期望的deadbeef。

而buf[16]和getxs函数的配合恰好可以满足我们搞破坏的需求。

一行输入的内容超过了16字节,getxs并不会停止读入,此时的读入已经超出了数组范围(数组访问越界),从而实现覆写改变高地址处内容。

具体修改什么内容呢?

主要有两个部分:getbuf()函数的返回地址(从而直接跳转到第二个printf,不执行赋值操作)和val的初始值

具体操作1

设个断点开始调试,进入test函数

看寄存器状态,得知EBP地址为0019FDB4

看一眼 EBP地址里存的内容为0019FEE8(原原EBP地址,即test函数栈帧的原EBP地址——main函数的EBP地址,这里其实不太严谨,但为了后续方便表述所以用了两个原)

再看内存中val的地址,为0019FDAC

(内容是cccccccc说明val变量还未初始化)

看汇编代码得知val赋值语句和第二个printf的地址分别为004119D7,004119DA

 到此为止我们可以先用表格做个总结

 

具体操作2

跟进调试,进入getbuf函数,栈帧切换为getbuf

 看一眼寄存器,发现新EBP地址为0019FCD4

在内存里查看新BEP地址里存的值,发现为原EBP地址(即test函数栈帧EBP地址)0019FDB4

 看一下0019FDB8和0019FDBC里存的值,发现分别是val赋值语句的函数返回地址(004119D7)和原原EBP地址(0019FEE8)。

这里凡是相关EBP地址的内容我们都不能改,不然会报错,但是函数返回值可以任由我们操纵。

我们可以把0019FDB8的值由004119D7改为004119DA,这样就可以跳过赋值语句直接printf。

最后再看一眼buf数组的首地址为0019FCC0,因为是16个char,所以占四字节

 我们可以用表格模拟当前栈的分布情况

最终payload:

12345678 12345678 12345678 12345678 12345678 B4FD1900 DA194100 E8FE1900 12345678 12345678 12345678 12345679 12345680 12345681 12345682 12345683 12345684 12345685 12345686 12345687 12345688 12345689 12345690 12345691 12345692 12345693 12345694 12345695 12345696 12345697 12345698 12345699 12345700 12345701 12345702 12345703 12345704 12345705 12345706 12345707 12345708 12345709 12345710 12345711 12345712 12345713 12345714 12345715 12345716 12345717 12345718 12345719 12345720 12345721 12345722 12345723 12345724 12345725 12345726 efbeadde

 

没学过几天C语言的我都能做出,相信优秀的你们一定也没问题!!!!

再见,安全项目QWQ

这篇关于【C语言】SCU安全项目2-BufBomb的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/518002

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

SpringBoot通过main方法启动web项目实践

《SpringBoot通过main方法启动web项目实践》SpringBoot通过SpringApplication.run()启动Web项目,自动推断应用类型,加载初始化器与监听器,配置Spring... 目录1. 启动入口:SpringApplication.run()2. SpringApplicat

Go语言连接MySQL数据库执行基本的增删改查

《Go语言连接MySQL数据库执行基本的增删改查》在后端开发中,MySQL是最常用的关系型数据库之一,本文主要为大家详细介绍了如何使用Go连接MySQL数据库并执行基本的增删改查吧... 目录Go语言连接mysql数据库准备工作安装 MySQL 驱动代码实现运行结果注意事项Go语言执行基本的增删改查准备工作

Springboot项目构建时各种依赖详细介绍与依赖关系说明详解

《Springboot项目构建时各种依赖详细介绍与依赖关系说明详解》SpringBoot通过spring-boot-dependencies统一依赖版本管理,spring-boot-starter-w... 目录一、spring-boot-dependencies1.简介2. 内容概览3.核心内容结构4.

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Go语言使用net/http构建一个RESTful API的示例代码

《Go语言使用net/http构建一个RESTfulAPI的示例代码》Go的标准库net/http提供了构建Web服务所需的强大功能,虽然众多第三方框架(如Gin、Echo)已经封装了很多功能,但... 目录引言一、什么是 RESTful API?二、实战目标:用户信息管理 API三、代码实现1. 用户数据