Este artigo está disponível em Inglês na PenTest Magazine e também no Pulse (LinkedIn).
Motivação
Muitos negócios na Internet são mantidos por algum tipo de serviço web. Mesmo aplicações simples executando em seu laptop ou desktop ou em seu smartphone podem depender de algum servidor web localizado por aí, como a nuvem privada da sua empresa ou ainda uma nuvem pública (AWS, Azure, Google Cloud Platform, entre outras). O boom da Web 2.0 (e as aplicações correspondentes) demanda preocupação e ação por parte de todas as pessoas envolvidas, desde empresários a desenvolvedores de aplicações e profissionais de segurança. Portanto, vamos falar um pouco de segurança web!
Se você nunca ouviu falar do OWASP (Open Web Application Security Project), recomendo fortemente a visita. Essa iniciativa é focada em Web Security e tem um documento muito interessante chamado “Top Ten”, que é relacionado aos dez riscos mais críticos em segurança para a web. Portanto, tudo é informação valiosa! Infelizmente, as estatísticas estão um pouco desatualizadas (2013), mas ainda são muito úteis. Observe que “SQL Injection” e “Cross-Site Scripting (XSS)” ainda se encontram no topo. Os caras do OWASP estão trabalhando numa atualização futura desse documento.
A figura 1 mostra o Relatório Anual de Segurança da Cisco de 2016. Pode-se perceber que Web Security é uma preocupação crescente, independentemente se as ferramentas de segurança estão on-premises ou se são administradas por algum serviço baseado em nuvem.
Figura 1: Relatório Anual de Segurança da Cisco para 2016
Introdução
Eu apresento o ZAP (Zed Attack Proxy), um web scanner bem completo e versátil, focado em dois objetivos: ser fácil de usar e ainda muito poderoso. O ZAP é um dos dois projetos de Web Scanners mantidos pelo OWASP. Escolhi cobri-lo, basicamente por conta de três pontos:
- É open source;
- Tem uma documentação muito boa (incluindo vídeos de tutorial);
- Suporta múltiplas plataformas (Windows, Linux e macOS).
O ZAP está disponível aqui, mas também possui um repositório no Github, onde é possível encontrar o próprio código, assim como referências à API, guias de usuário, plugins e mais.
Algumas características básicas do ZAP incluem:
- Intercepting Proxy: um proxy transparente entre seu browser de teste e a aplicação;
- Scanners Ativos e Passivos: você pode escolher apenas descobrir vulnerabilidades ou realmente atacar o alvo;
- Spider: para lidar com código em AJAX;
- Geração de Relatórios: os formatos possíveis são HTML, XML e texto limpo;
- Código de Bruce Force: ele emprega o DirBuster do OWASP;
- Fuzzing: implementado através do fuzzed ou do OWASP JBroFuzz;
- Extensão de Código via plugins: saiba mais aqui.
Com a ajuda de ferramentas e bibliotecas tão conhecidas, o ZAP se mostra como uma opção excelente para realizar pentest em aplicações web, sendo você um novato ou um profissional experiente.
With the help of so great well-known tools and libraries, ZAP shows itself is a cool option to pentesting web apps, being you a novice or an experienced professional.
Web Security é uma preocupação crescente, independentemente se as ferramentas de segurança estão on-premises ou se são administradas por algum serviço baseado em nuvem.
Alvo
Antes de começar a usar o ZAP, é preciso escolher o alvo. A documentação do projeto menciona, várias vezes, que você deve ser autorizado para executar o pentest no alvo escolhido.
Obviamente, não usarei nenhum sistema em produção sob minha responsabilidade (ou de qualquer outra pessoa). Portanto, implementei um servidor Tomcat na mesma VM de laboratório com Ubuntu. Baixei o BodgeIT, primariamente por conta de possuir os mesmos requisitos Java que o ZAP e também porque ele possui brechas que podem ser exploradas de maneira fabulosa. Para completar, o BodgeIT menciona o ZAP como uma escolha para pentest.
Depois de baixar o arquivo zip, dê uma olhada no arquivo Dockerfile. Ele contém algumas linhas relacionadas ao arquivo certo para ser usado. A versão atual do BodgeIT implementa uma imagem em Docker. Se você deseja usá-la, acesse este link. Se você não deseja usá-la (ou não possui o Docker), pode simplesmente baixar o arquivo war e copiá-lo para o diretório webapps do Tomcat, usando o comando abaixo (pode ser necessário rolar o snippet para vê-lo por completo).
curl -s -L https://github.com/psiinon/bodgeit/releases/download/1.4.0/bodgeit.war > bodgeit.war | mv /usr/local/tomcat/webapps
Observe que o comando original inclui uma parte “mv” para mover o arquivo para o diretório webapps do Tomcat. Entretanto, minha instalação não possui um diretório “/usr/local/tomcat/webapps”. Assim, alterei o comando para mover o arquivo para meu diretório “/var/lib/tomcat7/webapps”.
Caso você ainda não saiba, assim que o arquivo .war for copiado para o diretório webapps, o Tomcat extrairá o conteúdo do mesmo e construirá a estrutura correta de diretórios para suportar a aplicação. Esta é uma operação automática e facilmente verificável:
$ pwd /var/lib/tomcat7/webapps $ ls -lh total 1004K drwxr-xr-x 7 tomcat7 tomcat7 4,0K Jan 7 20:14 bodgeit -rw-r--r-- 1 root root 993K Jan 7 20:14 bodgeit.war drwxr-xr-x 3 root root 4,0K Jan 7 17:21 ROOT $ ls -lhp bodgeit total 124K -rw-r--r-- 1 tomcat7 tomcat7 368 Jul 30 2012 about.jsp -rw-r--r-- 1 tomcat7 tomcat7 2,8K Jul 30 2012 admin.jsp -rw-r--r-- 1 tomcat7 tomcat7 6,7K Jul 30 2012 advanced.jsp -rw-r--r-- 1 tomcat7 tomcat7 11K Jul 30 2012 basket.jsp -rw-r--r-- 1 tomcat7 tomcat7 3,8K Jul 30 2012 contact.jsp -rw-r--r-- 1 tomcat7 tomcat7 68 Jul 30 2012 footer.jsp -rw-r--r-- 1 tomcat7 tomcat7 3,1K Jul 30 2012 header.jsp -rw-r--r-- 1 tomcat7 tomcat7 2,2K Jul 30 2012 home.jsp drwxr-xr-x 2 tomcat7 tomcat7 4,0K Jan 7 20:14 images/ -rw-r--r-- 1 tomcat7 tomcat7 14K Jul 30 2012 init.jsp drwxr-xr-x 2 tomcat7 tomcat7 4,0K Jan 7 20:14 js/ -rw-r--r-- 1 tomcat7 tomcat7 4,1K Jul 30 2012 login.jsp -rw-r--r-- 1 tomcat7 tomcat7 291 Jul 30 2012 logout.jsp drwxr-xr-x 2 tomcat7 tomcat7 4,0K Jan 7 20:14 META-INF/ -rw-r--r-- 1 tomcat7 tomcat7 2,5K Jul 30 2012 password.jsp -rw-r--r-- 1 tomcat7 tomcat7 4,7K Jul 30 2012 product.jsp -rw-r--r-- 1 tomcat7 tomcat7 4,8K Jul 30 2012 register.jsp -rw-r--r-- 1 tomcat7 tomcat7 2,2K Jul 30 2012 score.jsp -rw-r--r-- 1 tomcat7 tomcat7 3,4K Jul 30 2012 search.jsp -rw-r--r-- 1 tomcat7 tomcat7 475 Jul 30 2012 style.css drwxr-xr-x 2 tomcat7 tomcat7 4,0K Jan 7 20:14 tests/ drwxr-xr-x 4 tomcat7 tomcat7 4,0K Jan 7 20:14 WEB-INF/
Você pode verificar o processo acompanhando a saída do arquivo /var/log/tomcat7/catalina.out (ignore as mensagens de warning):
INFO: Deploying web application archive /var/lib/tomcat7/webapps/bodgeit.war Jan 07, 2017 8:14:54 PM org.apache.catalina.loader.WebappClassLoaderBase validateJarFile INFO: validateJarFile(/var/lib/tomcat7/webapps/bodgeit/WEB-INF/lib/servlet-api.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class Jan 07, 2017 8:14:55 PM org.apache.catalina.startup.TldConfig execute INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. Jan 07, 2017 8:14:57 PM org.apache.catalina.startup.HostConfig deployWAR INFO: Deployment of web application archive /var/lib/tomcat7/webapps/bodgeit.war has finished in 2,714 ms
Instalação
A versão em uso quando da escrita deste artigo era a 2.5.0. Baixe o binário correto para sua plataforma e escolha ou escolha a versão cross-plataforma. Minha VM de laboratório está usando Ubuntu 16.04.1 (Xenial) com as últimas atualizações. Você pode testar a versão em Docker se preferir. Usuários do macOS podem também baixar e instalar o ZAP automaticamente através do brew.
Entretanto, não há procedimento específico de instalação. O ZAP depende do Java. O script de carga verificará a existência do JRE ou JDK e tentará usá-lo se possível. Se algo der errado, você receberá uma mensagem de erro correspondente. Execute o “zap.sh” para iniciar o ZAP:
$ ./zap.sh Found Java version 1.8.0_111 Available memory: 2000 MB Setting jvm heap size: -Xmx512m 710 [main] INFO org.zaproxy.zap.GuiBootstrap - OWASP ZAP 2.5.0 started. Jan 07, 2017 8:30:03 PM java.util.prefs.FileSystemPreferences$1 run INFO: Created user preferences directory
Depois de algumas verificações iniciais, uma janela com o acordo de licença do ZAP será exibida:
Figura 2: Acordo de licença do ZAP
Aqui, você deve prestar atenção a um ponto: o ZAP e o Tomcat usam a mesma porta padrão (TCP/8080). Portanto, se você, assim como eu, estiver usando os dois no mesmo sistema, verá a figura 3. Assim, após tentar carregar, receberá uma mensagem de erro como esta:
Figura 3: Mensagem de erro relacionada à porta
Na linha de comando, você receberá:
17173 [ZAP-BootstrapGUI] ERROR org.parosproxy.paros.core.proxy.ProxyServer - Failed to start the proxy server: java.net.BindException: Address already in use (Bind failed) at java.net.PlainSocketImpl.socketBind(Native Method) …
Como estou usando uma instalação controlada do Tomcat, foi fácil para mim mudar a porta. Para fazê-lo, basta editar o arquivo /etc/tomcat7/server.xml e alterar todas as ocorrências de 8080 dos trechos abaixo para alguma porta disponível no seu sistema. Salve o arquivo e reinicie o Tomcat. Usei a porta 8181.
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443" /> <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
Com a ajuda de ferramentas e bibliotecas tão conhecidas, o ZAP se mostra como uma opção excelente para realizar pentest em aplicações web, sendo você um novato ou um profissional experiente.
Uso Básico
Um dos primeiros conceitos aos quais se deve ficar atento é a persistência da base de dados. Por default, o ZAP perde todo seu trabalho de pentesting assim que é fechado. No entanto, esse comportamento pode ser alterado ao se escolher uma das opções de persistência. Isso pode ser feito na caixa de diálogo inicial ou em Tools->Options->Database.
Depois disso, é preciso configurar o browser para usar o ZAP como proxy. Isto está bem coberto na documentação oficial. Em caso de você estar tentando testar a aplicação no mesmo host em que o ZAP está rodando, um ponto que deve ser levado em conta é permitir o proxy mesmo para o localhost. Todos os browsers possuem esta configuração. Assim, quando configurando, deixe em banco o campo relativo a “excluir proxy para …” (ou algo similar).
Se você for testar alguma aplicação em HTTPS, deve importar no seu browser o certificado auto-gerado pelo ZAP. A partir da interface do ZAP, o certificado por ser exportado em Tools->Options->Dynamic SSL Certificates->Save.
Depois de acessar meu BodgeIT local, a tela do ZAP ficou preenchida assim:
Figura 4: Tela inicial do ZAP após a primeira carga do BodgeIT
Para cada site que você visitar, é possível obter mais detalhes na aba do lado esquerdo superior. Quando você seleciona o site, as requisições e respostas são mostradas na aba do lado direito superior. Na aba de baixo, pode-se ter acesso a ferramentas e resultados.
Você pode ver que todos os objetos HTTP (ou HTTPS) requisitados são capturados pelo ZAP. Pode-se inclusive obter os conteúdos HTML quando se executa o script correspondente. Por falar em scripts, eles são acessíveis na aba esquerda superior. Clique no sinal “+” e adicione a aba de scripts. Há um conjunto de categorias e templates para usar.
Depois de acessar algumas páginas web, insira o site do BodgeIT em um contexto. Isso simplificará procedimentos futuros relacionados aos componentes do site, como páginas dinâmicas, conteúdo estático e queries. Para fazer isso, simplesmente clique com o botão direito do mouse sobre o site na aba esquerda superior (Figura 4) e escolha “Include in Context”. Você pode escolher o default ou criar um novo. Prefira criar um novo para evitar misturá-lo com o contexto default.
Se seu único interesse é checar as brechas de segurança do site, pode ir para a aba “Quick Start”, clicar no botão “Select” e escolher o alvo (ou digitá-lo manualmente) e então, iniciar o ataque. Você verá que o ZAP abre muitas abas manualmente na parte de baixo da janela. Ele conduz vários testes tentando ir tão além quanto possível e mostrar as vulnerabilidades (Figura 5). Alertas descobertos são categorizados como bandeiras coloridas e mostrados no canto inferior direito. Para este teste, dois alertas vermelhos foram disparados.
Figura 5: ZAP executando um ataque
Agora, clique na aba Alerts para ver o que foi encontrado:
Figura 6: Alertas vermelhos no alvo
O ZAP encontrou dois dos riscos Top Ten do OWASP. Para cada alerta, juntamente com uma breve descrição da brecha de segurança, o programa mostra uma pequena dica sobre como corrigir o problema. Num cenário real, você deveria relatar suas descobertas.
Para o infinito e além!
O recurso quick attack é muito interessante e útil para se ter uma visão geral do que o alvo pode oferecer em termos de riscos e brechas. No entanto, você pode seguir no seu ritmo e usar cada recurso do ZAP um a um.
Uma coisa que pode ser feita daqui é mexer com autenticações. Muitos sites possuem algum tipo de autenticação (protegida ou não). O BodgeIT tem um formulário HTTP específico para registro e login de usuários. Após alguma navegação, incluindo sua permanência neste formulário, o ZAP automaticamente armazena a página correspondente em seu histórico e nas informações de sessão. Para tornar a configuração de autenticação mais fácil, faça o seguinte:
- Procure o elemento “POST… login.jsp”;
- Clique com o botão direito e escolha Flag as Context->”Your Context”:Form-based request;
- Na janela, mude o parâmetro “User name parameter *” para o nome de usuário e clique em OK.
Isto informa ao ZAP que página considerar como código de autenticação e em quais campos ele pode encontrar o nome de usuário e a senha. Veja a próxima figura.
Figura 7: Configurando reconhecimento automático de autenticação
De volta à linha “POST”, observe a aba Response à direita. Você precisa encontrar um string que possa ser informada ao ZAP como ele consegue saber quando um usuário está conectado. No BodgeIT, cada vez que alguém faz login, todas as outras páginas mostram um link de logout. Na aba Response, procure por isto:
<a href=”logout.jsp”>Logout</a>
Você não precisa copiar e colar isso manualmente. Selecione esta porção de texto, clique com o botão direito e escolha Flag as Context->”Your Context”:Authentication Logged-In Indicator. Quando fizer isso, a janela de propriedades da sessão é exibida novamente e a string selecionada preenche o campo de texto correspondente (Logged-in pattern). O ZAP automaticamente coloca “\Q” and “\E” respectivamente no começo e fim da linha. Isto representa uma regex (expressão regular).
Antes de fechar a janela, clique em “Users” para adicionar usuários do site manualmente ao ZAP. Isto será útil se você fizer login com um nome de usuário e tentar espionar o site com outro nome de usuário. Isto não deveria ser possível de se fazer se os mecanismos corretos de isolamento estivessem funcionais. Mas, este não é o caso do BodgeIT. 😉
Assim, no BodgeIT, registre cada usuário que você criou no ZAP. Depois disso, escolha um deles para fazer login. Se não estiver certo qual o usuário está logado, veja o canto superior direito. O username será apresentado lá. De volta ao ZAP, clique no nome da aplicação na aba esquerda (bodgeit) e escolha Attack->Spider… Isto abrirá uma janela cujos campos ponto de início e contexto são automaticamente preenchidos. Você deve escolher um nome de usuário. Escolha um que não esteja conectado. Clique em Start Scan e observe o ZAP fazer um web crawl no site completo. Muitas páginas são descobertas e colocadas na aba esquerda, incluindo aquelas relacionadas ao carrinho de compras (o que não deveria ocorrer). Repita o mesmo procedimento com o usuário que já está conectado.
Para testar o princípio de least privilege (você só tem acesso a partes de um sistema que são realmente acessíveis a você), é possível enviar informação para o site como um username específico e ver o quão longe um usuário regular ode ir. Para fazer isso, execute o seguinte:
- Clique no botão “Session Properties…” na barra de menu;
- Localize seu contexto (aquele criado anteriormente);
- Clique em OK;
- Localize e clique para ativar o botão “Forced User Mode” na barra de menu;
- Execute tarefas posteriores para testar a aplicação do nome de usuário escolhido.
Gerando Relatórios
Depois de usar a ferramenta, é hora de gravar as descobertas. Clique em Report->Generate HTML Report… Dê um nome para o arquivo e clique em OK. Uma nova aba de browser (ou janela) será aberta com o relatório criado.
Figura 8: Relatório HTML de exemplo do ZAP
Você pode escolher exportar apenas parte da mensagem ou histórico de resposta para o arquivo. O ZAP também permite comparar as descobertas com outra sessão salva anteriormente e exportar os resultados no formato XML. Mensagens e respostas são salvas em texto limpo.
Ferramentas Adicionais
O ZAP possui um menu bem completo que permite executar diversas tarefas interessantes, tais como:
- Criar e submeter requests personalizados para o site;
- Codificar e decodificar hashes em um conjunto de formatos (BASE64, Javascript, HTML, …);
- Criar e ativar breakpoints através de sua análise;
- Checar sintaxe e uso da API;
- Executar o Garbage Collector para fazer uma “limpeza da casa”;
- Enviar sua própria mensagem WebSocket;
- Brincar com Fuzzing.
E não se pode esquecer as extensões. O projeto ZAP tem um conjunto generoso de plugins prontos para uso. Eles todos estão disponíveis através do botão de três cores e suscetíveis a atualizações individuais. Teste alguns.
Conclusão
Depois de expor este panorama, devo dizer que o ZAP é uma ferramenta impressionante, não apenas porque é estável e fácil de usar, mas especialmente porque é completo. Além do mais, gratuito e de código aberto!
No começo de minha jornada através dele, pensei que a dependência do Java fosse tornar as coisas piores. Nós bem sabemos que o Java é uma plataforma ampla, mas que poderia impor alguns problemas de compatibilidade ou transformar a tarefa em um processo de troubleshoot infinito. Para minha surpresa, ele rodou de forma suave em minha VM de laboratório e deve funcionar da mesma forma em qualquer outra situação. Como meus dois centavos de contribuição, seria incrível se o relatório pudesse ser gerado em formato JSON. Isto facilitaria a análise através de ferramentas de terceiros e meu próprio conjunto de scripts usando bases de dados do tipo key-value pairs.
É um software que você deve considerar quando executando seus pentests. Definitivamente!
3 comentários
Jeremias Mariano · 2021-02-13 às 17:37
Artigo muito bom para começar no OwaspZap. Obrigado
Maurício Harley · 2021-02-15 às 18:16
Olá, Jeremias.
Obrigado pela visita. Fico feliz que tenha gostado. Sinta-se à vontade para sugerir novos artigos para o blog.
Abraço,
Maurício
Maltego e a Enumeração de Redes | Blog itHarley · 2017-10-10 às 01:42
[…] (JRE) para funcionar. Se você já está familiarizado com meus artigos, pode já ter lido meu texto sobre o ZAP (Zed Attack Proxy). Ele também possui esta dependência. Independente de qualquer discussão inútil sobre […]