# Introdução 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: * Oracle Mojarra (implementação de referência JSF) * Apache MyFaces # Escopo 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). # O estado do ViewState 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. ## ViewState no lado do servidor 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**! ## ViewState no lado do cliente 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 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/). 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.** 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. # O ataque ao ViewState 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) 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: ``` ``` 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. 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: ![calculadora iniciada via um ViewState JSF](https://www.alphabot.com/images/blog/jsf-viewstate/jsf-viewstate-started-calculator.png) 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.) \=> Tudo isso demonstra uma vulnerabilidade muito perigosa de execução remota de código (RCE) não autenticada. (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.) # As precondições para um ataque bem-sucedido Agora, quais são os ingredientes para um desastre? * 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` Vamos dar uma olhada nesses pontos em relação às duas implementações JSF. # Oracle Mojarra (implementação de referência JSF) 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`. ## Mojarra: ViewState não criptografado 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). 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. 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. 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: > 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'.\ > \ > 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 > > javax.faces.STATE_SAVING_METHOD > cliente > > > > com.sun.faces.ClientStateSavingPassword > java.lang.String 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. # 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/)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 - 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)! - 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 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)**.** - **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)**.