二进制安全虚拟机Protostar靶场(5)堆的简单介绍以及实战 heap0

本文主要是介绍二进制安全虚拟机Protostar靶场(5)堆的简单介绍以及实战 heap0,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

前言

这是一个系列文章,之前已经介绍过一些二进制安全的基础知识,这里就不过多重复提及,不熟悉的同学可以去看看我之前写的文章

什么是堆

堆是动态内存分配的区域,程序在运行时用来分配内存。它与栈不同,栈用于静态分配内存,并且具有固定的大小

程序使用如malloc、calloc、realloc等函数在堆上动态分配内存。当内存不再需要时,使用free函数释放。
例如:

int main(int argc, char **argv)
{struct data *d;d = malloc(sizeof(struct data));
}

通过malloc函数分配的堆地址:

在这里插入图片描述

接下来就用实战来讲解堆的运作机制

heap 0

在这里插入图片描述

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>struct data {  #定义了一个名为data的结构体char name[64];  #包含一个64字节大小的字符数组name
};struct fp {  #定义了一个名为fp的结构体int (*fp)();  #包含了一个函数指针fp
};void winner()  #自定义函数winner
{printf("level passed\n");  #输出level passed
}void nowinner()  #自定义函数nowinner
{printf("level has not been passed\n");  #输出level has not been passed
}int main(int argc, char **argv)  #主函数,从命令行获取参数
{struct data *d;  #声明了一个指向 struct data 类型结构体的指针 dstruct fp *f;  #声明了一个指向 struct fp 类型结构体的指针 fd = malloc(sizeof(struct data));   #给data结构体分配内存f = malloc(sizeof(struct fp));  #给fp结构体分配内存f->fp = nowinner;  #fp结构体中的函数指针初始化为指向nowinner函数printf("data is at %p, fp is at %p\n", d, f);  #输出data和fp结构体的内存地址strcpy(d->name, argv[1]);  #strcpy函数将命令行提供的第一个参数,复制到data结构体的name数组中f->fp();  #调用函数指针指向的函数nowinner}

漏洞发生在strcpy函数处,strcpy函数不会检查目标缓冲区的大小,如果我们提供的参数超过64字节,它将导致缓冲区溢出,如果发生了缓冲区溢出,并且覆盖了f->fp的值,那么可以使它指向winner函数,调用winner函数

我们先在第一个malloc函数调用的地方下一个断点,然后执行到断点处,来看看堆是怎么运行的

在这里插入图片描述

现在停在了malloc函数处,还没有执行该指令,可以看到程序空间里是没有堆的

在这里插入图片描述

输入n执行malloc函数,再次查看程序空间

在这里插入图片描述

可以看到,多出了一个heap空间,也就是堆,地址是0x804a000-0x806b000,我们查看这个堆空间里的数据

在这里插入图片描述

现在堆里只有两个数据,0x49-1,0x48是第一个mallco函数给我们分配的空间大小,为什么要减一呢,因为在这个堆中保存数据是,为了区分是否是空闲区域,都会在表示大小的值后面加一个1,+1了就说明当前空间已经被存放了数据,那这里为什么后面存放的数据都是0呢,是因为这个程序是从命令行参数里获取值然后保存的,我们运行程序时没有输入参数,所以这里都是0

在这里插入图片描述

在这里插入图片描述

name函数大小设置的是64字节,为什么程序给我们分配了72字节的空间,其实是这样算的

在这里插入图片描述

程序还将前面保留的四个字节空闲空间和本身表示大小的空间算进去了

而最后的0x20fb9,表示整个栈空间的大小,我们在程序执行strcpy函数的地方下一个断点,这个地方是程序将我们输入的值存入堆里的地方

在这里插入图片描述

我们重新运行程序,输入A,执行strcpy函数的指令,再在查看栈空间

在这里插入图片描述
在这里插入图片描述

程序已经将我们输入的8个A的十六进制值放入了堆,并且下面还有第二个mallco函数的空间

在这里插入图片描述

而这个0x8048478则是nowinner函数地址

在这里插入图片描述

前面说过,strcpy函数不会检查目标缓冲区的大小,如果我们提供的参数超过64字节,它将导致缓冲区溢出,如果发生了缓冲区溢出,并且覆盖了f->fp的值,那么可以使它指向winner函数,调用winner函数,我们输入76个字符就能完整覆盖nowinner函数地址,控制程序跳转的地址

python -c "print('A'*72 + 'B'*4)"

在这里插入图片描述

重新打开gdb,然后运行

在这里插入图片描述

这里程序提示跳转到了0x42424242的地址,也就是我们输入的BBBB,这时我们查看堆空间

在这里插入图片描述

我们已经将nowinner函数地址给覆盖了

在这里插入图片描述

我们将BBBB改为winner函数地址,就成功破解了程序

在这里插入图片描述

我们可以使用echo工具来输入不可见字符

./heap0 "`/bin/echo -ne "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x64\x84\x04\x08"`"

在这里插入图片描述

在这里插入图片描述

成功跳转到winner函数

堆是一个很难的部分,为了方便入门,这篇文章只是简单的介绍了一些堆的运作机制,之后的文章再慢慢介绍其他的机制

这篇关于二进制安全虚拟机Protostar靶场(5)堆的简单介绍以及实战 heap0的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

springboot简单集成Security配置的教程

《springboot简单集成Security配置的教程》:本文主要介绍springboot简单集成Security配置的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录集成Security安全框架引入依赖编写配置类WebSecurityConfig(自定义资源权限规则

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

Python实战之屏幕录制功能的实现

《Python实战之屏幕录制功能的实现》屏幕录制,即屏幕捕获,是指将计算机屏幕上的活动记录下来,生成视频文件,本文主要为大家介绍了如何使用Python实现这一功能,希望对大家有所帮助... 目录屏幕录制原理图像捕获音频捕获编码压缩输出保存完整的屏幕录制工具高级功能实时预览增加水印多平台支持屏幕录制原理屏幕

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程