summaryrefslogtreecommitdiff
path: root/docs/chapters/setup.tex
blob: 16c0bc5bb47ac2670b7e3b07ea5618068cc6e0a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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. 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}, 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 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.

\section{App mobile}
Il codice dell'app è presente al link \underline{\url{https://git.dcariotti.me/m6-ie/tree/app}}.
È una "banale" applicazione scritta usando Ionic \cite{IONIC} con 3 pagine:
\begin{enumerate}
    \item Home: ricorda cosa serve fare, ovvero il login;
    \item Sign in: permette di fare il login mediante username e password;
    \item Me: visualizza le informazioni dell'utente loggato.
\end{enumerate}

Sapendo ciò dovremo esaminare il file APK dell'applicazione per vedere come si comporta realmente.\\\\
Dentro il codice sorgente è presente il codice in JavaScript, ma a noi serve usarlo nel nostro dispositivo Android. Quindi, come faremo realmente sviluppando un'app Ionic, lo andremo a compilare e visualizzare l'APK dentro Android Studio \cite{ANDROIDSTUDIO}.
Questo passaggio lo ricreiamo per ricondurre a tutti i passaggi.


\begin{lstlisting}
$ git clone https://git.dcariotti.me/m6-ie
$ cd m6-ie/app
$ npm i
$ ionic capacitor add android
$ vi .env # Chi fa la build conosce effettivamente l'URL dell'API
$ npm run build --production
$ npx cap copy android
$ npx cap sync android
$ cd android
$ export ANDROID_SDK_ROOT="<path all'sdk>"
$ ./gradlew assembleDebug
\end{lstlisting}

L'ultimo comando creerà un APK valido dentro \emph{m6-ie/app/build/outputs/apk/debug/app-debug.apk}.
Da non confondere quindi con la creazione di pacchetti AAB\cite{APKVSAAB:1} per le release.

\subsection{Configurazione Android Studio}
Scaricato e installato il pacchetto dal link ufficiale bisognerà inoltre installare anche l'SDK e un Device, ovvero un emulatore di un dispositivo Android.

\begin{figure}[h]
\centering
\includegraphics[width=0.2\textwidth]{data/android-studio-screenshot}
\caption{Screenshot di Android Studio in Ubuntu focal}
\end{figure}


Nell'esempio qui di seguito io userò SDK 30 su un Pixel 4.\\
\\
Procediamo quindi al profiling dell'applicazione come da \textbf{Figure 3.1}.


Avviando l'emulatore attraverso \emph{Shift+F10} vedremo l'applicazione dentro il device Android, Google Pixel in questo caso.

\begin{figure}[h]
\centering
\includegraphics[width=0.2\textwidth]{data/pixel-device}
\caption{Screenshot dell'emulatore}
\end{figure}

Se provassimo ad intercettare il traffico usando il \emph{Network profiler} integrato non vedremmo nulla perché non vengono esaminate le richieste HTTP fatte in maniera ibrida, quindi useremo Wireshark per monitorare le richieste al server.