复现基于eBPF实现的Docker逃逸
0x00 关于本文 最近搞毕业设计在研究Docker逃逸,如果只把 CDK工具 的东西复现一遍(或者照抄),那诚意不足,也失掉了我刻意选我不熟悉领域的题目的意义所在,于是想自己动手做点东西。 看到 seebug上基于eBPF的逃逸 和 ScUpax0s的容器逃逸文章 ,我意识到基于eBPF的逃逸可以做一做,虽然他们都写了思路贴了部分代码片段,但毕竟没有放完整的代码出来,我自己踩坑实现一遍,可以学点东西,也能算是工作量。 文章中的代码实现已上传至 Github 。 在实现的过程中,ScUpax0s给了我许多指点,让我少走了很多弯路,感谢他! 0x01 eBPF为什么能帮助Docker逃逸 eBPF技术允许用户在用户态编写代码,被verifier扫描鉴定无问题后,送入内核执行。 e BPF可以在Linux系统的各个地方插桩,在执行到指定位置时,执行用户自定的代码,实现数据搜集和修改。 因此 eBPF使得用户可以在用户态高效安全地监控Linux的方方面面。 能看,还能改,黑客自然也可以拿它来使坏。更妙的是,在Docker环境中,容器和宿主机共享同一个内核,因此如果容器被赋予了CAP_SYS_ADMIN能力,成功在容器中加载了eBPF程序的话,eBPF程序将能够直接在系统的内核中运行,无视容器的各类隔离机制。因此在宿主机环境中作恶的eBPF,在容器中照作不误,它能在宿主机环境里面干上面,那就能在容器里干什么,突破隔离一步到位。 0x02 通过BPF劫持cron进行逃逸 尽管看起来很容易,但真正实现逃逸还需要一番周折。eBPF的代码仅能在触发插桩点的时候执行,它能够读参数,对指定地址的用户内存读写,但无法直接发起一个系统调用,弹一个shell回来。 seebug上基于eBPF的逃逸 给出了一种思路,即利用cron进行逃逸。 cron服务在Linux系统上实现了计划任务,它每隔一段时间检查配置文件是否被更改过,如果更改了就读取配置文件,根据配置文件的描述设定定时的命令执行。因此通过劫持cron对配置文件的访问,篡改文件的更改时间和读取内容,即可欺骗cron执行我们预定的命令,而cron是运行在宿主机上的,因此欺骗cron执行了命令相当于在宿主机中执行了命令,也就是逃逸。 0x03 程序整体结构