Openfire身份认证漏洞分析(CVE-2023-32315)
2023-12-6 12:2:28 Author: 白帽子左一(查看原文) 阅读量:7 收藏

 扫码领资料

获网安教程

免费&进群

openfire是一个即时通讯服务器,也称之为即时通讯平台。它是基于XMPP协议的,大家所熟悉的通讯软件QQ、MSN和Gtalk等等,其中Gtalk就是基于XMPP协议的实现。
在即时通讯中往往因为需要保存一些状态或者数据所以不能采用点对点通讯,而是需要搭建服务器来转发。

来源:https://blog.csdn.net/qin34/article/details/41316231

通俗的讲openfire是一个即时通讯服务器,也叫即时通讯平台

3.10.0 <= Openfire < 4.6.8

4.7.0 <= Openfire < 4.7.5

这个漏洞的原理有点像多年前出现的CVE-2008-6508目录穿越漏洞

在设置为maven项目之后,先从源头配置找起

<filter>
<filter-name>AuthCheck</filter-name>
<filter-class>org.jivesoftware.admin.AuthCheckFilter</filter-class>
<init-param>
<param-name>excludes</param-name>
<param-value>
login.jsp,index.jsp?logout=true,setup/index.jsp,setup/setup-*,.gif,.png,error-serverdown.jsp,loginToken.jsp
</param-value>
</init-param>
</filter>

该处定义了一个名为AuthCheckfilter,用于对部分url免除鉴权

然后全局搜索AuthCheckFilter去寻找定义文件

定位代码

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
// Do not allow framing; OF-997
response.setHeader("X-Frame-Options", JiveGlobals.getProperty("adminConsole.frame-options", "SAMEORIGIN"));
// Reset the defaultLoginPage variable
String loginPage = defaultLoginPage;
if (loginPage == null) {
loginPage = request.getContextPath() + (AuthFactory.isOneTimeAccessTokenEnabled() ? "/loginToken.jsp" : "/login.jsp" );
}
// Get the page we're on:
String url = request.getRequestURI().substring(1);
if (url.startsWith("plugins/")) {
url = url.substring("plugins/".length());
}
// See if it's contained in the exclude list. If so, skip filter execution
boolean doExclude = false;
for (String exclude : excludes) {
if (testURLPassesExclude(url, exclude)) {
doExclude = true;
break;
}
}

定义代码里面可以看出

if (testURLPassesExclude(url, exclude)) {
doExclude = true;
break;
}

doExclude = true则无需鉴权

继续跟进testURLPassesExclude方法

public static boolean testURLPassesExclude(String url, String exclude) {
// If the exclude rule includes a "?" character, the url must exactly match the exclude rule.
// If the exclude rule does not contain the "?" character, we chop off everything starting at the first "?"
// in the URL and then the resulting url must exactly match the exclude rule. If the exclude ends with a "*"
// character then the URL is allowed if it exactly matches everything before the * and there are no ".."
// characters after the "*". All data in the URL before

if (exclude.endsWith("*")) {
if (url.startsWith(exclude.substring(0, exclude.length()-1))) {
// Now make sure that there are no ".." characters in the rest of the URL.
if (!url.contains("..") && !url.toLowerCase().contains("%2e")) {
return true;
}
}
}
else if (exclude.contains("?")) {
if (url.equals(exclude)) {
return true;
}
}
else {
int paramIndex = url.indexOf("?");
if (paramIndex != -1) {
url = url.substring(0, paramIndex);
}
if (url.equals(exclude)) {
return true;
}
}
return false;
}

代码中 if (!url.contains("..") && !url.toLowerCase().contains("%2e")) {可以发现对部分字符做了过滤

但是其内置的web服务器支持对%u002e非标准unicode编码的解析

具体代码如下所示

if (!encodedPath && !dot)
{
if (_param == null)
_decodedPath = _path;
else
_decodedPath = _path.substring(0, _path.length() - _param.length() - 1);
}
else if (_path != null)
{
// The RFC requires this to be canonical before decoding, but this can leave dot segments and dot dot segments
// which are not canonicalized and could be used in an attempt to bypass security checks.
String decodedNonCanonical = URIUtil.decodePath(_path);
_decodedPath = URIUtil.canonicalPath(decodedNonCanonical);
if (_decodedPath == null)
throw new IllegalArgumentException("Bad URI");
}

for (int i = offset; i < end; i++)
{
char c = path.charAt(i);
switch (c)
{
case '%':
if (builder == null)
{
builder = new Utf8StringBuilder(path.length());
builder.append(path, offset, i - offset);
}
if ((i + 2) < end)
{
char u = path.charAt(i + 1);
if (u == 'u')
{
// 解码%uxxxx形式的Unicode字符
builder.append((char)(0xffff & TypeUtil.parseInt(path, i + 2, 4, 16)));
i += 5;
}
else
{
// 解码%xx形式的ASCII字符
builder.append((byte)(0xff & (TypeUtil.convertHexDigit(u) * 16 + TypeUtil.convertHexDigit(path.charAt(i + 2)))));
i += 2;
}
}
else
{
throw new IllegalArgumentException("Bad URI % encoding");
}
break;

环境部署

首先利用docker拉取漏洞版本镜像

然后开启漏洞环境

然后确定一下

部署完毕

利用漏洞

brupsuit打洞

go打洞

cd CVE-2023-32315-Openfire-Bypass/scan_all
go run main.go -u http://openfire.com:9090
go mod tidy

然后就直接出来了,操作不难

来源: https://xz.aliyun.com/t/12869

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权

@
学习更多渗透技能!体验靶场实战练习

hack视频资料及工具

(部分展示)

往期推荐

【精选】SRC快速入门+上分小秘籍+实战指南

爬取免费代理,拥有自己的代理池

漏洞挖掘|密码找回中的套路

渗透测试岗位面试题(重点:渗透思路)

漏洞挖掘 | 通用型漏洞挖掘思路技巧

干货|列了几种均能过安全狗的方法!

一名大学生的黑客成长史到入狱的自述

攻防演练|红队手段之将蓝队逼到关站!

巧用FOFA挖到你的第一个漏洞

看到这里了,点个“赞”、“再看”吧

文章来源: http://mp.weixin.qq.com/s?__biz=MzI4NTcxMjQ1MA==&mid=2247603678&idx=1&sn=076fe872903631181a02568a4f09871e&chksm=ebeb1cf3dc9c95e5e8caf420fc67e43fe967d2331f4ede217d9e84a5b4a812e3600d45bab344&scene=0&xtrack=1#rd
如有侵权请联系:admin#unsafe.sh