hacktricks/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization.md

179 lines
16 KiB
Markdown
Raw Normal View History

2023-06-06 18:56:34 +00:00
# Introdução
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
Depois de analisarmos [RCEs através de bibliotecas JSON mal configuradas](https://www.alphabot.com/security/blog/2017/net/How-to-configure-Json.NET-to-create-a-vulnerable-web-API.html), começamos a analisar os ViewStates das implementações JSF. [JavaServer Faces (JSF)](https://en.wikipedia.org/wiki/JavaServer_Faces) é uma tecnologia de interface do usuário (UI) para construir UIs da web com componentes reutilizáveis. JSF é usado principalmente para aplicativos empresariais e uma implementação JSF é tipicamente usada por um aplicativo da web que é executado em um servidor de aplicativos Java como JBoss EAP ou WebLogic Server. Existem duas implementações bem conhecidas da especificação JSF:
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
* Oracle Mojarra (implementação de referência JSF)
* Apache MyFaces
2023-06-06 18:56:34 +00:00
# Escopo
2023-06-06 18:56:34 +00:00
Esta postagem no blog se concentra nas duas implementações JSF 2.x: Oracle Mojarra (Implementação de Referência) e Apache MyFaces. Implementações mais antigas (JSF 1.x) também provavelmente são afetadas pelas vulnerabilidades descritas nesta postagem. (JSF 2.0.x foi lançado inicialmente em 2009, a versão atual é 2.3.x).
2023-06-06 18:56:34 +00:00
# O estado do ViewState
2023-06-06 18:56:34 +00:00
Uma diferença entre JSF e tecnologias web semelhantes é que JSF usa ViewStates (além de sessões) para armazenar o estado atual da visualização (por exemplo, quais partes da visualização devem ser exibidas atualmente). O ViewState pode ser armazenado no `servidor` ou no `cliente`. Os ViewStates do JSF são normalmente automaticamente incorporados em formulários HTML como um campo oculto com o nome `javax.faces.ViewState`. Eles são enviados de volta para o servidor se o formulário for enviado.
2023-06-06 18:56:34 +00:00
## ViewState no lado do servidor
2023-06-06 18:56:34 +00:00
Se o ViewState do JSF estiver configurado para ficar no `servidor`, o campo oculto `javax.faces.ViewState` contém um ID que ajuda o servidor a recuperar o estado correto. No caso do MyFaces, esse ID é um **objeto Java serializado**!
2023-06-06 18:56:34 +00:00
## ViewState no lado do cliente
2023-06-06 18:56:34 +00:00
Se o ViewState do JSF estiver configurado para ficar no `cliente`, o campo oculto `javax.faces.ViewState` contém um **objeto Java serializado** que é pelo menos codificado em Base64. Você pode ter percebido até agora que esta é uma estrada potencial para o desastre! Esse pode ser um dos motivos pelos quais os ViewStates do JSF são criptografados e assinados antes de serem enviados para o cliente. Os perigos de objetos Java serializados
2023-06-06 18:56:34 +00:00
Em 2015, na conferência AppSec California, [Gabriel Lawrence](https://twitter.com/gebl) e [Chris Frohoff](https://twitter.com/frohoff) realizaram uma apresentação com o título [Marshalling Pickles (how deserializing objects can ruin your day)](https://frohoff.github.io/appseccali-marshalling-pickles/). Esta apresentação lançou alguma luz sobre problemas esquecidos com a serialização de objetos Java e levou à descoberta de [várias vulnerabilidades graves de execução remota de código (RCE)](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/).
2023-06-06 18:56:34 +00:00
Infelizmente, levou algumas pessoas a acreditar que a vulnerabilidade poderia ser mitigada removendo/atualizando certas versões do Apache Commons Collections. Uma ação que pode realmente ajudar, mas não resolve a causa raiz do problema: Desserialização de Dados Não Confiáveis ([CWE 502](https://cwe.mitre.org/data/definitions/502.html)). Em outras palavras:\
**O uso de uma versão do Apache Commons Collections 'vulnerável' não significa que o aplicativo é vulnerável, nem a ausência de tal versão de biblioteca significa que o aplicativo não é vulnerável.**
2023-06-06 18:56:34 +00:00
No entanto, depois que um hacker malicioso [desligou e criptografou os sistemas da San Francisco Municipal Transportation Agency](https://krebsonsecurity.com/2016/11/san-francisco-rail-system-hacker-hacked/) via "Mad Gadget"/"Apache Commons Collections Deserialization Vulnerability", o Google iniciou a [Operação Rosehub](https://opensource.googleblog.com/2017/03/operation-rosehub.html). O objetivo da operação Rosehub era encontrar o maior número possível de projetos de código aberto Java que usavam uma versão de coleções comuns 'amigável ao atacante' como dependência e enviar solicitações pull aos proprietários do projeto para que esses projetos parassem de usar versões problemáticas de coleções comuns em novas versões.
2023-06-06 18:56:34 +00:00
# O ataque ao ViewState
2023-06-06 18:56:34 +00:00
Vamos supor que temos um aplicativo da web com uma página de login baseada em JSF:
![JSF based login](https://www.alphabot.com/images/blog/jsf-viewstate/jsf-viewstate-login.png)
2023-06-06 18:56:34 +00:00
Essa página de login tem um ViewState que não é criptografado nem assinado. Então, quando olhamos para sua fonte HTML, vemos um campo oculto contendo o ViewState: ViewState MyFaces não criptografado:
```
<input type="hidden" name="javax.faces.ViewState" id="j_id__v_0:javax.faces.ViewState:1" value="rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s" autocomplete="off" />
```
2023-06-06 18:56:34 +00:00
Se você decodificar o ViewState acima usando Base64, você notará que ele contém um objeto Java serializado. Este ViewState é enviado de volta para o servidor via POST quando o formulário é enviado (por exemplo, clique em Login). Agora, antes que o ViewState seja enviado de volta para o servidor, o invasor substitui o ViewState por seu próprio ViewState malicioso usando um gadget que já está no classpath do servidor (por exemplo, `InvokerTransformer` de commons-collections-3.2.1.jar) ou até mesmo um gadget que ainda não é conhecido pelo público. Com o gadget malicioso colocado no ViewState, o invasor especifica quais comandos deseja executar no servidor. A flexibilidade do que um invasor pode fazer é limitada pelos poderes dos gadgets disponíveis no classpath do servidor. No caso do `InvokerTransformer`, o invasor pode especificar quais comandos de linha de comando devem ser executados no servidor. O invasor em nosso exemplo escolheu iniciar uma calculadora na interface do nosso servidor baseado em Linux.
2023-06-06 18:56:34 +00:00
Depois que o invasor enviou seu formulário modificado de volta para o servidor, a implementação JSF tenta desserializar o ViewState fornecido. Agora, mesmo antes que a desserialização do ViewState tenha terminado, o comando é executado e a calculadora é iniciada no servidor:
2023-06-06 18:56:34 +00:00
![calculadora iniciada via um ViewState JSF](https://www.alphabot.com/images/blog/jsf-viewstate/jsf-viewstate-started-calculator.png)
2023-06-06 18:56:34 +00:00
Tudo aconteceu antes que a implementação JSF pudesse dar uma olhada no ViewState e decidir que não era bom. Quando o ViewState foi considerado inválido, geralmente um erro é enviado de volta ao cliente como "Expiração da visualização". Mas então já é tarde demais. O invasor teve acesso ao servidor e executou comandos. (A maioria dos invasores do mundo real não inicia uma calculadora, mas geralmente implantam um shell remoto, que eles usam para acessar o servidor.)
2023-06-06 18:56:34 +00:00
\=> Tudo isso demonstra uma vulnerabilidade muito perigosa de execução remota de código (RCE) não autenticada.
2023-06-06 18:56:34 +00:00
(Quase o mesmo cenário de ataque contra JSF como descrito acima já foi delineado e demonstrado na apresentação de 2015 (páginas 65 a 67): [Marshalling Pickles](https://frohoff.github.io/appseccali-marshalling-pickles/) realizada por Frohoff e Lawrence.)
2023-06-06 18:56:34 +00:00
# As precondições para um ataque bem-sucedido
2023-06-06 18:56:34 +00:00
Agora, quais são os ingredientes para um desastre?
2023-06-06 18:56:34 +00:00
* ViewState não criptografado (ou posse da chave de criptografia)
* Gadget no classpath do servidor
* No caso do Mojarra: ViewState configurado para residir no `cliente`
* No caso do MyFaces: ViewState configurado para residir no `cliente` **ou** no `servidor`
2023-06-06 18:56:34 +00:00
Vamos dar uma olhada nesses pontos em relação às duas implementações JSF.
2023-06-06 18:56:34 +00:00
# Oracle Mojarra (implementação de referência JSF)
2023-06-06 18:56:34 +00:00
Como dito antes, o Oracle Mojarra é a Implementação de Referência (RI) do JSF, mas pode não ser conhecido por esse nome. Pode ser conhecido como Sun JSF RI, reconhecido com o nome do pacote java `com.sun.faces` ou com o nome ambíguo do jar `jsf-impl.jar`.
2023-06-06 18:56:34 +00:00
## Mojarra: ViewState não criptografado
2023-06-06 18:56:34 +00:00
Então aqui está a coisa: o Mojarra não criptografou e assinou o ViewState do lado do cliente por padrão na maioria das versões de 2.0.x e 2.1.x. É importante observar que um ViewState do lado do servidor é o padrão em ambas as implementações JSF, mas um desenvolvedor poderia facilmente mudar a configuração para usar um ViewState do lado do cliente definindo o parâmetro `javax.faces.STATE_SAVING_METHOD` como `cliente`. O nome do parâmetro não revela de forma alguma que mudá-lo para cliente introduz vulnerabilidades graves de execução remota de código (por exemplo, um ViewState do lado do cliente pode ser usado em aplicativos da web em cluster).
2023-06-06 18:56:34 +00:00
Embora a criptografia do ViewState do lado do cliente seja o padrão no Mojarra 2.2 e em versões posteriores, não era para os ramos 2.0.x e 2.1.x. No entanto, em maio de 2016, os desenvolvedores do Mojarra começaram a retroportar a criptografia padrão do ViewState do lado do cliente para [2.0.x](https://github.com/javaserverfaces/mojarra/issues/4142) e [2.1.x](https://github.com/javaserverfaces/mojarra/issues/4141) quando perceberam que ViewStates não criptografados levam a vulnerabilidades de RCE.
2023-06-06 18:56:34 +00:00
Portanto, pelo menos a versão [2.1.29-08](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-08) (lançada em julho de 2016) do ramo 2.1.x e a versão [2.0.11-04](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.0.11-04) (também lançada em julho de 2016) do ramo 2.0.x têm a criptografia habilitada por padrão.
2023-06-06 18:56:34 +00:00
Quando analisamos as bibliotecas do Mojarra, notamos que a Red Hat também lança versões do Mojarra para os ramos 2.1.x e 2.0.x, sendo a mais recente [2.1.29-jbossorg-1](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.1.29-jbossorg-1) e [2.0.4-b09-jbossorg-4](https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.0.4-b09-jbossorg-4). Como ambos os lançamentos estavam sem criptografia padrão do ViewState, entramos em contato com a Red Hat e eles prontamente criaram o [Bug 1479661 - JSF client side view state saving deserializes data](https://bugzilla.redhat.com/show_bug.cgi?id=1479661) em seu bugtracker com o seguinte conselho de mitigação para o ramo 2.1.x:
2023-06-06 18:56:34 +00:00
> Uma aplicação web vulnerável precisa ter definido javax.faces.STATE_SAVING_METHOD como 'cliente' para habilitar o salvamento de ViewState do lado do cliente. O valor padrão no Enterprise Application Platform (EAP) 6.4.x é 'servidor'.\
> \
2023-06-06 18:56:34 +00:00
> Se javax.faces.STATE_SAVING_METHOD estiver definido como 'cliente', uma mitigação para esse problema é criptografar a visualização definindo com.sun.faces.ClientStateSavingPassword no web.xml da aplicação:
>
> ```markup
> <context-param>
> <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
2023-06-06 18:56:34 +00:00
> <param-value>cliente</param-value>
> </context-param>
>
> <env­-entry>
> <env­-entry-­name>com.sun.faces.ClientStateSavingPassword</env­-entry-­name>
2023-06-06 18:56:34 +00:00
> <env-­entry-­type>java.lang.String</env-­entry
```python
#!/usr/bin/python3
import sys
import hmac
from urllib import parse
from base64 import b64encode
from hashlib import sha1
from pyDes import *
YELLOW = "\033[93m"
GREEN = "\033[32m"
def encrypt(payload,key):
cipher = des(key, ECB, IV=None, pad=None, padmode=PAD_PKCS5)
enc_payload = cipher.encrypt(payload)
return enc_payload
def hmac_sig(enc_payload,key):
hmac_sig = hmac.new(key, enc_payload, sha1)
hmac_sig = hmac_sig.digest()
return hmac_sig
key = b'JsF9876-'
if len(sys.argv) != 3 :
print(YELLOW + "[!] Usage : {} [Payload File] [Output File]".format(sys.argv[0]))
else:
with open(sys.argv[1], "rb") as f:
payload = f.read()
f.close()
print(YELLOW + "[+] Encrypting payload")
print(YELLOW + " [!] Key : JsF9876-\n")
enc_payload = encrypt(payload,key)
print(YELLOW + "[+] Creating HMAC signature")
hmac_sig = hmac_sig(enc_payload,key)
print(YELLOW + "[+] Appending signature to the encrypted payload\n")
payload = b64encode(enc_payload + hmac_sig)
payload = parse.quote_plus(payload)
print(YELLOW + "[*] Final payload : {}\n".format(payload))
with open(sys.argv[2], "w") as f:
f.write(payload)
f.close()
print(GREEN + "[*] Saved to : {}".format(sys.argv[2]))
```
2023-06-06 18:56:34 +00:00
# Detecção de Chave Conhecida com Badsecrets
2023-06-06 18:56:34 +00:00
![Badsecrets](https://github.com/blacklanternsecurity/badsecrets) é uma biblioteca capaz de detectar o uso de chaves criptográficas conhecidas, olhando para os produtos que elas produzem e verificando em uma lista de chaves conhecidas ou fracas. Seu módulo `Jsf_viewstate` é capaz de detectar Java Server Faces ViewStates criados com chaves conhecidas em ambos Mojarra e MyFaces, além de ViewStates desprotegidos ou comprimidos.
2023-03-24 21:40:35 +00:00
2023-06-06 18:56:34 +00:00
A maneira mais rápida de usá-lo é com a ferramenta de exemplo `cli.py`, da seguinte forma:
2023-03-24 21:40:35 +00:00
```
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/cli.py Ly8gp+FZKt9XsaxT5gZu41DDxO74k029z88gNBOru2jXW0g1Og+RUPdf2d8hGNTiofkD1VvmQTZAfeV+5qijOoD+SPzw6K72Y1H0sxfx5mFcfFtmqX7iN6Gq0fwLM+9PKQz88f+e7KImJqG1cz5KYhcrgT87c5Ayl03wEHvWwktTq9TcBJc4f1VnNHXVZgALGqQuETU8hYwZ1VilDmQ7J4pZbv+pvPUvzk+/e2oNeybso6TXqUrbT2Mz3k7yfe92q3pRjdxRlGxmkO9bPqNOtETlLPE5dDiZYo1U9gr8BBQ=
```
2023-06-06 18:56:34 +00:00
Se encontrar uma correspondência, também listará a plataforma (Mojarra ou MyFaces), o algoritmo de criptografia em uso e se a compressão foi usada ou não, que são todos essenciais para a exploração.
2023-03-24 21:40:35 +00:00
2023-06-06 18:56:34 +00:00
Para procurar por viewstates vulneráveis em escala, em conjunto com a enumeração de subdomínios, o módulo `badsecrets` [**BBOT**]() pode ser usado:
2023-03-24 21:40:35 +00:00
```
bbot -f subdomain-enum -m badsecrets -t evil.corp
```
2023-06-06 18:56:34 +00:00
# Considerações finais
2023-03-24 21:40:35 +00:00
2023-06-06 18:56:34 +00:00
A maioria dos fatos sobre JSF ViewStates e seus perigos apresentados neste post não são exatamente novos, mas parece que nunca foram apresentados de forma tão condensada. Isso mostrou [mais uma vez](https://www.alphabot.com/security/blog/2017/net/How-to-configure-Json.NET-to-create-a-vulnerable-web-API.html) que mudanças de configuração aparentemente inofensivas podem levar a vulnerabilidades graves.
2023-06-06 18:56:34 +00:00
\=> Um dos problemas parece ser a falta de transferência de conhecimento entre pesquisadores de segurança e desenvolvedores que realmente usam e configuram bibliotecas que podem ser perigosas quando configuradas de certas maneiras.
2023-06-06 18:56:34 +00:00
# Referências
* [https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html](https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html)
* [https://0xrick.github.io/hack-the-box/arkham/](https://0xrick.github.io/hack-the-box/arkham/)
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<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>
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Você trabalha em uma **empresa de cibersegurança**? Quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- 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)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do 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)**.**
2022-04-28 16:01:33 +00:00
2023-06-06 18:56:34 +00:00
- **Compartilhe seus truques de hacking enviando PRs para o [repositório hacktricks](https://github.com/carlospolop/hacktricks) e [hacktricks-cloud repo](https://github.com/carlospolop/hacktricks-cloud)**.
2022-04-28 16:01:33 +00:00
</details>