内容简介:Linux内核中的漏洞并不罕见。现在Linux已经大约有2019年5月8日,美国国家漏洞数据库(NVD)公布了Linux内核漏洞(
0x00 前言
Linux内核中的漏洞并不罕见。现在 Linux 已经大约有 2600万行代码 ,仅在2018年就添加了3,385,121行代码,移除了2,512,040行代码,。在这种量级的代码复杂度下很难不存在漏洞。然而有些漏洞还是比较少见,比如未授权远程代码执行(RCE)漏洞:这是每个系统管理员都不想看到的关键问题。
2019年5月8日,美国国家漏洞数据库(NVD)公布了Linux内核漏洞( CVE-2019-11815 )的详细细节,通用漏洞评分系统(CVSS)3.0的基本评分为8.1。漏洞细节包括:可以通过“网络”进行攻击、无需特权、能获得管理员级别的代码执行,该漏洞在机密性、完整性和可用性(CIA)方面影响程度都“较高”。如果只看该评分,这似乎是非常严重的问题。然而在评估漏洞影响范围方面,我们不应当只参考CVSS基础评分所给出攻击方式、权限级别以及CIA标准。
CVSS 3基础评分的一个因素就是攻击复杂度,该漏洞在这方面也获得了“高”评级。这意味着如果想成功利用漏洞,攻击者需要依赖一些难以满足的特定条件。根据 CVSS 3.0标准 ,该评级意味着“漏洞成功利用依赖于攻击者无法控制的一些条件”以及“漏洞无法随意利用,需要攻击者针对漏洞组件在前期准备和执行方面投入较多精力,才可能成功攻击”。
详细查看漏洞细节后,我们就可以知道为什么这个评分在技术层面上是正确的(特别是要考虑到攻击复杂度方面因素),但并不能完全代表企业和用户所面临的实际风险。
0x01 漏洞分析
根据NVD的描述,该漏洞存在于“内核版本低于5.0.8之前的Linux发行版,具体位于 net/rds/tcp.c
的 rds_tcp_kill_sock
函数中”,并且存在“竞争条件,可以导致uaf(释放后使用)问题,与net命名空间清理有关”。从代码角度而言,这个漏洞描述非常准确且简洁,但由于提到TCP这个词,并且缺乏关键信息,这可能容易因此不必要的警报。
该漏洞涉及到的第一个组件是RDS(Reliable Datagram Sockets),这是由Oracle开发的一个套接字接口和协议,方便单个套接字向大量不同的端点发送和接受数据。当TCP作为底层传输协议时,该漏洞就涉及到RDS:RDS头中的应用数据被封装后通过TCP传输,通常会发送到16385端口,然后解封装并传输至RDS套接字。
除了Oracle的官方文档和维基百科上非常简短的一个页面之外,我们找不到关于RDS和典型用法的太多资料。由于该协议存在模糊性,并且之前还存在本地提权漏洞,因此多年来大多数Linux发行版(如Ubuntu)已经将与RDS有关的内核模块列入 黑名单 中,这样也迅速将这类漏洞的潜在风险控制在一定范围内。
那么当 rds
及 rds_tcp
内核模块处于启用状态会出现什么情况呢?
当在TCP协议上使用RDS时,底层TCP传输完全由内核来控制。这意味着当客户端建立一个新的RDS套接字时,内核就会在 tcp_connect.c
中通过 rds_tcp_conn_path_connect()
打开TCP套接字,而该函数由 threads.c
中的 rds_connect_worker()
线程函数负责调用。
图1. threads.c
中的 rds_connect_worker()
调用 rds_tcp_conn_path_connect()
当客户端的底层TCP套接字持续无法连接时,就会出现与RDS有关的问题。当TCP的 connect()
失败时,系统就会调用 rds_tcp_restore_callbacks()
函数,将 rds_tcp_connection
结构中的 t_sock
指针设置为 NULL
,这是非常合理的行为。
图2. rds_tcp_conn_path_connect()
调用 rds_tcp_restore_callbacks()
图3. 在 rds_tcp_restore_callbacks()
中将 t_sock
设置为 NULL
当引入第二个漏洞组件时就会出现问题:网络命名空间(network namespaces)。网络命名空间可以为指定的命名空间使用独立的一组接口和路由表,其中传统意义上整个操作系统与其他每个进程共享相同的接口和路由表。Docker等平台会使用这个命名空间功能为 容器 提供网络隔离机制。
当 rds_tcp_init()
初始化RDS-TCP套接字时,就会调用网络命名空间函数 register_pernet_device()
,传入指向 pernet_operations
结构体的一个指针( rds_tcp_net_ops
),其中包含待执行的初始化和退出函数,当初始化或删除网络命名空间以及激活套接字时就会调用这些函数。
图4. 调用 register_pernet_device()
注册网络命名空间设备
图5. rds_tcp_exit_net()
为网络命名空间设备的退出函数
退出函数 rds_tcp_exit_net()
会调用 rds_tcp_kill_sock()
,该函数用来清理RDS-TCP套接字中涉及的各个部分。其中有个清理过程会创建待清理的连接列表: tmp_list
。
内核会检查每个连接,判断在用的TCP套接字对应的 t_sock
指针是否为 NULL
,如果满足条件,就不会将 t_tcp_node
添加到“清理列表”中。这样处理的结果就是,内核不会针对这些节点调用 rds_conn_destroy()
,也不会执行许多“清理”操作。
图6. 如果 t_sock
为 NULL
则 rds_tcp_kill_sock()
不会执行清理操作
最重要的是, rds_connect_worker()
线程不会停止,会继续尝试重新连接。最终,作为清理命名空间的一个环节,底层网络结构会被释放,而正在运行的 rds_connect_worker()
可能还会用到该结构,这样就会触发释放后重用(use-after-free)问题。从技术角度上来讲,这个缺陷可以描述为:无需特殊权限,如果该漏洞成功被利用就可以实现管理员级别的代码执行。
这个问题修复起来也非常简单:系统管理员只需要确保存在漏洞的模块已被禁用,或者已安装了新版内核。
0x02 风险评估
分析完CVE-2019-11815后,该漏洞对用户而言意味着什么?潜在的受害者首先需要加载通常处于黑名单中的 rds
及 rds_tcp
模块,如果这些模块没被加载,那就不需要后续操作。如果攻击者终于找到了极其罕见的目标,由于TCP的 connect()
操作只由RDS-TCP客户端发起,跟服务端无关,因此攻击者需要诱导目标从网络命名空间中连接到攻击者可控的RDS-TCP套接字。
攻击者下一个任务就是触发底层TCP连接失败,与此同时触发目标用户的网络命名空间被系统清理:这是远程攻击者几乎无法完成的任务。除此之外,竞争条件(利用非预期时间点触发的缺陷来影响其他操作)通常也非常难以利用,需要大量尝试才有可能成功。
将这些条件考虑在内后,我们可以认为该漏洞“未经身份验证被远程利用”的概率近乎为零。该漏洞被用来提升本地权限的概率也非常低,需要系统加载通常处于黑名单中的 rds
及 rds_tcp
模块。
虽然从技术角度上来看这个漏洞CVSS评分没有问题,但用户应该了解到该风险同样依赖于攻击成功的可能性,因为攻击者能否成功实际上受利用复杂度和条件所限。在实际环境中这个漏洞很难利用成功,绝大多数Linux服务器在远程环境中根本不受影响。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- [译] 揭秘电商评分系统的核心原理:如何让评分更可信?
- 改变 Elasticsearch 评分来影响排序
- 基于 Logistict 回归的评分卡模型
- React 30 秒速学:制作星级评分组件
- 基于R语言的信用评分卡建模分析
- 8个超赞的深度学习课程(附评分)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
指数型组织
萨利姆•伊斯梅尔 (Salim Ismail)、迈克尔•马隆 (Michael S. Malone)、尤里•范吉斯特 (Yuri van Geest) / 苏健 / 浙江人民出版社 / 2015-8-1 / CNY 69.90
《指数型组织》是一本指数级时代企业行动手册。作者奇点大学创始执行理事萨利姆·伊斯梅尔归纳了指数型组织的11个强大属性,并提出了建立指数型组织的12个关键步骤。通过自己创建的一套“指数商”测试题,伊斯梅尔还测量出了指数型组织世界100强。 为什么小米、海尔和阿里巴巴能进入“指数型组织世界100强”名单?“独角兽”Uber、Airbnb、谷歌等知名企业是如何指数化自己的组织的? 未......一起来看看 《指数型组织》 这本书的介绍吧!