hacktricks/network-services-pentesting/pentesting-web/artifactory-hacking-guide.md
2023-06-06 18:56:34 +00:00

195 lines
16 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.

<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**? Confira 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 suas técnicas de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
</details>
**Este conteúdo foi retirado de** [**https://www.errno.fr/artifactory/Attacking\_Artifactory**](https://www.errno.fr/artifactory/Attacking\_Artifactory)
# Conceitos básicos do Artifactory <a href="#artifactory-basics" id="artifactory-basics"></a>
## Usuários e senhas padrão <a href="#default-users-and-passwords" id="default-users-and-passwords"></a>
As contas padrão do Artifactory são:
| Conta | Senha padrão | Notas |
| ------------ | ---------------------------------------------- | -------------------------------------------------------------------- |
| admin | password | conta comum de administração |
| access-admin | password (<6.8.0) ou um valor aleatório (>= 6.8.0) | usada apenas para operações de administração local |
| anonymous | | usuário anônimo para recuperar pacotes remotamente, não habilitado por padrão |
Por padrão, nenhuma política de bloqueio de senha está em vigor, o que torna o Artifactory um alvo principal para ataques de preenchimento de credenciais e pulverização de senhas.
## Autorizações <a href="#authorizations" id="authorizations"></a>
Idealmente, isso é o que você deve ver ao se conectar ao Artifactory:
![Página de login](https://www.errno.fr/artifactory/artif\_login.png)
Por outro lado, se você for recebido com algo mais parecido com isso:
![Página padrão](https://www.errno.fr/artifactory/artif\_default.png)
Significa que o "Acesso anônimo" foi habilitado no painel de administração, que é uma configuração comum usada para permitir que aplicativos recuperem artefatos sem problemas, mas permite que você, o atacante, veja mais do que é preferível.
## Verificando os direitos da conta <a href="#checking-account-rights" id="checking-account-rights"></a>
Às vezes, devido a uma má configuração, o acesso anônimo é permitido para implantar arquivos em alguns repositórios!
Para verificar em quais repositórios o usuário anônimo pode implantar, use a seguinte solicitação:
```
curl http://localhost:8081/artifactory/ui/repodata?deploy=true
{"repoList":["artifactory-build-info","example-repo-local"]}
```
Se houver entradas `repoKey` na solicitação, qualquer pessoa pode implantar nelas, o que é realmente muito ruim. Você definitivamente deve estar autenticado para implantar quaisquer arquivos.
Isso pode ser generalizado para outras contas assim que você obtiver uma senha ou token para elas.
## Listando usuários <a href="#listing-users" id="listing-users"></a>
Por algum motivo, listar usuários é um direito reservado apenas para administradores. Eu encontrei uma maneira alternativa de listar usuários (aqueles que estão implantando ativamente pelo menos) que depende do valor "Implantado por" dos artefatos:
![Implantado por](https://www.errno.fr/artifactory/artif\_deployed\_by.png)
[Este script](https://gist.github.com/gquere/347e8e042490be87e6e9e32e428cb47a) simplesmente tenta encontrar recursivamente todos os usuários que implantaram artefatos. Observe que pode levar um tempo para ser concluído se houver muitos repositórios (> 1000).
```
./artifactory_list_users.py http://127.0.0.1:8081/artifactory
There are 23 repositories to process
Found user admin
Found user test
Found user user
Found user test_deploy
```
## Permissões <a href="#permissions" id="permissions"></a>
Aqui estão as permissões básicas e sua utilidade:
* Gerenciar: ?
* Excluir/Sobrescrever: interessante para pentest
* Implantar/Cache: interessante para pentest
* Anotar: necessário para CVE-2020-7931
* Ler: geralmente uma permissão padrão
# Vulnerabilidades conhecidas <a href="#known-vulnerabilities" id="known-vulnerabilities"></a>
Aqui está uma lista selecionada de vulnerabilidades públicas de alto impacto:
## CVE-2016-10036: Upload de arquivo arbitrário e RCE (<4.8.6) <a href="#cve-2016-10036-arbitrary-file-upload--rce-486" id="cve-2016-10036-arbitrary-file-upload--rce-486"></a>
[Detalhes aqui.](https://www.exploit-db.com/exploits/44543)
Este é um pouco antigo e é improvável que você encontre uma versão tão desatualizada do Artifactory. No entanto, é bastante eficaz, pois é uma simples travessia de diretório que permite a execução de código arbitrário no nível do Tomcat.
## CVE-2019-9733: Bypass de autenticação (<6.8.6) <a href="#cve-2019-9733-authentication-bypass-686" id="cve-2019-9733-authentication-bypass-686"></a>
[Advisory original aqui.](https://www.ciphertechs.com/jfrog-artifactory-advisory/)
Em versões mais antigas do Artifactory (até 6.7.3), a conta `access-admin` usava uma senha padrão `password`.
Esta conta local normalmente é proibida de acessar a interface do usuário ou a API, mas até a versão 6.8.6 do Artifactory, era possível enganá-lo para acreditar que a solicitação emanava localmente se o cabeçalho HTTP `X-Forwarded-For` fosse definido como `127.0.0.1`.
## CVE-2020-7931: Injeção de modelo do lado do servidor (Artifactory Pro) <a href="#cve-2020-7931-server-side-template-injection-artifactory-pro" id="cve-2020-7931-server-side-template-injection-artifactory-pro"></a>
[Advisory original aqui.](https://github.com/atredispartners/advisories/blob/master/ATREDIS-2019-0006.md)
Aqui está uma [ferramenta que escrevi](https://github.com/gquere/CVE-2020-7931) para automatizar a exploração dessa vulnerabilidade.
Esses são os requisitos para a exploração:
* um usuário com direitos de implantação (criar arquivos) e anotação (definir filtrados)
* Artifactory Pro
A vulnerabilidade é bastante simples: se um recurso implantado for definido como filtrado, ele será interpretado como um modelo Freemarker, o que dá ao atacante uma janela de ataque SSTI. ![Recurso filtrado](https://www.errno.fr/artifactory/artif_filtered.png)
Aqui estão as primitivas implementadas:
* leituras básicas do sistema de arquivos
* gravações limitadas do sistema de arquivos
Isso deve ser suficiente para dar a você a execução remota de código de várias maneiras, da mais fácil/silenciosa à mais difícil/barulhenta:
* lendo um segredo no sistema de arquivos que permite que você pivote (/home/user/.bash\_history, /home/user/password.txt, /home/user/.ssh/id\_rsa …)
* adicionando uma chave SSH ao usuário
* implantando um arquivo .war para executar um servlet
* implantando um script de usuário Groovy do Artifactory
### Histórias .war: manobras de renomeação Java renameTo() <a href="#war-stories-java-renameto-shenanigans" id="war-stories-java-renameto-shenanigans"></a>
Esta é uma pequena história de como bati minha cabeça contra a parede por horas, se não dias, durante um pentest. Encontrei um Artifactory desatualizado que sabia que era vulnerável ao CVE-2020-7931. Implantei o modelo SSTI original do advisory e comecei a percorrer o sistema de arquivos. Parecia que o Artifactory havia sido instalado em um local não padrão, o que não é muito incomum, já que os administradores gostam de manter partições separadas entre binários de aplicativos, dados, logs e configuração (isso é uma coisa boa!). Não havia chaves SSH ou senhas no diretório home do usuário que me fornecessem um pivô fácil, então chegou a hora de ser menos discreto e escrever no sistema de arquivos. O envio da carga útil inicial (uma chave pública) para o diretório de upload do Artifactory correu bem, mas eu simplesmente não conseguia movê-la para o diretório de chaves SSH. Então voltei para minha sandbox de exploração, testei novamente e, eis que funcionou bem. Então, tinha que haver uma configuração diferente que me impedisse de concluir o método `renameTo()`. Neste ponto, é sempre uma boa ideia [verificar a documentação](https://docs.oracle.com/javase/8/docs/api/java/io/File.html#renameTo-java.io.File-) ... que claramente afirma que você não pode renomear arquivos em diferentes sistemas de arquivos, o que faz sentido dependendo da implementação do método, ou seja, se ele funciona em um nível de inode. Arg.
Lembre-se do que eu disse sobre os administradores gostarem de partições? Bem, este é um caso de um administrador que endureceu sua configuração sem saber contra minha exploração! Então, tive que cavar em uma espécie de prisão Java para encontrar outro método que me permitisse gravar um arquivo no disco. E isso não foi nada divertido, já que não estou familiarizado com nada do que está envolvido: modelos FTL, Java, Tomcat/Catalina. Descobri rapidamente que as fugas regulares da prisão Java simplesmente não funcionariam, pois a instância de novas classes era proibida. Depois de horas lendo a documentação das classes Java e Catalina, finalmente encontrei um método write() em um objeto ao qual eu poderia chegar. Mas estava limitado ao caminho base da aplicação da web... Então, pensei em combinar a gravação em outro sistema de arquivos e o `renameTo()` através deste novo sistema de arquivos acessível para, esperançosamente, poder gravar em qualquer lugar? E funcionou mais ou menos. Consegui gravar fora do diretório de upload temporário ... mas não tão longe dele, pois agora estava preso em outro sistema de arquivos que era o ponto de montagem para todas as coisas do Artifactory: configuração, aplicação e coisas do tipo. Então, ainda sem chave SSH para mim.
Ok, eu poderia gravar na pasta raiz do artifactory, com certeza eu poderia fazer algo aqui? Ei, o Tomcat padrão automaticamente implanta arquivos WAR escritos em seu caminho de aplicação, não é? Então usei o msfvenom para gerar um shell da web JSP embalado em um arquivo WAR e testei na minha sandbox... bem, ele foi implantado corretamente, mas não me deu execução de comando. Parece que o Tomcat padrão não lida com JSPs. Ugh. Ficando cada vez mais frustrado, procurei outra maneira de executar código no Tomcat e encontrei outro método de execução usando servlets. Não consegui encontrar uma carga útil apropriada, então dane-se, estou tudo dentro neste ponto e [criei o meu próprio que você pode encontrar aqui](https://github.com/gquere/javaWebShell). Testei na sandbox, funciona, ok. Coloquei no alvo, implantei e ... nada. Acontece que havia um proxy na frente do artifactory que reescrevia todos os URLs para /artifactory. Então, mesmo que minha porta dos fundos estivesse implantada e em execução, não havia como acessá-la... Se houvesse alguma execução remota de código a ser alcançada neste ponto, teria que ser no contexto do Artifactory, não do Tomcat.
Na manhã seguinte, estou chorando em minha mesa olhando pela última vez a documentação do Artifactory em vãs esperanças de uma epifania. E então as palavras mágicas "scripts Groovy" apareceram. A
```
cat artifactory.hashes
user:1f70548d73baca61aab8660733c7de81${CAFEBABEEBABEFAC}
john artifactory.hashes --format=dynamic_1
Loaded 1 password hash (dynamic_1 [md5($p.$s) (joomla) 256/256 AVX2 8x3])
password (user)
```
O outro tipo de senha bcrypt não requer nada especial, é apenas um hash bcrypt padrão:
```
cat artifactory_bcrypt.hashes
admin:$2a$08$EbfHSAjPLoJnG/yHS/zmi.VizaWSipUuKAo7laKt6b8LePPTfDVeW
john artifactory_bcrypt.hashes
Loaded 1 password hash (bcrypt [Blowfish 32/64 X2])
password (admin)
```
### Segredos remotos <a href="#remote-secrets" id="remote-secrets"></a>
O Artifactory pode precisar armazenar segredos para se identificar em serviços remotos. Esses segredos não são hash, é claro, eles são armazenados criptografados no disco, com a chave ao lado deles. Existem dois tipos de segredos mencionados na [documentação oficial](https://jfrog.com/knowledge-base/what-are-the-artifactory-key-master-key-and-what-are-they-used-for/).
**Formato antigo (<5.9): DES-EDE**
TODO. [Abra um problema se você tiver dados criptografados de amostra](https://github.com/gquere/ArtifactoryDecryptor).
**Novo formato (>=5.9): criptografia AES128-CBC, armazenada como base58**
Os segredos externos (como senhas de servidores remotos) são encontrados nos [descritores de configuração](https://www.jfrog.com/confluence/display/JFROG/Configuration+Files#ConfigurationFiles-GlobalConfigurationDescriptor), por exemplo, `/var/opt/jfrog/artifactory/etc/artifactory.config.latest.xml` e parecem:
```
<keyStorePassword>AM.25rLQ.AES128.vJMeKkaK6RBRQCUKJWvYEHUw6zs394X1CrRugvJsQGPanhMgQ5be8yjWDhJYC4BEz2KRE</keyStorePassword>
```
Onde:
* `AM` sempre denota um segredo criptografado do Artifactory
* `25rLQ` é o identificador do segredo que deve corresponder ao identificador da chave
* `AES128` obviamente é o algoritmo usado
* `vJMeK...KRE` é a codificação base58 de `IV_SIZE|IV|secret|CRC`
Mais segredos podem ser encontrados (tokens, backups de configuração...) usando a seguinte expressão regular:
```
grep -r 'AM\..*\.AES128\.' /var/opt/jfrog/artifactory/
```
A chave é armazenada em `/var/opt/jfrog/artifactory/etc/security/artifactory.key` e se parece com:
```
JS.25rLQ.AES128.7fcJFd3Y2ib3wi4EHnhbvZuxu
```
Onde:
* `JS` denota uma chave
* `25rLQ` é um identificador de chave exclusivo que mantém o controle de qual chave pode descriptografar quais segredos
* `AES128` é obviamente o algoritmo usado
* `7fcJFd3Y2ib3wi4EHnhbvZuxu` é a codificação base58 da chave e 2 bytes de CRC
Esta ferramenta que escrevi pode ser usada offline para descriptografar segredos do Artifactory: [ArtifactoryDecryptor](https://github.com/gquere/ArtifactoryDecryptor).
# Defendendo o Artifactory <a href="#defending-artifactory" id="defending-artifactory"></a>
Se você é a equipe azul ou um administrador do Artifactory, agora você deve ter uma boa ideia do que fazer:
* mantenha o Artifactory atualizado, especialmente quando atualizações críticas forem emitidas
* implemente uma política de senha sólida (sem senhas padrão, senhas fortes obrigatórias, bloqueios), preferencialmente diferida para um LDAP externo para melhor supervisão
* restrinja acessos (respeite o princípio do menor privilégio), especialmente para o usuário anônimo