CVE-2022-43781 Bitbucket Server & Data Center 环境变量注入导致RCE

环境

下载7.6.17版本 https://www.atlassian.com/software/bitbucket/download-archives

调试 C:\Atlassian\Bitbucket\7.6.17\bin\_start-webapp.bat

1
2
set JVM_SUPPORT_RECOMMENDED_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
start-bitbucket.bat /no-search

分析

7.6.17和7.6.19 diff

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/1.png

这个地方将用户名放入env环境变量

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/2.png

补丁要求用户名不能有空白字符,典型。我们需要看这个空白字符在哪用到了,以及对我们漏洞利用起了什么作用。

在创建仓库的时候,会通过com.atlassian.stash.internal.scm.git.command.CreateCommand调用git实现创建仓库。最终会执行到

com.atlassian.bitbucket.internal.process.nu.NuNioProcessHelper#run

1
2
3
4
5
6
public <T> T run(@Nonnull NioProcessParameters<T> parameters) {
    this.applyConfigurers(parameters);
    NioNuProcessHandler<T> handler = new NioNuProcessHandler(parameters, this.timeoutExecutor);
    this.createProcessBuilder(parameters, handler).run();
    return handler.asResult();
}

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/3.png

DefaultNioProcessConfigurer更新TEMP环境变量

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/4.png

RemoteUserNioProcessConfigurer 更新用户名环境变量

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/5.png

然后com.atlassian.bitbucket.internal.process.nu.NuNioProcessHelper#createProcessBuilder创建NuProcessBuilder实例来执行命令

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/6.png

接着调用NuProcessBuilder实例的run方法 com.zaxxer.nuprocess.NuProcessBuilder#run

1
2
3
4
5
public void run() {
    this.ensureListener();
    String[] env = this.prepareEnvironment();
    factory.runProcess(this.command, env, this.processListener, this.cwd);
}

在prepareEnvironment中,将this.environment从map转为string[]

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/7.png

1
2
REMOTE_USER -> admin
REMOTE_USER=admin

并且map to string[],然后分平台继续运行命令com.zaxxer.nuprocess.windows.WindowsProcess#run

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/8.png

在prepareProcess中将刚才处理的string[]转为char[],交给NuKernel32.CreateProcessW 用windows api执行命令。

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/9.png

getEnvironment函数

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/10.png

getEnvironmentBlock()函数中

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/11.png

\u0000作为分界符

当开启用户注册时,注册一个用户名为test\0xx=xx的用户,那么之前的REMOTE_USER会把用户名put进去,经过处理后会注入一个xx=xx的环境变量。

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/12.png

那么思考,注入环境变量之后怎么rce?

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/13.png

二进制文件是git.exe,在Git文档中环境变量部分,有GIT_EXTERNAL_DIFF,用这个可以执行自定义命令。

注册一个testa\00GIT_EXTERNAL_DIFF=$(cmd /c calc)

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/14.png

随便点个仓库看commit diff

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/15.png

弹计算器时,成功注入环境变量

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/16.png

但是执行命令用$(cmd /c calc)会卡住,因为调用win的git sh执行的cmd命令是cmd C:/ calc

1
2
3
sh -c "$(cmd /c calc) \"[email protected]\"" "$(cmd /c calc)" 1.txt "C:\\Atlassian\\ApplicationData\\Bitbucket\\tmp/git-blob-a01248/1.txt" 37bcc8b8cadedf38a76caa1633b17ae19292faaa 100644 "C:\\Atlassian\\ApplicationData\\Bitbucket\\tmp/git-blob-b01248/1.txt" 0ac3866ff50b73894c0f0de3a7587ecd7b78434b 100644

C:\Windows\system32\cmd.exe C:/ calc

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/17.png

这个地方可以改命令为$(powershell calc)就行了。具体利用需要自己变exp就行了。

https://y4er.com/img/uploads/CVE-2022-43781-Bitbucket-Server-RCE/18.png

搜了一下,发现这个空字节环境变量注入是com.zaxxer.nuprocess库的问题。

https://github.com/brettwooldridge/NuProcess/security/advisories/GHSA-cxgf-v2p8-7ph7

在这个advisories中,提到了:

This vulnerability can only be exploited to inject command line arguments on Linux.

所以除了这个命令注入以外,还可以注入环境变量。

参考

  1. https://petrusviet.medium.com/cve-2022-43781-32bc29de8960

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。