CVE-2022-26134 调试

简单来说就是一个confluence的未授权OGNL RCE

简单来说就是一个confluence的未授权OGNL RCE

修复版本

  • 7.4.17
  • 7.13.7
  • 7.14.3
  • 7.15.2
  • 7.16.4
  • 7.17.4
  • 7.18.1

官方修复建议是直接替换有漏洞的包并替换为更新后的包

  • 7.15.0 - 7.18.0修复

    删除

    <confluence-install>/confluence/WEB-INF/lib/xwork-1.0.3-atlassian-8.jar
    

    并替换为 xwork-1.0.3-atlassian-10.jar 然后重启应用

  • 6.0.0 - 7.14.2修复

    ​ 删除下面两个

<confluence-install>/confluence/WEB-INF/lib/xwork-1.0.3.6.jar     
<confluence-install>/confluence/WEB-INF/lib/webwork-2.1.5-atlassian-3.jar

​ 并替换为 ​ xwork-1.0.3-atlassian-10.jarwebwork-2.1.5-atlassian-4.jar ​ 下载CachedConfigurationProvider.class ​ 放到这个目录下

<confluence-install>/confluence/WEB-INF/classes/com/atlassian/confluence/setup/webwork

​ 要注意权限的问题 ​ 重启应用

调试环境

前置环境:

docker环境配置文件

version: '2'
services:
  web:
    image: vulhub/confluence:7.13.6
    ports:
      - "8090:8090"
      - "5050:5050"
    depends_on:
      - db
  db:
    image: postgres:12.8-alpine
    environment: 
    - POSTGRES_PASSWORD=postgres
    - POSTGRES_DB=confluence

调试源码为在/opt/atlassian/confluence

将/confluence/WEB-INF下的atlassian-bundled-plugins、atlassian-bundled-plugins-setup、lib文件设置为lib

修改/opt/atlassian/confluence/bin/setenv.sh文件,加入远程调试配置。

docker环境也需要对应的设置

首次访问的时候需要认证一下,数据库配置那里,地址是db,后三行都是postgres

网上的一个payload为

/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22cat%20/etc/passwd%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Response%22%2C%23a%29%29%7D/

直接接在url后面,返回的一个自定义header会把结果也返回

调试思路:

根据漏洞信息,官方修复措施

https://confluence.atlassian.com/doc/confluence-security-advisory-2022-06-02-1130377146.html

定位漏洞jar包,xwork-1.0.3-atlassian-10.jar ,比对修复前后的jar包发现修改主要在ActionChainResult.java,定位OGNL调用点,发现修复措施是将漏洞点TextParseUtil.translateVariables()给删除了,改为直接取值。意味着如果这个点再次出现并且能够控制输入,那么这个漏洞依然可以利用。

1

传入的namespace的值就是ognl表达式

2

然后到TextParseUtil.java的translateVariables方法,此时传入的payload在这里被解析

3

然后调用Ognl.getValue()

4

开始一系列的OGNL表达式处理

5

6

表达式解析完成后,执行命令并返回result

7

8

payload向下的触发暂时到这里,现在的疑问是这个payload是怎么从url传递到漏洞点的,这里是this.namespace,向上回溯,this.createResult()

(调了一下背景)9

10

this.proxy.getConfig().getResults();

现在就需要溯源这句

上面有一堆invoke来回的调用,溯源到DefaultActionProxy

11

ConfluenceServletDispatcher的proxy.execute();,再往上是ServletDispatcher,算是到头了

12

getActionName有两个,第二个 逻辑是返回’/’和’.’之间的字符串或者整个字符串

13

namespace则是返回’/’前的内容,现在就能理解为什么payload最后会有一个’/’

14

分析就到这里

后续

漏洞点触发器前会有一段类似循环的操作,最后把actionName设置为’notpermitted’就跳出循环了,触发之后也有一段循环然后等待新的请求,这两部分一个是和漏洞本身流程关系不大,一个是对这块不太了解就暂时不深究了。

从修复的地方可以看出原来的代码略显鸡肋,也不知道出于什么样的原因才这样写的,是因为本来有别的想法来拓展一些功能,最后没有实现,但是也没有修改这几句?

参考

https://mr-r3bot.github.io/research/2022/06/06/Confluence-Preauth-RCE-2022.html

https://zhuanlan.zhihu.com/p/526003612

https://forum.butian.net/share/1645