Race Condition

Race Condition(竞争条件)是一种情形,在该情形下系统或者程序的输出受其他不可控事件的顺序或事件的影响。软件中的Race Condition通常出现在两个并发线程访问同一个共享资源。因而存在Race Condition漏洞的特权程序,通过对不可控事件施加影响,攻击者能够影响特权程序的输出。

常见的Race Condition漏洞有一下两类

  • Time-of-Check Time-of-Use

这是一种存在于软件中的Race Condition漏洞在软件开发中,Time-of-Check Time-of-Use(TOCTOU、TOCTTOU或TOC/TOU)是一类由竞态条件引起的软件bug,其中包括对系统的一部分(例如安全凭据)的状态检查和对检查结果的使用。顾名思义,这种漏洞由检查时间和使用时间之间的间隔产生,如下代码:

if(!access("/tmp/XYZ",W_OK)){f=open("/tmp/XYZ",O_WRITE);write_to_file(f);
}
else{fprintf(stderr,"Permission Denied");
}

若以上代码执行在setuid程序中(特权程序),便产生了race condition 漏洞。access()检查了real uid(真实用户)是否具有对/tmp/XYZ文件的写权限(W_OK),若real uid拥有该权限其返回0,open()系统调用同样也检查了用户的权限,但是不同于access()检查real uid,open()检查effective uid。在文件被检查和被使用(打开open)期间,存在一段窗口期,攻击者可以利用该窗口期进行攻击,例如在运行该程序前,攻击者在/tmp目录下创建一个属于自己的文件,此时可以通过access()检查,在指令流到达open()前,将该文件通过符号链接指向任意root权限文件(如/etc/passwd),便可以通过open()检查,打开原本只有root权限才可以打开的文件,最终实现对任意文件写的权限。

  • Dirty Cow

Dirty Cow漏洞2016年10月被披露,该漏洞影响了所有基于linux的操作系统,如android。Dirty Cow可以造成非常严重的后果:攻击者可以通过该漏洞获取root权限,可以修改任何受保护的文件,即使他对该文件只有可读权限。

了解DirtyCow漏洞,需要首先了解部分linux系统函数,如下

void mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset)

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。mmap在用户空间映射调用系统中作用很大。头文件 <sys/mman.h>

参数说明:

  • start:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址。

  • length:映射区的长度。//长度单位是 以字节为单位,不足一内存页按一内存页处理

  • prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算合理地组合在一起

    PROT_EXEC //页内容可以被执行

    PROT_READ //页内容可以被读取

    PROT_WRITE //页可以被写入

    PROT_NONE //页不可访问

  • flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体

    MAP_FIXED //使用指定的映射起始地址,如果由start和len参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上。

    MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到msync()或者munmap()被调用,文件实际上不会被更新。

    MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个。

    MAP_DENYWRITE //这个标志被忽略。

    MAP_EXECUTABLE //同上

    MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号。

    MAP_LOCKED //锁定映射区的页面,从而防止页面被交换出内存。

    MAP_GROWSDOWN //用于堆栈,告诉内核VM系统,映射区可以向下扩展。

    MAP_ANONYMOUS //匿名映射,映射区不与任何文件关联。

    MAP_ANON //MAP_ANONYMOUS的别称,不再被使用。

    MAP_FILE //兼容标志,被忽略。

    MAP_32BIT //将映射区放在进程地址空间的低2GB,MAP_FIXED指定时会被忽略。当前这个标志只在x86-64平台上得到支持。

    MAP_POPULATE //为文件映射通过预读的方式准备好页表。随后对映射区的访问不会被页违例阻塞。

    MAP_NONBLOCK //仅和MAP_POPULATE一起使用时才有意义。不执行预读,只为已存在于内存中的页面建立页表入口。

  • fd:有效的文件描述词。一般是由open()函数返回,其值也可以设置为-1,此时需要指定flags参数中的MAP_ANON,表明进行的是匿名映射。

  • off_toffset:被映射对象内容的起点。

  • 返回值:成功映射,则mmap()返回被映射区的指针,失败时返回MAP_FAILED

mmap有许多应用,

  1. 进程间通信:两个进程想彼此通信,可以使用mmap映射同一个文件到其各自的内存空间中,一个进程对其自己内存空间中该文件的映射进行改动,另一个进程可以立即感知(flags是MAP_SHARED),这种映射形如两个进程间的共享内存。
  2. 提高性能:通常我们访问一个文件使用read()和write()系统调用,这两个函数需要在内核态和用户态间转换和复制数据,速度不快,通过使用内存映射,使得访问一个文件变成内存操作(在用户态进行),这使得访问文件的时间花销大大减小。

一旦一个文件被映射到内存,我们可以通过对内存读写来实现访问文件的目的。文件的内容会被加载到物理内存上,且会被映射到调用mmap()函数的进程的虚拟内存中(通过页机制)。不同的进程映射同一文件,尽管他们各自将该文件映射到的虚拟内存不同,但是在物理内存上相同。

针对mmap()函数,flags字段在Dirty Cow漏洞中,需要尤其主要MAP_SHAREDMAP_PRIVATE

  • MAP_SHARED:任何进程对自己的虚拟内存的修改,都会影响到物理内存上的文件内容,因而所有其他映射了该文件的进程都可以观察到修改。
  • MAP_PRIVATE:文件被映射到调用mmap()的进程的私人内存中,对该内存的内容的修改都不会影响文件的原始内容。因为复制内容到私人内存中需要消耗时间,因而在linux内核中采用Copy on Write方法,即只有当文件内容需要修改时才会复制其内容到新的一块内存,所以即使flags是MAP_PRIVATE,若没有对文件进行写,则系统不会将该文件复制到新的私有内存。

例如如图(参考《Computer Security:A Hands-on Approach 》):

从该图可以看出,新创建的物理内存不再映射原始文件,因此对该内存的改动不会影响原始文件内容,MAP_PRIVATE实现的便是该功能。

int madvise(void *addr,size_t length,int advice)

madvise函数建议内核,在从 addr 指定的地址开始,长度等于 len 参数值的范围内,该区域的用户虚拟内存应遵循特定的使用模式。内核使用这些信息优化与指定范围关联的资源的处理和维护过程。如果使用 madvise() 函数的程序明确了解其内存访问模式,则使用此函数可以提高系统性能。

参数说明:

  • advice :指出给内核的建议,在Dirty Cow漏洞中需要尤其注意MADV_DONTNEED

当使用MADV_DONTNEED时,内核会释放指示的内存空间的资源,例如上图,进程2在write操作前,其页表指向①物理内存,在copy on write之后,其页表指向②物理内存,使用MADV_DONTNEED之后,其页表又重新指向物理内存①,物理内存②被释放。

write()函数可以向映射的内存写入数据,通常情况下普通用户对于只读文件是不能进行修改的,但是在linux中,若文件通过MADV_DONTNEED映射到内存,则允许内核通过调用wirte()帮助用户在只读的内存上写数据。

在了解以上知识以后,我们可以来了解Dirty Cow漏洞。针对copy on write类型的内存,write()系统调用需要经过三个重要步骤

  1. 复制映射内村
  2. 更新进程页表,使其指向新挂载的物理内存
  3. 向内存写数据

不幸的是,上述三个操作不是原子操作,因而存在dirty cow漏洞,在2和3操作之间,若使用madvise且第三个参数设置为MADV_DONTNEED,则第2步更新页表的操作便成为徒劳之举,页表重新指向原始内存,此时若再执行第3步,则数据便重新写入原始内存(不管这个文件映射到内存,是不是read-only,这个数据都会写入)。这样便导致任何普通用户都可以对root权限才可以更改的文件进行更改(只要该用户对该文件有可读权限)。

Race Condition漏洞相关推荐

  1. Django下防御Race Condition漏洞

    今天下午在v2ex上看到一个帖子,讲述自己因为忘记加分布式锁导致了公司的损失: 我曾在<从Pwnhub诞生聊Django安全编码>一文中描述过关于商城逻辑所涉及的安全问题,其中就包含并发漏 ...

  2. Race Condition Vulnerability Lab

    注:查看全文请关注作者,或点击前往:Race Condition Vulnerability Lab Race_Condition_Vulnerability_Lab 1 概述 ​ 本实验的学习目标是 ...

  3. Race Condition Vulnerability Lab操作系统实验

    Race Condition Vulnerability Lab操作系统实验 实验准备 Task 2.A target_process.sh attack_process.c 运行&结果 异常 ...

  4. java race condition_java多线程(一)Race Condition现象及产生的原因

    什么是Race Condition 首先,什么是Race Condition呢,Race Condition中文翻译是竞争条件,是指多个进程或者线程并发访问和操作同一数据且执行结果与访问发生的特定顺序 ...

  5. python 很高兴问题_Python 3.7曾有一个很老的GIL竞态条件(race condition),我是这么解决的...

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 作者:Victor Stinner 作为Python最关键的组成部分之一:GIL(全局解释器锁),我花了4 ...

  6. 什么是Race Condition?

    简介 race condition是多线程的应用程序中经常遇到的问题,本文章接下来会解释什么是race condition,如何检测到它们以及如何解决这类问题. Race condition 从定义来 ...

  7. 数据争用(data race) 和竞态条件(race condition)

    在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的.但在处理实际问题 ...

  8. java race condition_java 多线程下race condition问题

    这个问题的讨论来自内部的一个关于"多线程环境下使用Hashmap的安全问题"的讨论,HashMap多线程的问题之前已经提过一次,见之前的blog.本篇文章主要讨论多线程下race ...

  9. java race condition_Java中的Race condition和Critical section(译)

    Java中的Race condition和Critical section(译) race condition,即竞态,是一种可能发生于critical section中的特殊状态,critical ...

最新文章

  1. powerpoint打字慢
  2. java 用sevlet实现ip定位以及天气预报的功能
  3. .NET Core 中的 Generic Host快速使用指南
  4. 3650m5服务器内存选择 ibm_各大品牌服务器租用价格表明细(附详细表单)
  5. AOP 详解 、AOP 中通知类型 、AOP 两种实现方式(Schema-base 和 AspectJ)
  6. java jdk文档查询方法_查询Java JDK文档的元数据
  7. HDUOJ1043Eight 八数码问题可以构造解
  8. 消防给水及消火栓系统技术规范_对于高位消防水箱《消防给水及消火栓系统技术规范》是如何规定...
  9. enumerate取下标
  10. 【每日算法Day 65】你能顺利救出地下城里的公主吗?
  11. 获取div相对文档的位置
  12. ArcGIS与地理加权回归GWR【一】
  13. python数学建模|综合评价方法
  14. 三国历史上最不该被埋没诋毁的十大人才
  15. 薅羊毛的神器,悄悄介绍给你,低调使用!
  16. 双系统下卸载ubuntu 20.04再安装ubuntu 18.04的相关方法、软件以及出现ACPI Error错误和解决办法
  17. 微信搜索引擎中索引的分布式演进
  18. 戴尔服务器温度显示器,选择Dell UltraSharp 27的四大理由:有温度的科技更近人心...
  19. Python for Data Analysis:Numpy
  20. SpringBoot2核心技术最好的一篇文章——2. 核心技术

热门文章

  1. 全球股市总市值创新高 中国IT企业存在感渐强
  2. android usb单反相机,android mtp 获取单反相机中的照片
  3. 可视化工具--Plotly
  4. 500是什么php,HTTP 500,该怎么解决
  5. 马斯克为其五处房产申请6100万美元抵押贷款 每月还18万美元
  6. shell基础正则表达式
  7. k8s之vpa浅析(附带案例)
  8. 网络直播平台搭建一个直播间的礼物系统
  9. 华北电力大学计算机科学,华北电力大学计算机科学与技术系介绍
  10. Python——pymssql安装