From 4afad1ead0970be6e9215560437c57cd4e23f069 Mon Sep 17 00:00:00 2001
From: Santo Cariotti <santo@dcariotti.me>
Date: Tue, 18 Oct 2022 21:54:02 +0200
Subject: dump

---
 docs/m6.tex | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 70 insertions(+), 5 deletions(-)

(limited to 'docs/m6.tex')

diff --git a/docs/m6.tex b/docs/m6.tex
index a7ac7c7..e1f1cb8 100644
--- a/docs/m6.tex
+++ b/docs/m6.tex
@@ -7,7 +7,7 @@
     \small\textsc{Dipartimento di Matematica e Informatica\\Corso di Internet Security}\\
     \Huge\textbf{M6: Insecure Authorization\\Attack side}\\
     \author{Santo Cariotti}
-    \date{x Settembre 2022}
+    \date{x y z}
 }
 
 \usepackage{graphicx}
@@ -25,18 +25,83 @@
 \input{chapters/jwt-attacks}
 
 \chapter{Attacco ad una API}
-Escluso l'attacco a JWT passiamo ad un possibile attacco rivolto ad un API.
-
 In genere, quando vogliamo tenere traccia del traffico di richieste che vi è dentro una web app (XHR \cite{XHR:1}, loading di immagini, fonts, codice JS) apriamo la "console sviluppatore" che ci dà a disposizione Firefox (o qualsiasi altro browser, come Chrome) e iniziamo a guardare. 
 Con questa relazione però, vogliamo fare un attacco attraverso un dispositivo mobile, quindi controlleremo il traffico in uscita nella nostra rete per scoprire a quale server la nostra mobile app sta facendo capo.
 \newline\newline
 Imposteremo tutto il necessario per replicare l'attacco visto nel capitolo precedente:
 \begin{itemize}
-	\item Una REST API con un problema di autorizzazione nell'endpoint degli utenti, il quale non verifica che l'utente loggato è effettivamente il possessore di quella risorsa;
-	\item Un'applicazione mobile che fa richieste a tale API.
+	\item Una REST API con un problema di autorizzazione nell'endpoint degli utenti, il quale non verifica che l'utente loggato è effettivamente il possessore di quella risorsa. La installeremo in un server su internet;
+	\item Un'applicazione mobile che fa richieste a tale API;
+	\item Wireshark\cite{WIRESHARK:1} per monitorare la rete.
 \end{itemize}
 
+\section{API}
+Nella realtà, come questa API pubblica \cite{REDDIT:1} fa, si espone un endpoint \emph{/api/v1/me/} dove \emph{v1} è la versione dell'API in cui si ritornano i dati per l'utente autenticato. E questa è una buona prassi, un endpoint che si può trovare più o meno in tutte le REST API.
+
+\textbf{Cosa proveremo a fare noi?} Proprio un'API che fa ciò, niente più e niente meno. Ci limiteremo però solo a controllare che il JWT passato è valido in modo da ritornare i dati dell'utente che noi pensiamo sia stato autorizzato.
+\newline\newline
+Il codice di questo servizio è presente al link \underline{\url{https://git.dcariotti.me/m6-ie/tree/server}}.
+\newline\newline
+La parte incriminata è la route qui sotto. Qui non si limita a ritornare la riga utente che corrisponde all'ID utente passato dall'header.
+
+\begin{lstlisting}
+async fn get_user(claims: Claims) -> Result<Json<UserList>, AppError> {
+    match User::find_by_id(claims.user_id).await {
+        Ok(user) => Ok(Json(user)),
+        Err(_) => Err(AppError::NotFound),
+    }
+}
+\end{lstlisting}
+
+in realtà qui non vi è nessun problema reale di sicurezza. È un API che funziona, ad ogni richiesta infatti controlla se il token è valido
+
+\begin{lstlisting}
+// bearer = variable with token string
+
+let token_data = decode::<Claims>(bearer.token(), &KEYS.decoding, &Validation::default())
+            .map_err(|_| AppError::InvalidToken)?;
+\end{lstlisting}
+
+infatti il problema sta nell'inizializzazione della codifica/decodifica di JWT, in particolare quando definiamo il secret.
+
+\begin{lstlisting}
+static KEYS: Lazy<Keys> = Lazy::new(|| {
+    let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");
+    Keys::new(secret.as_bytes())
+});
+
+impl Keys {
+    fn new(secret: &[u8]) -> Self {
+        Self {
+            encoding: EncodingKey::from_secret(secret),
+            decoding: DecodingKey::from_secret(secret),
+        }
+    }
+}
+\end{lstlisting}
+
+E proprio in questo "errore" nel secret che andremo ad attaccare. Useremo un attacco di bruteforcing all'header Authorization per far sì di avere i dati dell'utente con ID che noi vogliamo.
+
+\subsection{Forcing del secret}
+L'Authorization token è qualcosa di pubblico, che possiamo veder ad ogni richiesta HTTP. Il secret no, è usato per fare verificare la firma e rendere valido il token stesso. Quindi useremo un approccio simile a quello impiegato per "forzare" il login di una piattaforma: proveremo per forza bruta tutte le password possibili.
+In questo caso proveremo i possibili secret per far sì che la firma sia lo stesso valida.
+
+Prendendo una lista ben nota di secrets impiegati in servizi in produzione \cite{JWT_SECRETS_LIST:1} useremo il software open-source \textbf{Hashcat} \cite{HASHCAT}.
+Per crackare la password usando Hashcat bisogna dare in input il parametro dell'hash type di JWT, il sorgente in cui vi è il token che si vuole crackare e il sorgente in cui vi è la lista dei secrets.
+
+\begin{lstlisting}
+$ hashcat -m 16500 my-secret.dat jwt-secrets-list.dat
+
+eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMywiZXhwIjoxNjY2Mjk0Nzk2fQ.ay_RPoeTuV4e
+lBFqqCdTzF64GPcoEDOlJN2DUAOqwds:hello
+
+Session..........: hashcat
+Status...........: Cracked
+Hash.Type........: JWT (JSON Web Token)
+Hash.Target......: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIj...AOqwds
+\end{lstlisting}
 
+Qui vediamo come sia riuscito a trovare il secret, ovvero la stringa \emph{hello}.
 
 \bibliography{refs}
 \bibliographystyle{ieeetr}
-- 
cgit v1.2.3-18-g5258

