Files
FSI/relatorio/relatorio.tex
2026-05-31 13:14:42 +01:00

243 lines
12 KiB
TeX
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.
\documentclass[11pt,a4paper]{article}
\usepackage[portuguese]{babel}
\usepackage[lining]{ebgaramond}
\usepackage{style}
\setlength{\parindent}{0em}
\setlength{\parskip}{2ex}
\title{Practical Assignment \#3}
\author{
João Neto -- 2023234004\\[1em]
Vasco Alves -- 2022228207
}
\begin{document}
\maketitle
\newpage
\tableofcontents
\newpage
\section{Introduction}
Este trabalho tem como objetivo realizar testes de penetração numa aplicação
cobaia (o \textit{Juicebox}) desenhada para aprendizagem.
\section{Architecture Considered for Both Stages}
Utilizámos somente duas máquinas virtuais: um servidor a correr \textit{CentOS 9}
e um cliente a correr \textit{Kali Linux}. O servidor contém o serviço \textit{Apache},
que age como \textit{firewall} através do módulo \textit{ModSecurity}, e um servidor
\textit{Node.js} que aloja o \textit{Juicebox} --- a aplicação que vai servir de cobaia (\textit{dummy}).
Vão ser realizadas duas etapas de testes: primeiro, sem WAF (\textit{Web Application Firewall})
e com foco em explorar vulnerabilidades na aplicação; e, posteriormente, com uma WAF configurada para
mitigar as várias vulnerabilidades que foram encontradas na etapa anterior.
\subsection{Network structure}
\begin{itemize}
\item \textbf{Client (20.60.0.0/24)} Cliente.
\item \textbf{Server (10.60.0.0/24)} Apache+ModSecurity e JuiceShop.
\end{itemize}
\subsection{Servers}
\begin{itemize}
\item \textbf{10.60.0.1} Servidor CentOS 9 com WAF e aplicação JuiceShop.
\end{itemize}
\subsection{Services}
\begin{center}
\begin{tabular}{ll}
\toprule
Service & Port \\\midrule
NodeJS (JuiceShop) & 3000 \\
Apache (WAF) & 80 \\
\bottomrule
\end{tabular}
\end{center}
\section{Web application security testing}
\subsection{Information Gathering}
Utilizámos a política por omissão (\textit{default policy}) para a realização do \textit{Active Scan} através do OWASP ZAP. Com esta abordagem, obtivemos múltiplos alertas automáticos. De forma a priorizar a análise, investigamos as alertas principais com base no maior nível de risco e grau de confiança reportados pela ferramenta.
Adicionalmente, realizámos testes de infraestrutura utilizando ferramentas especializadas:
\begin{codeblock}{bash}
sqlmap -u "http://192.168.1.1:3000/rest/products/search?q=apple" -p q --level=5 --risk=3 --banner
\end{codeblock}
Ao executar o \textit{sqlmap}, descobrimos que o sistema de gestão de base de dados subjacente é o \textit{SQLite}.
Paralelamente, realizámos uma descoberta de ficheiros e diretórios através de técnicas de \textit{fuzzing} de URLs no OWASP ZAP recorrendo à lista de permissões da \textit{DirBuster}. Esta exploração revelou os seguintes endpoints publicamente expostos:
\begin{itemize}
\item \texttt{/ftp}: Servidor de armazenamento e transferência de ficheiros exposto.
\item \texttt{/metrics}: Métricas internas da infraestrutura expostas.
\item \texttt{/api-docs}: Documentação e esquemas estruturais da API.
\end{itemize}
\subsection{Configuration and Deployment Management Testing}
\subsubsection*{Enumerate Infrastructure and Application Admin Interfaces}
Identificámos e testámos o acesso ao endpoint \texttt{/api-docs} (\textit{Swagger UI}), validando que as interfaces de documentação interna do sistema e as definições da API estavam publicamente expostas sem qualquer tipo de controlo de acesso ou autenticação prévia.
\subsubsection*{Test HTTP Methods}
Testámos os métodos HTTP permitidos pelo servidor através do envio de pedidos \texttt{OPTIONS}. Verificámos que o servidor aceita métodos potencialmente perigosos ou desnecessários para utilizadores comuns em rotas específicas, expandindo a superfície de ataque da aplicação.
\subsubsection*{Test File Permission}
Analisámos as permissões de acesso no diretório \texttt{/ftp}. Verificámos que a falta de restrições rígidas ao nível do sistema de ficheiros permite a qualquer utilizador anónimo listar o conteúdo de diretórios estruturais e descarregar ficheiros não indexados na interface principal da aplicação.
\subsection{Identity Management Testing}
\subsubsection*{Test Role Definitions}
Efetuámos testes de manipulação de parâmetros do lado do cliente através das ferramentas de programador do navegador. Adicionámos manualmente os cookies \texttt{isAdmin} com o valor \texttt{true} e \texttt{role} com o valor \texttt{admin}. Após a atualização da página, não observámos qualquer escalonamento de privilégios, indicando que a aplicação não valida perfis administrativos com base nestes cookies específicos.
\subsubsection*{Test User Registration Process}
Utilizámos o OWASP ZAP para intercetar o tráfego de rede e definir um \textit{breakpoint} no pedido HTTP POST de registo de novos utilizadores. Modificámos o corpo do pedido JSON, injetando manualmente o parâmetro \texttt{"role":"admin"}:
\begin{codeblock}{json}
{
"email": "johnGomas@gmail.com",
"role": "admin",
"password": "password",
"passwordRepeat": "password",
"securityQuestion": {
"id": 2,
"question": "Mother's maiden name?",
"createdAt": "2026-05-30T12:28:33.216Z",
"updatedAt": "2026-05-30T12:28:33.216Z"
},
"securityAnswer": "poker"
}
\end{codeblock}
O servidor backend processou o pedido sem validar se o utilizador possuía autorização para definir o seu próprio perfil, o que resultou na criação bem-sucedida de uma conta com permissões totais de administrador (\textit{Mass Assignment Vulnerability}).
\subsubsection*{Testing for Account Enumeration and Guessable User Account}
Ao tentar registar um utilizador com o e-mail \texttt{admin@juice-sh.op}, verificámos que a aplicação devolve uma mensagem de erro explícita indicando que o e-mail já se encontra registado no sistema. Este comportamento confirma a vulnerabilidade de enumeração de contas, permitindo a um atacante mapear quais os e-mails válidos na plataforma.
\includegraphics[width=0.5\textwidth]{email-unique}
\subsubsection*{Testing for Weak or Unenforced Username Policy}
Após testar vários caracteres especiais no formulário de registo, criámos um utilizador com os seguintes dados nos campos de input:
\begin{itemize}
\item \textbf{E-mail:} \texttt{son'or1=1--@gmail.com}
\item \textbf{Nome/Campos Adicionais:} \texttt{<h1>STRONG}
\end{itemize}
A aplicação aceitou o registo sem validar a presença de carateres de injeção SQL ou tags HTML. Contudo, verificámos que é impossível efetuar login com esta conta posteriormente, uma vez que o processo de autenticação falha e resulta num erro genérico do tipo \texttt{[object Object]} no ecrã.
\includegraphics[width=0.5\textwidth]{email-invalido}
\subsection{Authentication Testing}
Realizámos testes de \textit{fuzzing} automatizado contra o formulário de login utilizando dicionários de credenciais. Identificámos que a aplicação não implementa mecanismos de bloqueio de conta (*Account Lockout*) ou limitação de taxa de pedidos (*Rate Limiting*), permitindo ataques contínuos de \textit{brute force}.
\subsection{Authorization Testing}
Testámos as permissões de acesso ao diretório \texttt{/ftp} e verificámos que o servidor está configurado para permitir nativamente apenas a visualização de ficheiros com as extensões \texttt{.md} e \texttt{.pdf}.
Seguidamente, explorámos falhas na validação de inputs através de uma injeção de \textit{Null Byte} codificado (\texttt{\%2500.md} ou \texttt{\%2500.pdf}). O ataque foi bem-sucedido e contornou a validação de extensões do servidor, garantindo o acesso e descarregamento de ficheiros confidenciais restritos: \texttt{encrypt.pyc} e \texttt{suspicious\_errors.yml}.
\subsection{Session Management Testing}
Identificámos que o cookie \texttt{token}, responsável por armazenar o identificador da sessão ativa do utilizador, possui a flag \texttt{HttpOnly} configurada como \texttt{false}. A ausência desta proteção significa que o token está totalmente exposto e pode ser lido por scripts do lado do cliente, tornando a sessão criticamente vulnerável a roubo por Cross-Site Scripting (XSS).
\subsection{Input Validation Testing}
\subsubsection*{Testing for Reflected Cross Site Scripting}
Durante a auditoria à barra de pesquisa de produtos, validámos a existência de uma vulnerabilidade de \textit{Reflected Cross-Site Scripting} (XSS) devido à ausência de higienização do input do utilizador.
\begin{enumerate}
\item \textbf{Injeção HTML:} Introduzimos o valor \texttt{<h1>apple} na pesquisa e verificámos que o resultado foi renderizado no navegador como um título estrutural, confirmando que o código HTML é injetado diretamente na página.
\item \textbf{Tentativa com Script Direto:} Inserimos o payload tradicional \texttt{<script>alert("someones gotta do it")</script>apple}. Esta tentativa não foi executada, demonstrando a presença de uma validação simples contra tags explícitas de script.
\item \textbf{Evasão com Evento de Erro:} Para contornar a restrição, injetámos uma tag de imagem com um caminho inválido acompanhado do manipulador de eventos \texttt{onerror}:
\begin{codeblock}{html}
<img src="x" onerror="alert('someones gotta do it')">apple
\end{codeblock}
O filtro falhou ao inspecionar este atributo e o navegador executou o código JavaScript com sucesso quando a imagem falhou o carregamento.
\end{enumerate}
Adicionalmente, explorámos o mesmo parâmetro de pesquisa recorrendo ao \textit{sqlmap} para validar falhas de injeção SQL, conseguindo extrair com sucesso a estrutura de 22 tabelas da base de dados:
\begin{codeblock}{bash}
sqlmap -u "http://10.60.0.1:3000/rest/products/search?q=apple" -p q --dbms=sqlite --prefix="'%" --suffix="%'--" --tables --batch
[22 tables]
+-----------------------+
| Addresses |
| BasketItems |
| Baskets |
| Captchas |
| Cards |
| ChallengeDependencies |
| Challenges |
| Complaints |
| Deliveries |
| Feedbacks |
| Hints |
| ImageCaptchas |
| Memories |
| PrivacyRequests |
| Products |
| Quantities |
| Recycles |
| SecurityAnswers |
| SecurityQuestions |
| Users |
| Wallets |
| sqlite_sequence |
+-----------------------+
\end{codeblock}
\subsection{Testing for Error Handling}
Ao tentar forçar o acesso a uma página ou ficheiro inexistente no servidor de ficheiros, como por exemplo na rota \texttt{/ftp/teste}, a aplicação falhou ao tratar a exceção de forma segura. Em vez de apresentar uma página de erro genérica (404), o servidor devolveu uma resposta detalhada expondo o \textit{stack trace} completo do ambiente \textit{Express.js}, revelando caminhos internos do sistema de ficheiros do servidor.
\includegraphics[width=\textwidth]{stack-trace}
\subsection{Client Side Testing}
Validámos que o token de sessão (JWT) do utilizador autenticado está armazenado diretamente no \texttt{localStorage} do navegador. Uma vez que o \texttt{localStorage} não possui mecanismos de proteção equivalentes à flag \texttt{HttpOnly} dos cookies, qualquer script executado no contexto da página consegue ler estes dados.
Utilizando a falha de XSS identificada anteriormente na barra de pesquisas, injetámos o seguinte payload direcionado:
\begin{codeblock}{html}
<img src="x" onerror="alert(localStorage.getItem('token'))">apple
\end{codeblock}
A execução deste vetor permitiu extrair o conteúdo do token diretamente do armazenamento local da vítima. Isto prova que um atacante pode automatizar a exfiltração destas informações e assumir a identidade de qualquer utilizador afetado sem necessitar de saber as credenciais de acesso de forma persistente.
\section{Web Application Security Firewall}
% Esta seccao sera preenchida com os resultados da Segunda Etapa (Com WAF ativada)
\subsection{Information Gathering}
\subsection{Configuration and Deployment Management Testing}
\subsection{Identity Management Testing}
\subsection{Authentication Testing}
\subsection{Authorization Testing}
\subsection{Session Management Testing}
\subsection{Input Validation Testing}
\subsection{Testing for Error Handling}
\subsection{Client Side Testing}
\section{Conclusions}
\end{document}