记录从攻击溯源到docker逃逸的学习
免责声明:由于传播、利用本文所发布的而造成的任何直接或者间接的后果及损失,均由使用者本人承担
前言
我的学习记录
重点并不是在溯源,而是因为这个过程,使我从docker逃逸中学到很多思考
Start
起因是改造WAF的时候,顺带看了一眼攻击ip,批量识别了一下ip反制一下。这里忘记截图了
只发现了一个IDC服务器比较有价值

如图,也就是这个160.*.*.93
攻击次数非常多,并且实打实的payload 不是误报

溯源过程
由于一些我的个人问题与线索指向人之间的摩擦
所以这里不描写具体的线索梳理过程,也不写溯源到的个人信息,当然这个也不重要,本身也没有什么新颖的操作
反制
这里先扫了全端口

直接从2375端口入手
2375是Docker远程API的默认端口,通过这个端口可以直接对远程的Docker守护进程进行操作,然后就是操作逃逸到宿主机,也就是那个2375端口未授权访问漏洞的常见利用
漏洞利用
访问http://ip:2375
当时的截图个人信息太多,打码又影响阅读,所以随便找了一张图凑数
回显内容大概如下

客户端连接列出所有容器
docker -H tcp://160.*.*.93:2375/ ps -a

hacker字段很显眼
当时想的是先进容器看看能不能翻出来点什么数据和配置,之后再做逃逸
连接这个hacker容器
docker -H tcp://160.202.230.93:2375 exec -it 9422f /bin/bash

这里失败了,于是开始了学习与排查
具体报错信息
1 | OCI runtime exec failed: exec failed: unable to start container process:error adding SSB flag to seccomp filter:SetSSB requires libseccomp ≥2.5.0 and API level ≥ 4 (current version: 2.5.5, API level:1): unknown |
排错
当时着急出成果,直接丢给了ChatGPT,几个参数就解决了
当然CDK,还有这个漏洞的exp,都可以一把梭,只是我平常不太用这些,一来渗透本身就是一个很考验细节和耐心的东西,工具里是别人的理解 别人的经历的场景,多一个符合少一个符合可能都会影响最终结果的走向,二来发现长时间用AI复制粘贴解决问题,自己变的唐唐的

抱着学习的心态 今天再来看这个问题,想着尽可能用AI做辅助 而不是被牵着鼻子走
根据”:“的分隔,我把报错分成3部分
首先,看第一层报错
OCI runtime exec failed: exec failed: unable to start container process
这句一目了然,docker想在容器里启动一个新进程,但是exec指向的进程启动失败了,OCI runtime眼熟报错经常碰到,创建Linux进程用的
第二层报错
error adding SSB flag to seccomp filter
”添加 SSB 标志到 seccomp 过滤器出错“
到这里就不懂了:SSB、seccomp 这两个是什么东西
seccomp
这个涉及到了Linux系统的底层,seccomp全称Secure Computing,在了解seccomp之前,需要先知道system call ,
简称syscall,是操作系统提供给程序与内核交互的接口,简单来说,用户程序不能直接操作硬件和核心资源,需要通过 syscall 向内核请求服务,通过 syscall,程序可以完成如文件操作、进程管理、网络通信这些功能,比如go里面 就提供了syscall的包,可以调用系统的调用
以及dockerdocs中也有相关文档 https://docs.docker.com/engine/security/seccomp/

seccomp 的功能 就是限制程序可调用的系统调用,就类似java里JEP 290一样的概念
SSB
全称Speculative Store Bypass,他是干什么的呢?我当时也理解了非常久,简单来说CPU运行的时候为了提高速度,涉及到一种做法叫投机行为,就是先假设一个题解,等答案,修改题解,对了就不用管了,这样岂不是增加了速度和效率吗,但是出现了一个问题,CPU先假设好题解,然后直接去修改题解,但是这个时候答案还没有公布,并且改的过程中是有行为痕迹的,这些痕迹就可以被其他人看到,然后推测出答案,我能理解到的差不多这个意思吧
SSB的作用就是约束CPU禁止它跳过存储顺序,也是为了防御 CVE-2018-3639 漏洞
官方的说法

到这里就有点清晰了,docker exec是在容器创建新的进程,那么必然会加载seccomp,而seccomp会启用SSB,这个报错就说在添加SSB到seccomp失败了
在docker官方仓库的issue也找到了相关讨论https://github.com/moby/moby/issues/42619

Docker/Moby currently enables the Speculative Store Bypass mitigation when using seccomp. This is default for the seccomp syscall and for libseccomp.
Docker 自动会启用SSB缓解,当使用 seccomp 时,这个是默认行为
第三层报错
SetSSB requires libseccomp ≥2.5.0 and API level ≥ 4 (current version: 2.5.5, API level:1)
这个就比较简单了,说了一下设置SSB需要具备的条件,
libseccomp ≥2.5.0 (现版本2.5.5 已满足)
API level ≥ 4(当前宿主机系统等级是1)
libseccomp
docker启动容器或者启动进程的时候,通过libseccomp实现 seccomp的功能
在一些文章和仓库中也有描述
https://segmentfault.com/a/1190000016366810

https://github.com/docker-archive-public/nestybox.libseccomp-golang

https://libseccomp.readthedocs.io/en/latest/

综合推导出来就是
Docker 通过 containerd 调用 runc ->runc 在创建进程时要安装 seccomp 过滤器>runc 需要 libseccomp 来实现 seccomp 加载>libseccomp把规则(也就是seccomp filter)加载到内核
API level
从这个文档中 https://man7.org/linux/man-pages/man3/seccomp_api_get.3.html

可以得知API level 就是用来定义 libseccomp 功能等级的指标,一级能干什么 二级能干什么…
写的也很明显,4级就可以设置SSB
解决
把所有的名词都搞清楚了,触发错误的原因就是:docker 在执行 docker exec 时,尝试给新进程启用 SSB 缓解,但是宿主机上的 libseccomp 功能等级(API level 是 1)太低,不支持 SSB,导致容器进程无法启动
在浏览dockerdocs那篇文档的时候,也就是https://docs.docker.com/engine/security/seccomp/?utm_source=chatgpt.com#run-without-the-default-seccomp-profile
末尾写了 可以用-security-opt seccomp=unconfined来声明, 不使用默认 seccomp profile

这样就可以直接绕过直接绕过 SSB 设置问题,不设置了 SetSSB就不会调用接口,那么就不存在libseccomp和API level的条件检查
逃逸
启动一个新容器 然后挂载宿主机硬盘,并且不加载seccomp进入shell
docker -H tcp://160.*.*.93:2375 run -rm -it --security-opt seccomp=unconfined -v /:/mnt --entrypoint /bin/bash xxxxx

成功进入容器
考虑到网络情况,刚开始打算写ssh公钥,但是因为宿主机的authorized_keys文件只有r权限,正常来说是755才可以,后面尝试用计划任务执行chmod改authorized_keys文件权限也是一直没效果,所以放弃
写计划任务拿宿主机shell:
这里还涉及到ubuntu计划任务反弹shell的细节问题:可以看这篇博客解决,属于是老掉牙了
然后就发现计划任务写进去不执行,
当时找了好久,翻了好多日志,尝试了几乎所有的计划任务路径,/etc/crontab、/var/spool/cron/crontabs/、/etc/systemd/system/等
当时用了个笨办法,先从计划任务日志里查看正在执行的任务,然后根据日志中的关键字,去各个计划任务目录里查找对应的文件,从而确认这些任务是由哪个目录下的计划任务触发的
最终确认在/etc/cron.d/zzh写入,不管是系统级还是用户级计划任务,只有这一个zzh文件中的计划任务在执行,非常离谱,所以像这种自动化的梭哈工具 怎么可能找到,不动手看就利用失败了

成功收到shell

这也就是160开头 93结尾的攻击着IP,逃逸成功拿到了宿主机的权限
现在回头看,直接去读官方开发文档和源码来定位问题,似乎比单纯向AI复制粘贴命令更有主动性,也更容易真正理解问题的本质,但解决问题的时间线会被拉长
或许只需要平衡好时间投资和知识投资之间的关系……

