Fundada em 2001, a OWASP (Open Web Application Security Project) é uma comunidade online que cria e disponibiliza de forma gratuita artigos, metodologias, documentação, ferramentas e tecnologias no campo da segurança de aplicações web. Seu documento mais famoso é o OWASP Top 10, que define os maiores riscos de segurança em aplicações web. A lista desses riscos são atualizadas anualmente e podem ser visualizadas gratuitamente aqui.
Para auxiliar a análise desses riscos, a OWASP criou uma ferramenta chamada ZAP (Zed Attack Proxy) e disponibilizou gratuitamente para download. O OWASP ZAP é muito utilizado de forma manual por quem está executando o teste de vulnerabilidade, mas ele também fornece um conjunto de APIs permitindo que o programador automatize através de scripts a execução dos testes.
Nesse texto, vou mostrar como executar um teste com o ZAP utilizando a linguagem Python, no sistema operacional Linux e tendo como alvo uma aplicação web contendo algumas vulnerabilidades.
Instalação do ZAP
Antes de mais nada, é necessário ter o Java instalado no seu sistema. A instalação varia de acordo com o sistema operacional e por isso não vou detalhar aqui.
A documentação do ZAP fornece diversas maneiras de instalá-lo no Linux, OSX e Windows. O modo de instalação abaixo funciona com a maioria das distribuições Linux:
wget http://bit.ly/2wBM7AT # URL encurtada do ZAP
tar zxf ZAP_2.6.0_Linux.tar.gz
mv ZAP_2.6.0 $HOME/zap
Executando o ZAP no Linux
Como disse antes, é necessário ter o Java instalado. Depois, basta entrar no diretório do ZAP e executar o script zap.sh.
cd ~/zap
sh zap.sh
A tela inicial pergunta se você quer salvar a sessão. Selecione a terceira opção e clique no botão “Start”:
Em seguida, aparecem os plugins que estão desatualizados. Você pode atualizar todos agora e esperar algum tempo ou fechar essa janela e optar por atualizar depois.
Feito isso, o ZAP está sendo executado e escutando a porta 8080, onde vão ser recebidas as requisições através da API Rest.
Rodando a aplicação web vulnerável
Existe um projeto Open Source de uma aplicação web chamado Juice Shop e serve apenas para fins de estudo. Na documentação do projeto está descrito como rodar a aplicação. O jeito mais rápido e simples é utilizando uma imagem Docker existente:
docker run -d -p 3000:3000 bkimminich/juice-shop
Com isso, a aplicação web está rodando na porta 3000.
Automatizando os testes de vulnerabilidade com Python 3
A única dependência necessária é python-owasp-zap. Instalei utilizando o gerenciador de pacotes do Python:
pip install python-owasp-zap-v2.4
Depois de instalar essa biblioteca, criei o script zap.py conforme abaixo:
cat >> zap.py <<EOF
from zapv2 import ZAPv2
from pprint import pprint
import time, sys
if len(sys.argv) is not 2:
print('Too short arguments.')
sys.exit(1)
target = sys.argv[1]
zap = ZAPv2(proxies={'http': 'http://localhost:8080'})
zap.urlopen(target)
scanid = zap.spider.scan(target)
time.sleep(2)
while (int(zap.spider.status(scanid)) < 100):
print('Spider progress %s: ' + zap.spider.status(scanid))
time.sleep(2)
print('Spider completed')
# Give the passive scanner a chance to finish
time.sleep(5)
print('Scanning target %s' % target)
scanid = zap.ascan.scan(target)
while (int(zap.ascan.status(scanid)) < 100):
print('Scan progress %: ' + zap.ascan.status(scanid))
time.sleep(5)
print('Scan completed')
# Report the results
print('Hosts: ' + ', '.join(zap.core.hosts))
pprint (zap.core.alerts())
html = zap.core.htmlreport()
with open('report_file.html', 'a') as f:
f.write(html)
EOF
O script recebe como argumento a URL da aplicação web que vai ser testada e utiliza o ZAP que está rodando em localhost na porta 8080. Para executar o script:
python zap.py http://localhost:3000
Enquanto o script é executado, a janela do ZAP exibe o que está sendo feito:
Quando o script finaliza com sucesso, ele cria o arquivo report_file.html contendo o resultado do teste:
Conclusão
Automatizar esse tipo de teste permite que eu aprimore o processo de Integração Contínua. Para quem utiliza o Jenkins, existe um plugin para trabalhar com o OWASP ZAP.