attack xv6

news2025/1/24 14:52:08

思路

被这个实验折磨了两天,可能是2024新出的一个实验内容,网上资料少,参考了一篇仅有的博客,吭哧吭哧分析出来了个大概吧…在此记录一下,以便帮助有需要的人。

attack xv6的ans只有几行代码,根据实验描述,大概能猜到是secret程序结束之后,attack程序复用了它的物理内存,然后读取之前写入内存中的密码。难点在于我们如何定位到那段内存。

在开始之前直接先给出ans,可以看到代码是很简单的:

#include "kernel/types.h"
#include "kernel/fcntl.h"
#include "user/user.h"
#include "kernel/riscv.h"

int
main(int argc, char *argv[])
{
  // your code here.  you should write the secret to fd 2 using write
  // (e.g., write(2, secret, 8)
  char *end = sbrk(17*PGSIZE);
  end += 16 * PGSIZE;
  write(2, end+32, 8);
  exit(1);
}

下面说说实验思路,实验目的是找到被复用的物理内存,而内核的物理内存使用栈式链表管理(kalloc.c),secret程序通过kalloc从栈顶取内存页来使用,程序结束后通过kfree将这些内存页放回栈顶。到attack运行的时候同样使用kalloc从栈顶取内存页,因此就给了attack复用物理内存的机会。

值得注意的是,secret分配内存时这些页的出栈顺序,不一定与attack分配内存时的出栈顺序相同,比如secret分配页的顺序为1,2,3,归还的顺序为2,3,1,那么此时栈顶到栈底的页分别为1,3,2,当attack来分配的时候,拿到页的顺序就是1,3,2。因此核心在于分析程序运行时物理内存页的分配以及回收顺序,才能知道attack应该到哪块内存中获取密码。

fork secret

我们从attacktest中的第一个fork开始分析。

image-20241218210711222

fork调用了allocproc来创建proc,allocproc中首次使用了kallocp->trapframe分配一页物理页。

image-20241218210834186

接着allocproc调用proc_pagetable创建页表,其中,先调用uvmcreate使用kalloc为根页表分配一页:

image-20241218211533731

然后为trampolinep->trapframe建立映射,这两页在最虚拟内存的最高地址处,处于同一个三级页目录(xv6使用sv39,即三级页表),因此又kalloc了两页,分别对应一页二级页表、一页三级页表:

image-20241218211559339

因此allocproc一共创建了4页(trapframe、三级页表)。

回到fork中,由于此时xv6的fork还没实现copy on write特性,因此需要把父进程用户内存中的内容(用户内存即stack、heap这些低地址内存,不包括trapframe、trampoline)使用uvmcopy全部复制到子进程中。此时父进程用户内存占用此时为4页,因此子进程也复制了这4页进来,由于这4页位于虚拟内存中的低地址,其二级三级页表与trapframe/trampoline的都不一样,所以还会创建两页分别用于二级三级页表,一共kalloc了4+2=6页(为什么是4页具体原因在后面分析exec时会揭晓)。

综上,fork一共分配了4+6=10页。

exec secret

然后就是执行exec

image-20241218212525915

exec的实现中,会使用proc_pagetable创建新的页表来替换旧页表(这个也好理解,因为exec目的就是替换整个程序镜像,相当于从头开始执行一个新的程序,之前程序的相关内容全部丢弃)。根据之前的分析,proc_pagetable会分配3页。

接着,exec遍历elf文件的program header,将所有LOAD段加载进内存中。具体是通过uvmalloc分配物理内存,loadseg将段加载进内存。xv6程序的elf文件包含两个LOAD段,data段和text段,可以通过readelf看一下:

image-20241218213350943

这两个段分别加载到虚拟内存的第0页和第1页中。同理,这两页属于低地址的用户内存,需要2页(二级页表、三级页表)+2页来分别存放这两个段。

接着,exec为用户栈分配内存:

image-20241218213731624

这里的USERSTACK值为1,因为xv6固定用户栈大小为一页,后面的+1多出的一页用于page guard,便于栈溢出的处理。另外栈是紧挨着data段和text段之后分配的,他们属于同一个三级页表,不需要额外分配页表,因此栈分配一共分配了2页

exec的最后,还调用了proc_freepagetable来释放旧页表和旧用户内存:

image-20241218214350688s’d’s

其中的两个uvmunmap释放pte映射(避免后续uvmfree的时候意外释放trampoline和trapframe的物理内存),并不释放物理页,因为trampoline是整个操作系统共享的不需要释放,而trapframe是用户态和内核态转换时的用到的存储区域,十分重要,同样不会释放(关于trapframe和trampoline的详细说明可以查阅book-riscv)。最后的uvmfree则是释放旧页表占用的内存(5页)以及用户内存(4页),共9页。

综上,exec一共分配了3+4+2=9页,然后又释放了9页。

secret

然后就是执行secret程序了,使用了sbrk分配了32页内存,然后在第10页写入数据。

至此,经过forkexecsbrk之后,secret程序一共占用了10+32=42页

wait secret

attacktest程序调用wait(0),获取到secret的proc,调用freeproc释放其内存:

image-20241218215540939

下面我们重点关注释放内存的顺序,即文章开头思路中说到的kfree“入栈”。

image-20241218215720587

首先是释放一页trapframe。然后进入proc_freepagetable中的uvmfree

image-20241218215822928

先调用uvmunmap从低到高地址释放用户内存,根据之前内存分配的分析,释放顺序为data段+text段、用户栈+page guard、32页堆内存(每页从低地址页到高地址页依次释放/入栈),共36页

最后释放页表,共5页

此时我们可以知道,kmem维护的空闲链表栈,从栈顶开始的页依次为:5页页表、第32页堆内存、第31页堆内存、…、第10页堆内存(密码所在的页)、…、第1页堆内存、page guard…

attack

attacktest运行attack的方式和运行secret的一样,都是通过fork+exec,直接拿前面的分析结果,我们知道在开始执行attack程序之前,fork分了配10页,exec分配9页又释放了9页,其中fork分配的10页来自于5页页表、第32 ~ 28页堆内存,exec分配的9页来自第27 ~ 19页堆内存,后面又释放了9页回栈顶(因为我们要的第10页堆内存还在下面,所以我们不用关心这9页分别是什么),此时栈顶开始的页依次为:9页、第18页堆内存、…、第10页堆内存、…,通过用手指头数一下发现,我们只需要分配17页,密码就在最后一页中。

参考

https://blog.csdn.net/weixin_42543071/article/details/143351746

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262220.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink CDC实时同步mysql数据

官方参考资料: https://nightlies.apache.org/flink/flink-cdc-docs-master/zh/docs/connectors/flink-sources/mysql-cdc/ Apache Flink 的 Change Data Capture (CDC) 是一种用于捕获数据库变化(如插入、更新和删除操作)的技术。Flink CDC…

eclipse 如何设置项目、不同类型文件的 utf8 编码

编码问题一直是软件开发中让人头疼的小细节,尤其是团队协作中,若编码格式不统一,乱码问题便会频繁出现。那么如何在 Eclipse 中统一设置项目和文件的 UTF-8 编码,避免因编码问题造成不必要的困扰呢?今天,我…

Unity中触发器Trigger无法被射线检测到的问题

今天在做项目的时候发现,同一个物体,当他是碰撞器的时候,可以被射线检测到. 但是当他变成触发器的时候,射线就检测不到了??? 本来以为就是这样的,但是查了资料发现并没有这样的限制,触发器也是可以正常被射线检测的 到处查资料都没有发现问题,后来发现是下面这个设置不知道…

第一个AJAX调用XMLHttpRequest

第一个AJAX调用XMLHttpRequest 创建对象,用于浏览器和服务器的通信,不需要刷新浏览器 const request new XMLHttpRequest();通过GET请求方式在API中请求数据 request.open(GET, https://restcountries.com/v3.1/name/Russia);注:我这里的…

群落生态学研究进展】Hmsc包开展单物种和多物种分析的技术细节及Hmsc包的实际应用

联合物种分布模型(Joint Species Distribution Modelling,JSDM)在生态学领域,特别是群落生态学中发展最为迅速,它在分析和解读群落生态数据的革命性和独特视角使其受到广大国内外学者的关注。在学界不同研究团队研发出…

如何在 Apifox 中发布多语言的 API 文档?

“API 文档是开发协作的桥梁,而多语言支持则让这座桥梁跨越更多的技术边界。使用 Apifox,不仅可以快速生成 API 文档,还能轻松实现多语言的支持与发布。今天,我们一起来探索 Apifox 在多语言文档发布中的最佳实践!” …

华为云检查服务器状态

VNC方式登录云服务器正常,但无法通过远程桌面连接方式登录云服务器时,推荐您按照以下思路排查问题。 以下排查思路根据原因的出现概率进行排序,建议您从高频率原因往低频率原因排查,从而帮助您快速找到问题的原因。 如果解决完某…

leetcode212. 单词搜索 II

给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。 单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一…

无缝钢管内表面缺陷检测的自强化感知协调网络

摘要 无缝钢管是重要的工业材料。然而,无缝钢管中的内表面缺陷检测具有挑战性,并且会显著影响无缝钢管的性能和寿命。现有的检测方法是劳动强度大的,并且检测结果的可视化程度低。因此,本文提出了一种新型的管道内表面缺陷螺旋式全…

Kioptrix靶场渗透--level1.1

目录 环境搭建 镜像包下载 下载后解压,并修改配置 开始渗透 获取IP 获取具体服务 尝试sql注入 尝试命令执行 反弹shell 提权 查看Linux的内核版本 下载脚本 将脚本上传至靶机 编译脚本 编译后执行 第一个脚本失败,再找个脚本 使用cat /…

AI技术在演示文稿制作中的应用一键生成PPT

在快节奏的现代工作环境中,时间就是金钱。为了提高工作效率,许多专业人士都在寻找能够快速生成演示文稿(PPT)的工具。本文将探讨AI技术如何帮助用户自动生成演示文稿,从文案撰写到排版,最终输出成品&#x…

中国当代印章孙溟㠭篆刻锤凿印《无题Ⅵ》

孙溟㠭篆刻锤凿印《无题Ⅵ》 孙溟㠭篆刻锤凿印《无题Ⅵ》 此作品有人说看到了流星雨,有人说看到了战争,有人说看到了疾风暴雨,有人说看到了烟花庆新年,有人说是天气突变下的冰雹……!至于是什么仁者见仁智者见智。 孙…

游戏引擎学习第54天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们现在正专注于在游戏世界中放置小实体来代表所有的墙。这些实体围绕着世界的每个边缘。我们有活跃的实体,这些实体位于玩家的视野中,频繁更新,而那些离玩家较远的实体则以较低的频率运…

STM32F407ZGT6-UCOSIII笔记2:UCOSIII任务创建实验-Printf 函数卡住 UCOSIII 系统问题解决

今日简单编写熟悉一下UCOSIII系统的任务创建代码,理解一下OS系统: 并发现以及解决了 Printf 函数卡住 UCOSIII 系统问题解决 文章提供测试代码讲解、完整工程下载、测试效果图 目录 文件结构解释: 任务函数文件: 目前各个文件任…

linux centos 7 安装 mongodb7

MongoDB 是一个基于文档的 NoSQL 数据库。 MongoDB 是一个文档型数据库,数据以类似 JSON 的文档形式存储。 MongoDB 的设计理念是为了应对大数据量、高性能和灵活性需求。 MongoDB使用集合(Collections)来组织文档(Documents&a…

kafka的处理的一些问题 消费延迟

kafka的处理的一些问题 消费者客户端不但没有背压而且内存充足,但产生的消费延迟越来越大在Kafka的Leader副本宕机时 消费者客户端不但没有背压而且内存充足,但产生的消费延迟越来越大 比如我们这个kakfa集群一共有3个Broker节点 TOp1有5个分区&#xf…

计算机网络技术基础:3.计算机网络的拓扑结构

网络拓扑结构是指用传输媒体互连各种设备的物理布局,即用什么方式把网络中的计算机等设备连接起来。将工作站、服务站等网络设备抽象为点,称为“节点”;将通信线路抽象为线,称为“链路”。由节点和链路构成的抽象结构就是网络拓扑…

Vue3源码笔记阅读1——Ref响应式原理

本专栏主要用于记录自己的阅读源码的过程,希望能够加深自己学习印象,也欢迎读者可以帮忙完善。接下来每一篇都会从定义、运用两个层面来进行解析 定义 运用 例子:模板中访问ref(1) <template><div>{{str}}</div> </template> <script> impo…

STM32F407寄存器点灯

背景描述&#xff1a; 最近用32开发遇到问题不得不看寄存器了&#xff0c;就回顾了一下寄存器手册的查看方式和寄存器的使用方法&#xff1b; 上一次这么细致的记录还是在刚学习STM32的时候&#xff0c;之前觉得看寄存器手册以及配置寄存器是有点难度的事情&#xff0c;现在回头…

2024年12月11日Github流行趋势

项目名称&#xff1a;maigret 项目维护者&#xff1a;soxoj, kustermariocoding, dependabot, fen0s, cyb3rk0tik项目介绍&#xff1a;通过用户名从数千个站点收集个人档案信息的工具。项目star数&#xff1a;12,055项目fork数&#xff1a;870 项目名称&#xff1a;uv 项目维护…