Confluence 未授权 RCE (CVE-2019-3396) 漏洞分析
作者:Badcode@知道创宇404实验室
时间:2019年4月8日
看到官方发布了预警,于是开始了漏洞应急。漏洞描述中指出Confluence Server与Confluence Data Center中的Widget Connector存在服务端模板注入漏洞,攻击者能利用此漏洞能够实现目录穿越与远程代码执行。
确认漏洞点是Widget Connector,下载最新版的比对补丁,发现在com\atlassian\confluence\extra\widgetconnector\WidgetMacro.java
里面多了一个过滤,这个应该就是这个漏洞最关键的地方。
可以看到
1 |
this.sanitizeFields = Collections.unmodifiableList(Arrays.asList(VelocityRenderService.TEMPLATE_PARAM)); |
而TEMPLATE_PARAM
的值就是_template
,所以这个补丁就是过滤了外部传入的_template
参数。
1 2 3 4 |
public interface VelocityRenderService { public static final String WIDTH_PARAM = "width"; public static final String HEIGHT_PARAM = "height"; public static final String TEMPLATE_PARAM = "_template"; |
翻了一下Widget Connector里面的文件,发现TEMPLATE_PARAM
就是模板文件的路径。
1 2 3 4 5 6 7 8 9 10 |
public class FriendFeedRenderer implements WidgetRenderer { private static final String MATCH_URL = "friendfeed.com"; private static final String PATTERN = "friendfeed.com/(\\w+)/?"; private static final String VELOCITY_TEMPLATE = "com/atlassian/confluence/extra/widgetconnector/templates/simplejscript.vm"; private VelocityRenderService velocityRenderService; ...... public String getEmbeddedHtml(String url, Map<String, String> params) { params.put(VelocityRenderService.TEMPLATE_PARAM, VELOCITY_TEMPLATE); return velocityRenderService.render(getEmbedUrl(url), params); } |
加载外部的链接时,会调用相对的模板去渲染,如上,模板的路径一般是写死的,但是也有例外,补丁的作用也说明有人突破了限制,调用了意料之外的模板,从而造成了模板注入。
在了解了补丁和有了一些大概的猜测之后,开始尝试。
首先先找到这个功能,翻了一下官方的文档,找到了这个功能,可以在文档中嵌入一些视频,文档之类的。
看到这个,有点激动了,因为在翻补丁的过程中,发现了几个参数,url
,width
,height
正好对应着这里,那_template
是不是也从这里传递进去的?
随便找个Youtube视频插入试试,点击预览,抓包。
在params
中尝试插入_template
参数,好吧,没啥反应。。
开始debug模式,因为测试插入的是Youtube视频,所以调用的是com/atlassian/confluence/extra/widgetconnector/video/YoutubeRenderer.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class YoutubeRenderer implements WidgetRenderer, WidgetImagePlaceholder { private static final Pattern YOUTUBE_URL_PATTERN = Pattern.compile("https?://(.+\\.)?youtube.com.*(\\?v=([^&]+)).*$"); private final PlaceholderService placeholderService; private final String DEFAULT_YOUTUBE_TEMPLATE = "com/atlassian/confluence/extra/widgetconnector/templates/youtube.vm"; ...... public String getEmbedUrl(String url) { Matcher youtubeUrlMatcher = YOUTUBE_URL_PATTERN.matcher(this.verifyEmbeddedPlayerString(url)); return youtubeUrlMatcher.matches() ? String.format("//www.youtube.com/embed/%s?wmode=opaque", youtubeUrlMatcher.group(3)) : null; } public boolean matches(String url) { return YOUTUBE_URL_PATTERN.matcher(this.verifyEmbeddedPlayerString(url)).matches(); } private String verifyEmbeddedPlayerString(String url) { return !url.contains("feature=player_embedded&") ? url : url.replace("feature=player_embedded&", ""); } public String getEmbeddedHtml(String url, Map<String, String> params) { return this.velocityRenderService.render(this.getEmbedUrl(url), this.setDefaultParam(params)); } |
在getEmbeddedHtml
下断点,先会调用getEmbedUrl
对用户传入的url
进行正则匹配,因为我们传入的是个正常的Youtube视频,所以这里是没有问题的,然后调用setDefaultParam
函数对传入的其他参数进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="kd">private</span> <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="nf">setDefaultParam</span><span class="o">(</span><span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">params</span><span class="o">)</span> <span class="o">{</span> <span class="n">String</span> <span class="n">width</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">params</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"width"</span><span class="o">);</span> <span class="n">String</span> <span class="n">height</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">params</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"height"</span><span class="o">);</span> <span class="k">if</span> <span class="o">(!</span><span class="n">params</span><span class="o">.</span><span class="na">containsKey</span><span class="o">(</span><span class="s">"_template"</span><span class="o">))</span> <span class="o">{</span> <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"_template"</span><span class="o">,</span> <span class="s">"com/atlassian/confluence/extra/widgetconnector/templates/youtube.vm"</span><span class="o">);</span> <span class="o">}</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">(</span><span class="n">width</span><span class="o">))</span> <span class="o">{</span> <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"width"</span><span class="o">,</span> <span class="s">"400px"</span><span class="o">);</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isNumeric</span><span class="o">(</span><span class="n">width</span><span class="o">))</span> <span class="o">{</span> <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"width"</span><span class="o">,</span> <span class="n">width</span><span class="o">.</span><span class="na">concat</span><span class="o">(</span><span class="s">"px"</span><span class="o">));</span> <span class="o">}</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">(</span><span class="n">height</span><span class="o">))</span> <span class="o">{</span> <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"height"</span><span class="o">,</span> <span class="s">"300px"</span><span class="o">);</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isNumeric</span><span class="o">(</span><span class="n">height</span><span class="o">))</span> <span class="o">{</span> <span class="n">params</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"height"</span><span class="o">,</span> <span class="n">height</span><span class="o">.</span><span class="na">concat</span><span class="o">(</span><span class="s">"px"</span><span class="o">));</span> <span class="o">}</span> <span class="k">return</span> <span class="n">params</span><span class="o">;</span> <span class="o">}</span> |
取出width
和height
来判断是否为空,为空则设置默认值。关键的_template
参数来了,如果外部传入的参数没有_template
,则设置默认的Youtube模板。如果传入了,就使用传入的,也就是说,aaaa是成功的传进来了。
大概翻了一下Widget Connector里面的Renderer,大部分是不能设置_template
的,是直接写死了,也有一些例外,如Youtube,Viddler,DailyMotion等,是可以从外部传入_template
的。
能传递_template
了,接下来看下是如何取模板和渲染模板的。
跟进this.velocityRenderService.render
,也就是com/atlassian/confluence/extra/widgetconnector/services/DefaultVelocityRenderService.class
里面的render
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<span class="kd">public</span> <span class="n">String</span> <span class="nf">render</span><span class="o">(</span><span class="n">String</span> <span class="n">url</span><span class="o">,</span> <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">params</span><span class="o">)</span> <span class="o">{</span> <span class="n">String</span> <span class="n">width</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">params</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"width"</span><span class="o">);</span> <span class="n">String</span> <span class="n">height</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">params</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"height"</span><span class="o">);</span> <span class="n">String</span> <span class="n">template</span> <span class="o">=</span> <span class="o">(</span><span class="n">String</span><span class="o">)</span><span class="n">params</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"_template"</span><span class="o">);</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">(</span><span class="n">template</span><span class="o">))</span> <span class="o">{</span> <span class="n">template</span> <span class="o">=</span> <span class="s">"com/atlassian/confluence/extra/widgetconnector/templates/embed.vm"</span><span class="o">;</span> <span class="o">}</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">(</span><span class="n">url</span><span class="o">))</span> <span class="o">{</span> <span class="k">return</span> <span class="kc">null</span><span class="o">;</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">></span> <span class="n">contextMap</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="na">getDefaultVelocityContext</span><span class="o">();</span> <span class="n">Iterator</span> <span class="n">var7</span> <span class="o">=</span> <span class="n">params</span><span class="o">.</span><span class="na">entrySet</span><span class="o">().</span><span class="na">iterator</span><span class="o">();</span> <span class="k">while</span><span class="o">(</span><span class="n">var7</span><span class="o">.</span><span class="na">hasNext</span><span class="o">())</span> <span class="o">{</span> <span class="n">Entry</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">entry</span> <span class="o">=</span> <span class="o">(</span><span class="n">Entry</span><span class="o">)</span><span class="n">var7</span><span class="o">.</span><span class="na">next</span><span class="o">();</span> <span class="k">if</span> <span class="o">(((</span><span class="n">String</span><span class="o">)</span><span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">()).</span><span class="na">contentEquals</span><span class="o">(</span><span class="s">"tweetHtml"</span><span class="o">))</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">(),</span> <span class="n">entry</span><span class="o">.</span><span class="na">getValue</span><span class="o">());</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="n">entry</span><span class="o">.</span><span class="na">getKey</span><span class="o">(),</span> <span class="n">GeneralUtil</span><span class="o">.</span><span class="na">htmlEncode</span><span class="o">((</span><span class="n">String</span><span class="o">)</span><span class="n">entry</span><span class="o">.</span><span class="na">getValue</span><span class="o">()));</span> <span class="o">}</span> <span class="o">}</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"urlHtml"</span><span class="o">,</span> <span class="n">GeneralUtil</span><span class="o">.</span><span class="na">htmlEncode</span><span class="o">(</span><span class="n">url</span><span class="o">));</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isNotEmpty</span><span class="o">(</span><span class="n">width</span><span class="o">))</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"width"</span><span class="o">,</span> <span class="n">GeneralUtil</span><span class="o">.</span><span class="na">htmlEncode</span><span class="o">(</span><span class="n">width</span><span class="o">));</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"width"</span><span class="o">,</span> <span class="s">"400"</span><span class="o">);</span> <span class="o">}</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isNotEmpty</span><span class="o">(</span><span class="n">height</span><span class="o">))</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"height"</span><span class="o">,</span> <span class="n">GeneralUtil</span><span class="o">.</span><span class="na">htmlEncode</span><span class="o">(</span><span class="n">height</span><span class="o">));</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">contextMap</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"height"</span><span class="o">,</span> <span class="s">"300"</span><span class="o">);</span> <span class="o">}</span> <span class="k">return</span> <span class="k">this</span><span class="o">.</span><span class="na">getRenderedTemplate</span><span class="o">(</span><span class="n">template</span><span class="o">,</span> <span class="n">contextMap</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> |
_template
取出来赋值给template
,其他传递进来的参数取出来经过判断之后放入到contextMap
,调用getRenderedTemplate
函数,也就是调用VelocityUtils.getRenderedTemplate
。
1 2 3 |
<span class="kd">protected</span> <span class="n">String</span> <span class="nf">getRenderedTemplate</span><span class="o">(</span><span class="n">String</span> <span class="n">template</span><span class="o">,</span> <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">></span> <span class="n">contextMap</span><span class="o">){</span> <span class="k">return</span> <span class="n">VelocityUtils</span><span class="o">.</span><span class="na">getRenderedTemplate</span><span class="o">(</span><span class="n">template</span><span class="o">,</span> <span class="n">contextMap</span><span class="o">);</span> <span class="o">}</span> |
一路调用,调用链如下图,最后来到/com/atlassian/confluence/util/velocity/ConfigurableResourceManager.class
的loadResource
函数,来获取模板。
这里调用了4个ResourceLoader
去取模板。
1 2 3 4 |
<span class="n">com</span><span class="o">.</span><span class="na">atlassian</span><span class="o">.</span><span class="na">confluence</span><span class="o">.</span><span class="na">setup</span><span class="o">.</span><span class="na">velocity</span><span class="o">.</span><span class="na">HibernateResourceLoader</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">velocity</span><span class="o">.</span><span class="na">runtime</span><span class="o">.</span><span class="na">resource</span><span class="o">.</span><span class="na">loader</span><span class="o">.</span><span class="na">FileResourceLoader</span> <span class="n">org</span><span class="o">.</span><span class="na">apache</span><span class="o">.</span><span class="na">velocity</span><span class="o">.</span><span class="na">runtime</span><span class="o">.</span><span class="na">resource</span><span class="o">.</span><span class="na">loader</span><span class="o">.</span><span class="na">ClasspathResourceLoader</span> <span class="n">com</span><span class="o">.</span><span class="na">atlassian</span><span class="o">.</span><span class="na">confluence</span><span class="o">.</span><span class="na">setup</span><span class="o">.</span><span class="na">velocity</span><span class="o">.</span><span class="na">DynamicPluginResourceLoader</span> |
这里主要看下Velocity自带的FileResourceLoader
和ClasspathResourceLoader
FileResourceLoader
会对用户传入的模板路径使用normalizePath
函数进行校验
可以看到,过滤了/../
,这样就导致没有办法跳目录了。
路径过滤后调用findTemplate
查找模板,可看到,会拼接一个固定的path
,这是Confluence的安装路径。
也就是说现在可以利用FileResourceLoader
来读取Confluence目录下面的文件了。
尝试读取/WEB-INF/web.xml
文件,可以看到,是成功的加载到了该文件。
但是这个无法跳出Confluence的目录,因为不能用/../
。
再来看下ClasspathResourceLoader
1 2 3 4 5 6 7 8 9 |
<span class="kd">public</span> <span class="n">InputStream</span> <span class="nf">getResourceStream</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">ResourceNotFoundException</span> <span class="o">{</span> <span class="n">InputStream</span> <span class="n">result</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span> <span class="k">if</span> <span class="o">(</span><span class="n">StringUtils</span><span class="o">.</span><span class="na">isEmpty</span><span class="o">(</span><span class="n">name</span><span class="o">))</span> <span class="o">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="n">ResourceNotFoundException</span><span class="o">(</span><span class="s">"No template name provided"</span><span class="o">);</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">result</span> <span class="o">=</span> <span class="n">ClassUtils</span><span class="o">.</span><span class="na">getResourceAsStream</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">getClass</span><span class="o">(),</span> <span class="n">name</span><span class="o">);</span> <span class="o">......</span> <span class="o">}</span> |
跟进ClassUtils.getResourceAsStream
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="kd">public</span> <span class="kd">static</span> <span class="n">InputStream</span> <span class="nf">getResourceAsStream</span><span class="o">(</span><span class="n">Class</span> <span class="n">claz</span><span class="o">,</span> <span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span> <span class="k">while</span><span class="o">(</span><span class="n">name</span><span class="o">.</span><span class="na">startsWith</span><span class="o">(</span><span class="s">"/"</span><span class="o">))</span> <span class="o">{</span> <span class="n">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="na">substring</span><span class="o">(</span><span class="mi">1</span><span class="o">);</span> <span class="o">}</span> <span class="n">ClassLoader</span> <span class="n">classLoader</span> <span class="o">=</span> <span class="n">Thread</span><span class="o">.</span><span class="na">currentThread</span><span class="o">().</span><span class="na">getContextClassLoader</span><span class="o">();</span> <span class="n">InputStream</span> <span class="n">result</span><span class="o">;</span> <span class="k">if</span> <span class="o">(</span><span class="n">classLoader</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">classLoader</span> <span class="o">=</span> <span class="n">claz</span><span class="o">.</span><span class="na">getClassLoader</span><span class="o">();</span> <span class="n">result</span> <span class="o">=</span> <span class="n">classLoader</span><span class="o">.</span><span class="na">getResourceAsStream</span><span class="o">(</span><span class="n">name</span><span class="o">);</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">result</span> <span class="o">=</span> <span class="n">classLoader</span><span class="o">.</span><span class="na">getResourceAsStream</span><span class="o">(</span><span class="n">name</span><span class="o">);</span> <span class="k">if</span> <span class="o">(</span><span class="n">result</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">classLoader</span> <span class="o">=</span> <span class="n">claz</span><span class="o">.</span><span class="na">getClassLoader</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">classLoader</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">result</span> <span class="o">=</span> <span class="n">classLoader</span><span class="o">.</span><span class="na">getResourceAsStream</span><span class="o">(</span><span class="n">name</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="o">}</span> <span class="k">return</span> <span class="n">result</span><span class="o">;</span> <span class="o">}</span> |
会跳到/org/apache/catalina/loader/WebappClassLoaderBase.class
跟进,发现会拼接/WEB-INF/classes
,而且其中也是调用了normalize
对传入的路径进行过滤。。
这里还是可以用../
跳一级目录。
尝试读取一下../web.xml
,可以看到,也是可以读取成功的,但是仍然无法跳出目录。
我这里测试用的版本是6.14.1
,而后尝试了file://
,http://
,https://
都没有成功。后来我尝试把Cookie删掉,发现还是可以读取文件,确认了这个漏洞不需要权限,但是跳不出目录。应急就在这里卡住了。
而后的几天,有大佬说用file://
协议可以跳出目录限制,我惊了,我确定当时是已经试过了,没有成功的。看了大佬的截图,发现用的是6.9.0的版本,我下载了,尝试了一下,发现真的可以。
问题还是在ClasspathResourceLoader
上面,步骤和之前的是一样的,断到/org/apache/catalina/loader/WebappClassLoaderBase.class
的getResourceAsStream
方法
前面拼接/WEB-INF/classes
获取失败后,继续往下进行。
跟进findResource
,函数前面仍然获取失败
关键的地方就在这里,会调用super.findResource(name)
,这里返回了URL,也就是能获取到对象。
不仅如此,这里还可以使用其他协议(https,ftp等)获取远程的对象,意味着可以加载远程的对象。
获取到URL对象之后,继续回到之前的getResourceAsStream
,可以看到,当返回的url不为null时,
会调用url.openStream()
获取数据。
最终获取到数据给Velocity渲染。
尝试一下
至于6.14.1为啥不行,赶着应急,后续会跟,如果有新的发现,会同步上来,目前只看到ClassLoader
不一样。
6.14.1
6.9.0
这两个loader的关系如下
现在可以加载本地和远程模板了,可以尝试进行RCE。
关于Velocity的RCE,基本上payload都来源于15年blackhat的服务端模板注入的议题,但是在Confluence上用不了,因为在调用方法的时候会经过velocity-htmlsafe-1.5.1.jar
,里面多了一些过滤和限制。但是仍然可以利用反射来执行命令。
用python -m pyftpdlib -p 2121
开启一个简单的ftp服务器,将payload保存成rce.vm,保存在当前目录。
将_template
设置成ftp://localhost:2121/rce.vm
,发送,成功执行命令。
对于命令回显,同样可以使用反射构造出payload,执行ipconfig
的结果。
漏洞影响
根据 ZoomEye 网络空间搜索引擎对关键字 "X-Confluence" 进行搜索,共得到 61,856 条结果,主要分布美国、德国、中国等国家。
全球分布(非漏洞影响范围)
中国分布(非漏洞影响范围)
漏洞检测
2019年4月4日,404实验室公布了该漏洞的检测PoC,可以利用这个PoC检测Confluence是否受该漏洞影响。
参考链接
- 漏洞检测PoC
- Remote code execution via Widget Connector macro - CVE-2019-3396
- 漏洞预警 | Confluence Server 远程代码执行漏洞
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/884/