HYUNSUNG03/libcjack
GitHub: HYUNSUNG03/libcjack
从 Docker 镜像中无需启动容器即可提取原始 libc 和 ld,并用 patchelf 对 pwn 题目二进制文件进行本地化调试适配的命令行工具。
Stars: 0 | Forks: 0
# libcjack
**直接从 Docker 镜像中提取 `libc` 和 `ld`,并对你的 pwn 二进制文件执行 `patchelf`。**
*容器永远不会被启动。一次都不会。*
[](LICENSE)
[](pyproject.toml)
[](pyproject.toml)
[](#install)
**English** · [한국어](README.ko.md)
```
$ libcjack ./chall
[*] target: chall (x86_64, 64-bit)
[*] Dockerfile: Dockerfile
base image ubuntu:18.04
[*] pulling ubuntu:18.04
[*] creating container (not started)
[+] libc /lib/x86_64-linux-gnu/libc.so.6
[+] ld /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
[*] backup: chall.orig
[+] patched
interpreter /home/you/chall/libs/ld-2.27.so
rpath $ORIGIN/libs
[*] verifying with ldd:
linux-vdso.so.1 (0x00007ffd8f3fe000)
libc.so.6 => /home/you/chall/libs/libc.so.6 (0x00007f2b41e00000)
[+] done. to revert: cp chall.orig chall
```
就是这样。现在你可以在自己的机器上,使用你自己的 gdb / pwndbg / pwntools,针对远程运行的完全相同的 libc 进行调试。
## 问题所在 你得到了一个带有 Dockerfile 的 pwn 挑战。为了调试它,你进入了容器内部: ``` $ docker run -it chall bash # apt-get update && apt-get install -y gdb python3 ``` 然后你的 libc 就在不知不觉中被改变了。
## 解决方案 libcjack 不会去诊断这个问题。它直接将其消除。 `docker create` 会创建一个容器但不启动它,因此 `apt` 永远不会执行,提取出的 libc 与镜像中包含的完全一致。调试是在你的宿主机上进行的,也就是你的工具所在的地方。 | | 在容器内部调试 | 使用 libcjack | | ------------------------ | ----------------------------------- | -------------------------------- | | gdb / pwndbg / pwntools | 每次都要在里面安装 | 已经在你的宿主机上 | | 你最终得到的 libc | 取决于 `apt` 今天的决定 | 与镜像提供的一模一样 | | `docker run` | 是 | **从不** | | 每个挑战的设置 | 从头重复 | 一条命令 |
## 安装 ``` $ pipx install git+https://github.com/HYUNSUNG03/libcjack ``` 需要你的 `PATH` 中包含 `docker` 和 `patchelf`: ``` $ sudo apt install patchelf # Debian / Ubuntu $ sudo pacman -S patchelf # Arch $ sudo dnf install patchelf # Fedora ``` Linux x86_64,或 WSL2。
## 用法 ``` $ libcjack ./chall # use ./Dockerfile next to it $ libcjack ./chall --from ubuntu:18.04 # name an image directly $ libcjack ./chall --from ubuntu:bionic-20180426 # pin a dated tag $ libcjack ./chall -f ./docker/Dockerfile # point at a Dockerfile $ libcjack ./chall -f ./Dockerfile --build # build it first ``` | Flag | 作用 | | ---------------------------- | ---------------------------------------------------------------- | | `--from IMAGE` | 要从中提取的镜像标签或摘要 | | `-f`, `--from-dockerfile` | 用于读取 `FROM` 行的 Dockerfile | | `--build` | 构建 Dockerfile,而不是读取其基础镜像 | | `--libs-dir DIR` | 提取出的库存放的位置 — 默认为二进制文件旁的 `libs/` |
我什么时候才真正需要 --build?
几乎不需要。一个典型的 CTF Dockerfile 看起来像这样: ``` FROM ubuntu:18.04 RUN apt-get update && apt-get install -y socat COPY ./chall /chall CMD socat tcp-l:1337,fork,reuseaddr exec:/chall ``` 这里没有任何东西触及 libc,所以基础镜像的 libc **就是**远程的 libc。libcjack 读取 `FROM` 行,拉取 `ubuntu:18.04`,并完全跳过构建。 只有当 Dockerfile 本身改变了 libc 时,你才需要 `--build` —— 比如 `apt-get upgrade`、`dist-upgrade`,或者直接安装 `libc6`。libcjack 会精确扫描这些操作并警告你: ``` [!] this Dockerfile contains commands that can move libc: apt-get upgrade the base image's libc may differ from the remote. Consider --build. ``` 纯粹的 `apt-get update` 和 `apt-get install` 被刻意*不*标记 —— 它们几乎出现在每个 Dockerfile 中,对它们发出警告纯粹是噪音。 即使使用 `--build`,libcjack 也**只运行 Dockerfile 所说的内容**。它永远不会注入自己的命令 —— 这样做会重现这个工具旨在防止的污染。
固定旧版本 libc
现在的 `ubuntu:18.04` 是一个包含了所有安全更新的重建版本 —— 包括那个向后移植的 tcache 检查。如果你想要最初的 2.27 版本,请使用带日期的标签: ``` $ libcjack ./chall --from ubuntu:bionic-20180426 ``` 或者直接固定一个摘要: ``` $ libcjack ./chall --from ubuntu@sha256:a76d0e9d... ```
## 工作原理 ``` Dockerfile ──▶ base image ──▶ docker create ──▶ docker cp ──▶ patchelf ──▶ ./chall (never started) libc + ld ``` 1. 读取二进制文件的 ELF 标头以获取其架构。 2. 解析镜像 —— 来自 `--from`,或者 Dockerfile 的 `FROM` 行。 3. **`docker create`** —— 创建一个容器,但*不*启动它。 4. **`docker cp -L`** 将 libc 和 ld 复制出来,遵循符号链接(`libc.so.6` 通常是到 `libc-2.27.so` 的链接)。 5. **`docker rm`** 删除容器。 6. 将二进制文件备份为 `
## 适用范围 libcjack 只做一件事。它不会恢复被剥离的符号、获取调试源代码、生成 `solve.py`,也不会审计你的 libc 具有哪些缓解措施。 如果你手头已经有了一个 `libc.so.6` 文件,[**pwninit**](https://github.com/io12/pwninit) 是更好的工具,而且功能丰富得多。libcjack 的存在是为了应对你只有一个 Dockerfile 的情况。 仅支持 glibc —— 不支持基于 musl 的镜像(如 Alpine)。
## License MIT
标签:Blue Team, Docker, Patchelf, Pwn, Python, 二进制安全, 安全防御评估, 无后门, 请求拦截, 逆向分析, 逆向工具