【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

相关文章

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

Go语言中Recover机制的使用

《Go语言中Recover机制的使用》Go语言的recover机制通过defer函数捕获panic,实现异常恢复与程序稳定性,具有一定的参考价值,感兴趣的可以了解一下... 目录引言Recover 的基本概念基本代码示例简单的 Recover 示例嵌套函数中的 Recover项目场景中的应用Web 服务器中

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv