-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathdocumentation.tex
More file actions
415 lines (389 loc) · 44.4 KB
/
documentation.tex
File metadata and controls
415 lines (389 loc) · 44.4 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
\documentclass[11pt]{article}
\title{ExploitFarm}
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{float}
\usepackage[left=2.5cm, right=2.5cm, top=2.5cm, bottom=2.5cm]{geometry}
\usepackage{titlesec}
\usepackage{tocloft} % Optional: to customize TOC appearance
% Redefine paragraph to behave like a subsection for TOC purposes
\titleformat{\paragraph}
[runin] % Keep the paragraph style without line break
{\normalfont\normalsize\bfseries} % Style
{\theparagraph} % Numbering style
{1em}
{}
\titlespacing*{\paragraph}{0pt}{3.25ex plus 1ex minus .2ex}{1em}
\setcounter{secnumdepth}{4}
\setcounter{tocdepth}{4}
\author{Domingo Dirutigliano}
\begin{document}
\begin{titlepage}
\begin{center}
\vspace*{1cm}
\LARGE{\textbf{ExploitFarm Project}}
\vspace{0.5cm}
Analisi di progetto e documentazione
\vspace{0.5cm}
\begin{figure}[H]
\centering
\includegraphics[width=0.2\textwidth]{logo.png}
\end{figure}
\vspace{0.5cm}
\textbf{Domingo Dirutigliano}
\vfill
Politecnico di Bari\\
Software Engineering
\vspace{0.1cm}
\end{center}
\end{titlepage}
\tableofcontents
\newpage
\section{Introduzione}
\subsection{Preambolo}
Il seguente progetto è stato realizzato per essere utilizzato nelle competizioni Capture the flag (CTF) in modalità attack defence. Questa tipologia di competizioni è organizzata progetti come \href{https://cyberchallenge.it/}{CyberChallenge} mirati alla formazione di esperti in cybersecurity, progetto di in cui svolgo il ruolo di istruttore al Politecnico di Bari, ma anche da team internazionali di CTF, citando per esempio la \href{https://2024.faustctf.net/}{Faust CTF}. La competizione si svolge tra diversi team di cybersecurity, ogni team ha un server con alcuni servizi avviati che sono uguali per tutti i team. I seguenti servizi hanno delle vulnerabilità al loro interno che permettono l'estrapolazione di informazioni normalmente non accessibili. Al centro di tutta la competizione c'è l'infrastruttura di gara che si occupa di collegare le varie macchine e team alla rete di gara e di offrire i servizi del gameserver. Il gameserver è un elemento fondamentali in queste competizioni poiché è l'elemento responsabile della verifica del normale funzionamento dei servizi di tutti i team, ed è anche il responsabile del conteggio dei punteggi. La competizione è divisa in slot temporali chiamati round o tick di durata fissa (solitamente circa 2 minuti) in cui avvengono delle azioni ripetitive dall'inizio alla fine della competizione stessa. Ogni tick infatti il gameserver esegue dei controlli sull'operatività dei servizi e inserisce i "dati sensibili" da rubare che sono le flag. Le flag sono dei valori alfanumerici di un formato fisso, ben definito e riconoscibile (differente da gara a gara) di natura randomica che rappresenta l'informazione sensibile da rubare e proteggere. Ogni team quindi riceverà per ogni servizio, nello specifico per ogni Flag Store 1 flag per ogni tick, l'obiettivo del team è sfruttare le vulnerabilità dei servizi per rubare le flag agli altri team e consegnarle al gameserver che a quel punto assegnerà dei punti extra al team che è riuscito ad ottenere le flag e penalizzerà il team che non ha protetto le flag, e quindi per lo stesso meccanismo il team deve anche proteggere il servizio provando a chiudere le vulnerabilità evitando che altri team possano rubare le loro flag mantenendo il servizio funzionante. In queste competizioni il calcolo del punteggio che dipende strettamente dalle scelte degli organizzatori tende sempre a penalizzare pesantemente quei team che non rendono disponibili e funzionanti i servizi, di modo da rendere necessaria e di prima importanza la piena operatività del servizio stesso. Inoltre non è possibile riconoscere e distringuere i bot che visitano la pagina dai bot che attaccano degli altri team, e questo è possibile tramite un operazione di anonimizzazione del traffico tramite ad esempio un SNAT integrato dagli organizzatori a questo fine.
\subsection{Descrizione generale}
"Exploitfarm" è un software specializzato per le competizioni CTF Attack/Defence, che si occupa principalmente di gestire la fase di attacco e ti tutto quello che conseguentemente questa fase richiede per essere eseguita correttamente, al fine di semplificare e velocizzare gli attacchi.\\
In generale Exploitfarm si occupa di attaccare in parallelo una serie di team (attacker) e di raccogliere ed inviare seguendo i criteri e limitazioni indicate per la competizione che si sta svolgendo le flag al gameserver (submitter).
\subsection{Obiettivi generali del progetto}
\begin{itemize}
\item Setup e installazione facile, veloce, personalizzabile e facilmente automizzabile
\item Gestione delle risorse per gli attacchi dinamica e reattiva
\item Scrittura degli exploit e dei test su questi semplificata
\item Interfaccia intuitiva con avvio e configurazione intuitiva e rapida
\item Keep track of anything: accumula dati sugli attacchi e ne permette un'analisi veloce ed intuitiva
\item Rende semplice la condivisione/collaborazione sugli attacchi e la loro esecuzione
\item Leggero da eseguire su qualsiasi piattaforma
\item Gestione distribuita degli attacchi
\item Configurazione e modifiche dinamiche
\end{itemize}
\subsection{Perchè lo sviluppo di un nuovo attacker/submitter?}
Gli attacker attualmente esistenti sono spesso incompleti, difficili da configurare e da completarne il setup, facilmente inclini ad errori che spesso comportano una perdita di tempo aggiuntiva, non hanno alcun tipo di gestione del carico supportato dalla macchina che esegue gli attacchi, non memorizza o espone alcun dato statistico sull'andamento degli attacchi ed infine non gestisce la condivisione degli exploit stessi.\\
Date le forti lacune presenti in software simili già esistenti, ho ritenuto opportuno la creazione di un'alternativa agli attacker attualmente esistenti.\\
\textbf{NOTA}: "ExploitFarm" è liberamente ispirato ad un altro attacker molto famoso chiamato \href{https://github.com/DestructiveVoice/DestructiveFarm}{DestructiveFarm}, ma ne condivide a livello di codice unicamente delle piccole porzioni del suo client "start\_xploit.py" a loro volta modificate ed adattate, in alcune parti riscritte e riprogettate completamente date le netti differenze di requisiti dei progetti.
\section{Project Managment}
La gestione del progetto è principalmente plan-driven con un approccio però che si avvicina allo "scrum" per progettazione e organizzazione dei task (organizzate in un backlog di user-stories). Il progetto di per se è già in una fase di sviluppo avanzata, pertanto la gestione del progetto riguarderà l'aggiunta della feature per l'avvio di singoli attacchi distribuiti tra più client.
\subsection{Gestione generale}
L'approccio scelto per lo sviluppo delle nuove funzionalità è basato sullo "scrum" con un approccio tendenzialmente plan-driven dati i tempi brevi assegnati per il progetto stesso. Sono assenti le riunioni giornaliere e tutta l'attività si dividerà in soli 2 sprint per l'integrazione di 2 macro-funzionalità.
Sempre a causa di tempi ristretti, i test non sono previsti, ma unicamente micro test durante lo sviluppo stesso per verificarne il funzionamento.
\subsection{Kanban (github)}
Il progetto è interamente condiviso e gestito su github, grazie alla funzionalità dei progetti di cui si sfrutta il backlog che permette di gestire le user-stories con tag, ordini di priorità e direttamente associabili ai branch in cui si esegue l'attività di sviluppo, per questo molto integrato con lo sviluppo stesso.
Il kanban finale è disponibile al seguente link
\href{https://github.com/orgs/Pwnzer0tt1/projects/1}{QUI} e inoltre è anche possibile visualizzare le modifiche eseguite sul progetto dall'inizio di questa fase di sviluppo al seguente link \href{https://github.com/Pwnzer0tt1/exploitfarm/compare/0be4b22b0676dede1836719639ae2edc3a508504...c9f8c3c28bd88ca35072ffe24f16c19e4b27c2e9}{QUI}
\begin{figure}[H]
\centering
\includegraphics[width=0.6\textwidth]{backlog.png}
\end{figure}
\subsection{Scheduling}
Sono definite 3 fasi principali nel progetto:
\begin{itemize}
\item Brainstorming, definizione dei requisiti tecnici e documentazione
\item 1* Milestone/Sprint: gestione degli exploit
\item Technical features: From polling to event driven updates + switching to sqlalchemy
\item 2* Milestone/Sprint: gestione dei gruppi di client per gli attacchi condivisi
\end{itemize}
Le fasi sono definite proprio per la necessità di progettare lo sviluppo stesso dei nuovi requisiti, e dalla mancanza della feature di gestione degli exploit necessaria allo sviluppo della seconda milestone.
L'inizio del progetto con la prima fase è iniziata il 03-10-2024, la consegna è fissata per il 20-12-2024.
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{scheduling.png}
\end{figure}
\subsection{COCOMO Analysis}
Il modello COCOMO utilizzato per la stima è quello del Post-architecture model dato che la fase in sviluppo è una fase di implementazione di feature con un progetto di base già pre-ingegnerizzato (Con size stimata di 2k righe di codice).
\[ E = A \times Size^B \times \prod_{i=1}^{n} EM_i \]
Con:
\[ B = 0.91 + 0.01 \times \sum Scale Factors \]
\begin{itemize}
\item A = 2.94 (tipico per Post-Architecture COCOMO)
\item $Size \simeq 2k$ righe di codice
\end{itemize}
\subsubsection{Effort Multipliers}
Si utilizzerà un subset dei 17 moltiplicatori previsti per COCOMO post-architecture.
\begin{itemize}
\item RELY = 1.26 (Very High)
\item DATA = 1.00 (Nominal)
\item CPLX = 1.17 (High)
\item RUSE = 0.95 (Low)
\item DOCU = 1.00 (Nominal)
\item TIME = 1.29 (Very High)
\item PVOL = 1.00 (Nominal)
\item PCAP = 0.88 (High)
\item TOOL = 0.90 (High)
\item SITE = 1.00 (Nominal)
\item SCED = 1.00 (Nominal)
\end{itemize}
\[
\prod_{i=1}^{n} EM_i = 1.431
\]
\subsubsection{Scale Factors}
\begin{itemize}
\item PREC = 1.24 (Very High)
\item FLEX = 1.01 (Very High)
\item RESL = 4.24 (Nominal)
\item TEAM = 1.0 (No team, not used)
\item PMAT = 1.56 (Very High)
\end{itemize}
\[ B = 0.91 + 0.01 \times \sum Scale Factors = 0.99 \]
\subsubsection{Risultato Finale}
\[ E = A \times Size^B \times \prod_{i=1}^{n} EM_i = 8.36 \]
\subsubsection{Duration}
\[ C = 3.67 \]
\[ D = 0.28 + 0.2 \times (B - 0.91) = 0.296 \]
\[ T = C \times E^D = 6.8 (mesi) \]
Tuttavia assumendo gli obiettivi del progetto, è intuitivo comprendere come la stima eseguita è eccessiva rispetto al reale tempo necessario al raggiungimento dell'obiettivo.
\subsection{Risk Managment and Analysis}
\subsubsection{Stima dell'effort e requisiti}
Durante lo sviluppo c'è la possibilità nascano nuove esigenze date da limitazioni tecniche attualmente presenti nel progetto: per attutire i danni possibili generati dalla nascita di nuovi requisiti o anche alla sottostima del tempo necessario, è necessario iniziare al più presto dalla data schedulata l'effettiva data di inizio dello sviluppo di modo da permettere l'allocazione di più slot temporali ad una determinata user-story nello sviluppo prima che possa terminare la deadline di consegna, punto critico nel progetto. Il livello di rischio associato è "Moderato".
\subsubsection{Rilascio di versioni non totalmente funzionanti}
C'è la possibilità che a causa di modifiche a diverse parti del progetto, si possano presentare bug in parti non direttamente inerenti ma collegate alla parte di software modificata. Per ovviare a questo problema è utile eseguire in maniera atomizzata prima della pubblicazione della release dei test automatici che verificano il funzionamento corretto della piattaforma. Nonostante il rischio si classificato come Medio, date le scadenze strette non è prevista attualmente la scrittura di test automatizzati.
\subsubsection{Rischio di rendere la piattaforma complessa gestire}
Il progetto ha grandi requisiti e grandi ambizioni a livello di funzionalità che tuttavia dopo essere sviluppate possono risultare complesse nel loro utilizzo anche per gli utenti target che sono classicamente utenti esperti. Andando in questa direzione potremmo perdere uno degli obiettivi del progetto, cioè quello di facile utilizzo, autorizzazione e setup. Il rischio è medio elevato e potrebbe comportare lo sviluppo di parti della piattaforma che necessitano un completo refactoring o riscrittura in seguito. Per evitare questo rischio è necessario un confronto esterno con altri giocatori CTF per avere opinioni esterne, quindi opinioni esenti del bias dello sviluppatore del progetto, che sviluppandone le funzionalità non si rende conto di eventuali funzionalità complesse da utilizzare. Questo permetterebbe una rivisitazione e progettazione migliore del progetto.
\subsection{Release Managment}
Le release di ExploitFarm avvengono tramite github con una catena di building automatica del container di exploitfarm che contiene frontend compilato e backend, automaticamente rilasciato e pubblicato su gihtub packages che ne rilascia il download pubblico.
Inoltre per l'esecuzione di exploitfarm è disponibile uno script che genera dinamicamente un docker compose e lo avvia utilizzando i container pullati dai repository online, e inoltre si assicura che la versione avviata di exploitfarm sia l'ultima disponibile.
\subsection{Modello di Business}
Il progetto di per se nasce come progetto totalmente opensource, quindi non a scopo di lucro. Tuttavia un possibile approccio di Business adottabile liberamente ispirato a quello di un'altra importante piattaforma opensource per le competizioni CTF Jeopardy (\href{https://github.com/CTFd/CTFd}{CTFd}) è quello di continuare ad offrire una piattaforma completamente opensource e gratuita ma di offrire a pagamento un deploy di ExploitFarm con eventuali client attaccanti hostati (con dimensioni del server adattabili e scalati anche in base al costo e al peso dell'exploit) di modo da rendere immediato l'accesso all'attacker, anche con eventuali supporti rapidi alla connessione a VPN della gara, o al bridging da uno dei PC del team della rete di gara se non sono presenti connessioni VPN.
\subsection{Analisi SWOT}
\subsubsection{S: Punti di forza}
\begin{itemize}
\item Unicità sulle funzionalità
\item Interfaccia innovativa
\item Setup Semplice
\item TUI
\item Statistiche
\end{itemize}
\subsubsection{W: Punti di debolezza}
\begin{itemize}
\item Elevata complessità
\item Centralizzato (SPOF)
\end{itemize}
\subsubsection{O: Opportunità}
\begin{itemize}
\item Pubblicizzazione
\item Aggiunta di test automatici
\end{itemize}
\subsubsection{T: Minaccie}
\begin{itemize}
\item Impossibilità di mantenere il progetto a fronte di una grande complessità da gestire
\end{itemize}
\section{Specifiche}
\subsection{Architettura del progetto}
Il progetto è composto principalmente da un server centrale (nello specifico un web server) che coordinerà una serie di client sia frontend (web) che tramite una CLI. La parte di coordinamento, di submitting e gestione dei dati è affidata al server. Il modello è un modello client server dove tuttavia alcuni client cioè i client da terminale svolgono un ruolo fondamentale per il funzionamento del progetto stesso e comunicano tramite comunicazioni bilaterali grazie alle websocket. Pertanto il progetto pur avendo di base una architettura client-server, intrinsecamente implementa alcune sue parti con architetture ad eventi e peer-to-peer
\begin{figure}[H]
\centering
\includegraphics[width=0.8\textwidth]{general_layout.png}
\end{figure}
\begin{figure}[H]
\centering
\includegraphics[width=0.8\textwidth]{Architecture.png}
\end{figure}
\subsubsection{Backend}
Il backend sarà il core del progetto poiché conterrà tutta la logica per il coordinamento dei vari client che invieranno il risultato degli attacchi, dovrà gestire i dati ed elaborarli al fine di renderli facilmente fruibili dai client, inoltre conterrà la logica e si occuperà della gestione del submitting delle flag al gameserver seguendo i requisiti indicati in fase di setup.
\\Tecnologie utilizzate:
\begin{itemize}
\item FastAPI (wsgi, sviluppo backend)
\item Postgres (Database SQL)
\item Redis (Caching e gestione multiprocesso del backend)
\item Sqlachemy + SqlModel (ORM per postgres)
\item Socket.IO (Comunicazione backend via Websocket ad eventi con rpc)
\end{itemize}
\subsubsection{Frontend}
La visualizzazione avanzata dello stato di ExploitFarm è invece affidata alla parte frontend del webserver che dovrà permettere un facile accesso ai dati presenti sul server, offrendoli tramite strumenti di analisi come grafici che devono essere mirati sulle esigenze decisionali che possono emergere durante una competizione Attack Defence. Inoltre dovrà segnalare e rendere facilmente e tempestivamente nota la presenza di eventuali errori di qualsiasi tipo sull'intera infrastruttura permettendone un'intervento quanto più immediato da parte del team.
\\Tecnologie utilizzate:
\begin{itemize}
\item React (Sviluppo della SPA)
\item Mantine UI (Per l'interfaccia)
\item React Query (Gestione richieste caching e state frontend)
\item Zustand (Gestione dei token e global state)
\item Socket.IO (Comunicazione backend via Websocket ad eventi con rpc)
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=0.8\textwidth]{exploitfarm-web.png}
\end{figure}
\subsubsection{CLI (xfarm)}
Infine un'ultima parte fondamentale in tutto il progetto è il client che deve essere eseguito preferibilmente su macchine diverse da quella che offre il server, che si occupa dell'esecuzione stessa degli attacchi, della creazione del progetto dell'attacco, del monitoraggio (parziale) dell'attacco stesso. Anche il client stesso dovrà avere un'interfaccia in questo caso TUI intuitiva e veloce da utilizzare che deve rendere immediato e facile l'avvio dell'attacco e l'inserimento dei dati richiesti per l'esecuzione dell'attacco stesso.
\\Tecnologie utilizzate:
\begin{itemize}
\item Typer (per lo sviluppo della CLI)
\item Textual (per lo sviluppo della TUI interattiva)
\item Socket.IO (Comunicazione backend via Websocket ad eventi con rpc)
\end{itemize}
\begin{figure}[H]
\centering
\includegraphics[width=0.6\textwidth]{xfarm-start-cmd.png}
\end{figure}
\subsection{Specifica dei requisiti (FURPS+)}
\subsubsection{Functionality}
\paragraph{Esecuzione Attacchi}\mbox{}\\
Il sistema deve essere in grado di eseguire un attacco scritto in qualsiasi linguaggio che rispetti determinati requisiti e prenda in input i dati necessari ad eseguire l'accatto, e li esegui in maniera coordinata monitorandone l'esecuzione e raccogliendo tutte le informazioni che potrebbero essere necessarie per analizzare la singola esecuzione dell'attacco. Gli attacchi dovranno essere inoltre coordinati per essere eseguiti seguendo un determinato criterio di scheduling configurato sul server
\paragraph{Submission delle flag}\mbox{}\\
Il sistema deve essere in grado di raccogliere da tutti gli attacchi e filtrare le flag duplicate, e inviare queste seguendo i limiti imposti dal gameserver, tramite le configurazioni disponibili che ne devono permettere una gestione flessibile. Inoltre per allggerire il carico, il sistema deve anche automaticamente far scadere le flag che non soddisfano i requisiti di consegna per il gameserver.
\paragraph{Gestione di attacchi distribuiti}\mbox{}\\
In caso di exploit con un carico computazionale e di memoria non indifferente come nel caso di alcuni attacchi criptografici o di attacchi che necessitano l'elaborazione di media, ExploitFarm deve disporre di un sistema per creare dei gruppi di client che eseguono lo stesso attacco ma i cui team da attaccare siano distribuiti in maniera bilanciata e basata sulla potenza computazionale dei client nel gruppo.
\paragraph{Gestione Exploit}\mbox{}\\
I sorgenti degli attacchi devono poter essere facilmente condivisibili e avviabili anche da altri utenti. Inoltre è richiesto anche tenere traccia delle versioni dell'attacco di modo da permetterne la segnalazione di vecchie versioni, aggiornamento di nuove versioni in maniera automatica in caso di attacchi condivisi (definiti in seguito), e analisi post-gara.
\subsubsection{Usability}
\paragraph{Setup}\mbox{}\\
Il setup di ExploitFarm dalla sua installazione alla conclusione della sua configurazione deve essere di facile ed intuitivo utilizzo e di semplice finalizzazione. Al fine di perseguire questo obiettivo, la tecnologia per l'avvio del progetto è Docker, che ne permette facilmente di avviare un postgres e server redis dedicati e isolati. Inoltre è possibile avviare exploitfarm tramite un one-command, che avvierà il progetto da un repository pubblico con il container pre-buildato. Una volta avviato la configurazione iniziale dovrà essere compilabile ed eseguita sia tramite un'interfaccia web che tramite una automizzazione che è possibile scrivere tramite la libreria python associata al progetto.
\paragraph{Analisi statistiche e visualizzazione}\mbox{}\\
Il sistema deve disporre di una interfaccia sempre aggiornata e facile da visionare per il monitoraggio delle flag in arrivo, degli attacchi eseguiti, che permetta la visualizzazione degli errori in caso di attacchi crashati o non funzionanti, di selezionare e filtrare i dati in base a dei parametri di ricerca e infine disporre di una serie di grafici che mostrino l'andamento degli attacchi durante la gara, di modo da permetterne una visione immediata.
\subsubsection{Reliability}
\paragraph{Dinamicità delle configurazioni}\mbox{}\\
Tutte le configurazioni nella fase di setup devono essere modificabili e automaticamente aggiornate su tutti i client e in tutte le componenti del backend stesso, in modo da evitare interruzioni brusche degli attacchi, permettendo la continuità dell'esecuzione dei client e quindi dispendi di tempo nella riconfigurazione del sistema.
\paragraph{Error handling e managment}\mbox{}\\
Se a causa di errori rilevabili c'è un errore nel sistema rilevabile, il sistema deve prontamente notificare su tutti i client l'errore/warning includendo tutte le informazioni utili a rilevarne l'origine, la motivazione e quindi velocizzando la risoluzione del problema.
\paragraph{Resilienza del sistema}\mbox{}\\
Il sistema deve tentare in tutti i modi di impedire il riavvio ne tantomeno la chiusura degli exploit, e quindi anche a fronte di errori nei limiti di fattibilità continuare ad eseguire gli attacchi e consegnare le flag al gameserver. Ad esempio in caso il server vada offline gli attacker devono continuare ad accumulare flag fino a che il gameserver non tornerà online, e in caso di riavvio degli exploit mantenere la coda salvata per essere inviata successivamente. L'obiettivo deve essere non perdere flag ottenute e cercare di consegnarle al gameserver il prima possibile.
\subsubsection{Performance}
\paragraph{Bilancio dei processi nell'esecuzione di un attacco}\mbox{}\\
Gli attacchi devono essere parallelizzati ed eseguiti tenendo conto delle risorse libere nel sistema: in caso il sistema arrivi in trashing o il processore sia saturo, il client deve ribilanciare automaticamente il quantitativo di attacchi eseguiti al fine di non mandare il sistema in blocco. Cioè deve avvenire anche negli attacchi distribuiti.
\subsubsection{Supportability}
\paragraph{Adattabilità}\mbox{}\\
Il sistema deve al limite di quanto possibile lasciare liberi gli utilizzatori di personalizzare ogni sua parte in modo dal renderlo adattabile a ogni CTF attack defence possibilmente senza modificare il source code del server o del client stesso. Inoltre gli attacchi devono poter essere scritti in qualsiasi linguaggio (nonostante tutta l'infrastruttura verti su python)
\paragraph{Portabilità e avvio}\mbox{}\\
L'avvio del server deve essere rapido e semplice da configurare, inoltre deve facilmente adattarsi a più macchine e deve risultare semplice il passaggio di tutti i dati in un altro server, pertanto la migrazione deve essere quanto più intuitiva e rapida possibile.
\subsubsection{+}
\paragraph{Versioning}\mbox{}\\
Si utilizza un versioning a 3 cifre le quali sono la prima per la major release, che comporta dei cambiamenti stutturali al programma con possibile conseguente rottura di vecchi client, La seconda cifra indica la feature release che non influenza o provoca danni alle altre funzionalità ma è solo un'implementazione integrativa e non distruttiva, mentre l'ultimo numero indica la patch di quella versione in cui vengono risolti bug e crash inaspettati per le nuove funzionalità ma non solo.
Viene fatta eccezione per le versioni con major 0. che sono consideranti ancora in sviluppo e non stabili, pertanto in queste versioni potrebbe verificarsi anche un cambio di API nelle feature release.
\paragraph{Licenza}\mbox{}\\
Il progetto è open-source rilasciato con licenza GPL-3
\paragraph{Use-Case diagram}\mbox{}\\
\begin{figure}[H]
\centering
\includegraphics[width=1\textwidth]{general_use_case.png}
\end{figure}
\subsection{Specifiche Tecniche}
\subsubsection{Database}
Il database che gestisce i dati di ExploitFarm, data l'elevata mole di dati aspettata e la velocità di ricerca dei dati richiesta, è postgres e a seguito della stesura dell'analisi dei requisiti è stato progettato seguendo il seguente schema E/R
\begin{figure}[H]
\centering
\includegraphics[width=0.6\textwidth]{ExploitFarmDB.png}
\end{figure}
Alcune note aggiuntive:
\begin{itemize}
\item Env è una tabella che continene alcuni parametri di configurazione di ExploitFarm
\item Submitter è una collezione di script python candidati come submitter per il sistema, essendo slegato dalla logica di attacco non ha alcuna relazione con le altre tabelle
\end{itemize}
\subsubsection{Redis}
Il sistema integra un server redis per la coordinazione tra i vari processi all'interno del backend, per permettere una comunicazione immediata tra i vari processi, gestione della cache delle stats, e la gestione delle websocket Socket.Io integrate per gli aggiornamenti realtime sui client
\subsubsection{Gestione funzionalità backend}
Il backend di ExploitFarm è composto da 3 parti principali
\begin{itemize}
\item HTTP API routing and serving
\item Stats Processor
\item Submitter Process
\item SocketIo Process (skio process)
\end{itemize}
\paragraph{API HTTP}\mbox{}\\
L'API HTTP Si occupa di rispondere alle richieste dei client che per la necessità (come da requisito) di mantenere le configurazioni aggiornate, hanno un peso non indifferente sulle richieste fatte, pertanto le API sono parallelizzate per mantenere il sistema reattivo.
\paragraph{Stats processor}\mbox{}\\
Lo stats processor è nato come necessità dato l'elevato costo computazionale del calcolo dei dati per le statistiche inizialmente affidato alle API HTTP. Lo stato processo in maniera asincrona dal resto del sistema, scarica incrementalmente i dati dal database, e incrementa sempre in maniera scalare un dato strutturato json che contiene i contatori di flag e attacchi sulla base di parametri fortemente eterogenei quali lo stato dell'attacco, lo stato della submission della flag, il team target dell'attacco, il client che ha eseguito l'attacco, il servizio associato e l'exploit associato. La seguente struttura dati ha permesso la generazione dei dati ai fini della creazione dei grafici senza appesantire il sistema ad ogni richiesta dei dati. Le statistiche vengono salvati nel server redis permettendone la condivisione tra i vari processi, L'API HTTP si limita a scaricare ed esporre i dati. Ci sono particolari casi per modifica di configurazioni per cui lo stats processor ricrea da 0 le statistiche, ma prelevando i dati a blocchi per evitare sovraccarichi, e un ricalcolo stesso incrementale.
\paragraph{Submitter Process}\mbox{}\\
Il submitter process si occupa della submission delle flag al gameserver dell'infrastruttura di gioco. In particolare rispettando i timeout e le regole configurate nella fase di setup e aggiornando i dati con le ultime modifiche eseguite al submitter anche in fase di esecuzione.
Il submitter inoltre verifica il corretto funzionamento dello script scritto dal team e segnala tempestivamente sia in tutti i client sia nella pagina frontend eventuali errori o warning permettendo al team di verificare e riparare tempestivamente lo script di submission, evitando di perdere punti a causa di errori nella fase di scrittura dello script di submission.
\paragraph{SocketIo Process}\mbox{}\\
Il processo dedicato a socket.io si occupa di replicare su delle websocket accessibili ed usate dal frontend e da xfarm per permettere la segnalazione immediata di cambiamenti (i client poi si occupano di aggiornare i dati che hanno subito aggiornamenti).
Inoltre questo processo per gli stessi fini, periodicamente verifica lo stato degli exploit e scatena un evento di aggiornamento per gli exploit in caso un exploit non risponda da troppo tempo. Lo stesso processo si occupa di gestire l'interazione con i vari client negli attacchi condivisi, coordinadoli tramite le websocket socket.io.
\subsubsection{Funzionalità frontend}
Il frontend deve essere reattivo e dinamico, pertanto utilizza tecnologie come react per la sua realizzazione. Il frontend deve gestire il login alla piattaforma se configurato, eseguire il setup iniziale, offrire un editor per la gestione del submitter, visualizzazione di grafici, tabella delle ultime flag attenute, visualizzare lo status dei vari exploit, i log dei vari attacchi.
In particolare la schermata principale del frontend deve offrire statistiche tramite grafici su flag, team e attacchi configurabili in base anche a dei filtri nei limiti delle statistiche offerte dal stats processor backend.
Tramite le websocket esposte backend il frontend monitora gli eventi e aggiorna i dati che hanno subito modifiche.
\subsubsection{Strutturazione del client (xfarm)}
Il client xfarm è installato nei sistemi tramite la libreria di exploitfarm disponibile sul package manager di python pip, e consiste in una Terminal UI (TUI) che deve permettere la creazione e avvio degli exploit in maniera semplice. In particolare si deve evitare la memorizzazione e l'utilizzo di flag a riga di comando spesso scomodi da utilizzare. xfarm deve richiedere automaticamente la password di autenticazione se richiesta dal backend stesso, chiedere in input e memorizzare in un file di configurazione a livello di utente di sistema, i dati utili alla connessione al backend di ExploitFarm. Queste informazioni devono essere richieste solo una volta, e il client deve automaticamente rilevare il cambio di server exploitfarm tramite un uuid generato dal server per ogni deploy. Inoltre il client deve assicurarsi che la versione del client stesso coincida con quella del server al fine di evitare incongruenze tra client e server. Il client deve anche creare l'ambiente per l'exploit, dove scrivere l'exploit. Il workspace dell'exploit deve essere adatto alla facile pacchettizzazione e auto-avvio dell'attacco anche su altri client. L'exploit deve poter essere scritto per qualsiasi linguaggio, tuttavia ExploiFarm offrirà funzionalità già scritta nella sua libreria per gli script in python dato che rappresenta il linguaggio maggiormente utilizzato per la scrittura di exploit nelle attack defence.
\subsubsection{Autobilanciamento del carico sul client per l'esecuzione degli attacchi}
L'esecuzione degli attacchi agli altri team deve avvenire con un timeout per attacco dinamico e calcolato in base alle risorse della macchina su cui il client è in esecuzione disponibili in realtime, quindi deve adattarsi in base al carico che il sistema ha in quel momento.
Il flusso di esecuzione di un attacco è rappresentato dal seguente schema:
\begin{figure}[H]
\centering
\includegraphics[width=0.45\textwidth]{attack_sequence.png}
\end{figure}
\subsubsection{Gestione e versioning degli exploit}
Il client deve permettere l'invio il download e l'update degli exploit caricati sulla piattaforma e di quello presente in locale. Questa funzionalità permette una facile condivisione dei sorgenti degli exploit con gli altri componenti del team ed è fondamentale feature per l'implementazione degli attacchi condivisi.
\subsubsection{Controllo distribuito degli attacchi condivisi}
Il backend tramite anche uno scambio di dati con i client deve bilanciare l'assegnazione dei team ai vari client negli attacchi condivisi senza una configurazione manuale dei pesi sui vari client sulla quantità di team da associare ad ogniuno di questi. Gli attacchi condivisi devono rispettare i cambiamenti di configurazioni e verificare che tutti i client periodicamente, in caso di client non in risposta deve permettere per quanto possibile di portare a termine l'esecuzione di tutti gli attacchi.
La comunicazione tra i client e il server riguardante il controllo distribuito è interamente basato su socket.io.
Gli attacchi condivisi pertanto procedono secondo il seguente workflow:
\begin{enumerate}
\item Creazione di un gruppo di attacco (insieme di client associati ad un exploit)
\item Join di ulteriori client nel gruppo di attacco
\item Start dell'attack group
\item Eventuali nuovi join/left nel gruppo
\item Chiusura del gruppo di attacco
\end{enumerate}
\begin{figure}[H]
\centering
\includegraphics[width=0.45\textwidth]{shared_attack_sequence.png}
\end{figure}
\paragraph{Definizione dei parametri disponibili e calcolati dal sistema}\mbox{}\\
Contestualizziamo il problema periodicamente, analizzandone il processo per 1 tick/round, che poi andrà periodizzato per quanto necessario.
\begin{itemize}
\item $N_C$: Numero di client nel gruppo
\item $N_T$: Numero di team totali\\\\
Individueremo in seguito $i = [0,N_C-1]$ l'indice relativo al client\\
Inoltre definiamo $j = [0, N_T-1]$ l'indice relativo ai team, e quindi all'attacco eseguito nel tick
\item $Q_i$: grandezza della coda di esecuzione per l' i-esimo client. (definita esplicitamente in seguito)
\item $R_i$ attacchi in esecuzione sul client (sempre $<= Q_i$)
\item $T_R$ Tick/Round time (Tempo definito nel setup relativo alla durata di un round)
\item $T_K$ Timeout associato agli attacchi (Kill time)
\item $T_{C,j}$ Tempo effettivamente consumato per il j-esimo attacco (per il j-esimo team)
\item $T_{T,j}$ Ultimo tempo di timeout calcolato per il j-esimo attacco (per il j-esimo team)
\end{itemize}
\paragraph{Valutazione della potenza computazionale di ogni client}\mbox{}\\
Ai fini di distribuire in base alle risorse disponibili nel gruppo di attacco proporzionalmente a quelle che è la potenza computazionale del singolo client. Al Join/Avvio di un gruppo verrà consigliato un numero di processi in contemporanea da assegnare all'attack group, che sarà personalizzabile dall'utente (questo per valutarlo in base al carico che ci si aspetta di avere per l'attacco). Questo parametro verrà utilizzato come parametro di valutazione sulla potenza del client dato che di default verrà consigliato un valore calcolato sulla base di quanti core sono disponibili sulla macchina.
\paragraph{Gestione del tempo di esecuzione per ogni attacco}\mbox{}\\
Il sistema ha come obiettivo quello di riuscire ad eseguire tutti gli attacchi entro il tempo di tick: ai fini di perseguire questo obiettivo, si definisce un timeout globale, inizialmente impostato ad un tempo che ne permette l'esecuzione degli attacchi assegnando slot temporali uguali ad ogni esecuzione. Tuttavia durante l'esecuzione degli attacchi, se questi occuperanno meno tempo, dovranno in qualche modo influire sul tempo di timeout incrementandolo, dando quindi la possibilità di terminare l'esecuzione di attacchi su team in cui l'operazione sta richiedendo un tempo superiore a quello medio degli attacchi. Si definisce la tecnica utilizzata per il calcolo di questo tempo dinamico in seguito.
Inoltre, i processi seguiranno in ogni caso un timeout globale che ne terminerà l'esecuzione in ogni caso superato il tick time. (Questo timeout è indipendente dal primo timeout dinamico)
\paragraph{Algoritmo di distribuzione degli attacchi}\mbox{}\\
Saputi la grandezza delle $Q_i$ code per ogni client, l'assegnazione dei processi avviene tramite una priority queue, in cui ad ogni client viene associato una priorità calcolata, e viene associato un attacco a quel processo che ha priorità maggiore.
IL sistema entra in uno stato di attesa se il processo con la priorità più alta ha come valore un valore $<= 0$.
La priorità chiamata $P_{CL, i}$ (Processi per client assegnabili) è calcolata tramite la seguente formula:
\\\\$P_{CL, i} = \frac{Q_i-R_i}{min\{Q_i\}}$\\\\
La seguente formula varia dinamicamente il suo valore per client dipendentemente al carico assegnato, al quantitativo di risorse disponibili e modulato sulla base del client più "debole" nella coda.
Nello specifico l'algoritmo prende i client con $P_{CL, i} >= 1$ ed associa ad ogniuno un numero di attacchi pari a $\lfloor{}P_{CL, i}\rfloor{}$. Terminata una iterazione sui client, si riesegue la stessa operazione.
Se non ci sono client con $P_{CL, i} >= 1$ allora si procede a considerare tutti i client con $P_{CL, i} > 0$ assegnando ciclicamente un processo al client per cui risulta: $P_{CL, i} = max\{P_{CL_i}\}$.
Se non ci sono client con $P_{CL}>0$ allora il sistema rimane in attesa di nuovi eventi.
Si specifica che ad ogni assegnazione di un nuovo attacco ad un client $R_i$ viene incrementato: al contrario nel momento in cui un client termina l'esecuzione di un attacco $R_i$ viene decrementato.
In caso nuovi client entrano nel gruppo non si modifica lo stato di esecuzione corrente, ma si ricalcolano i coefficienti e si procede come precedentemente descritto. La medesima cosa succede per client che abbandonano il gruppo, che tuttavia in questo caso comporterà un riaccodamento dei processi che erano in esecuzione su quel client. Ciò avviene anche se si verifica la perdita della connessione considerando il client come fuori dal gruppo, in questo caso il client deve terminare la sua esecuzione, poichè il server ri-assegnerà i task che stava eseguendo.
\begin{figure}[H]
\centering
\includegraphics[width=0.45\textwidth]{attack_assign.png}
\end{figure}
\paragraph{Algoritmo di calcolo del timeout}\mbox{}\\
NOTA: Di seguito si descriverà come verrà calcolato il timeout da applicare ad ogni processo dipendentemente dalla possibilità di eseguire tutti gli attacchi entro il tick: Questo timeout quindi definisce il tempo che verrebbe assegnato al primo processo avviato per permetterne l'esecuzione degli altri. Ciò implica che durante i ricalcoli successivi descritti in seguito ci potrebbero essere timeout che eccedono dal tempo del tick. Questo non comporta un problema poichè come descritto precedentemente in contemporanea al vincolo del seguente timeout viene applicato anche un vincolo globale e statico, che mette come soglia massima per l'esecuzione la fine del tick, pertanto non sarà in ogni caso possibile eccedere dal tick per l'esecuzione di un attacco relativo al tick stesso.\\\\
Definiamo dei nuovi valori di tempo:
\begin{itemize}
\item $T_{J, i}$: Tempo di join dell' i-esimo client: Questo tempo vale 0 se il client ha eseguito il join prima dell'inizio del tick, mentre assume un valore che corrisponde al tempo mancante al termine del tick se riguarda un client che ha eseguito il join durante questo tick.
\item $T_{L, i}$: Tempo di left dell' i-esimo client: Questo tempo vale il tempo rimanente lasciato non in esecuzione dalla fine del tick del j-client che esce dal gruppo. Se il j-esimo client non è uscito dal gruppo questo tick questo valore vale 0
\item $T_{LJ, i} = T_{J,i}-T_{l,i}$: Tempo di left/join per client (definisce il guadagno totale dato dai left e join di un singolo client).
\item $T_{LJ} = \sum_{i} T_{LJ,j} Q_i$: Tempo totale di left/join (definisce in totale il tempo guadagnato/perso a causa delle operazioni di join e left dei client)
\item $T_{G, j} = T_{T,j} - T_{C, j}$: Tempo di guadagno per attacco
\item $T_G = \sum_{j} T_{G,j}$: Tempo di guadagno totale
\item $T_{VB} = \sum_{i} Q_i T_R$: (tempo virtualmente disponibile di base) interpretabile come il tempo totale disponibile di esecuzione su un core singolo per tick, calcolato all'inizio del tick.
\item $T_{V} = T_{VB} + T_G + T_{LJ}$: Tempo virtualmente disponibile
\end{itemize}
Il tempo virtualmente disponibile tiene conto dei tempi guadagnati grazie alla veloce esecuzione di alcuni attacchi, permettendo di ridistribuire questo tempo tra gli altri processi. Questo tempo può incrementare o diminuire durante l'esecuzione anche in base all' abbandono o al join di nuovi client, pertanto si presta utile al calcolo del timeout flessibilmente a quelle che sono le disponibilità istante per istante.\\\\
Tramite questo tempo definiamo infine il timeout $T_K = \frac{T_V}{N_T}$
Anch'esso varia in base al numero di team che potrebbe variare durante l'esecuzione.
\section{Conclusioni}
\subsection{Discussione}
Il progetto ha dovuto subire fortissime modifiche e rallentamenti a causa di 2 problematiche emerse durante lo sviluppo stesso, tra cui l'utilizzo di un ORM che con il rilascio di python 3.13 non essendo aggiornato ha causato problematiche tecniche, e che a causa di questo è stato sostituito con l'ORM attualmente utilizzato: SqlModel sviluppato dagli stessi creatori di FastAPI e basato su SQLAlchemy che è un progetto molto più solido stabile supportato e ampiamente utilizzato rispetto a Ormar (l'ORM scelto precedentemente). Il cambio di ORM ha richiesto un refactoring totale del backend permettendo però si sviluppare query più ottimizzate rispetto al builder di query di ormar molto più limitato nelle sue funzionalità.
Inoltre per la necessità di implementare una comunicazione realtime tra i client e il server, l'implementazione di redis e socket io ha permetto la ristrutturazione del progetto dall'utlizzo di richieste in polling che andavano a consumare risorse in continuazione e a generare traffico non utile, ad un approccio di gestione più event driven che ha reso molto più efficiente e immediatamente reattiva tutta l'interfaccia, e la comunicazione dei vari worker backend in maniera più efficiente grazie ai pubsub di redis e la cache condivisa. Inoltre è stato anche completamente ristrutturato lato client xfarm la parte di attacco ed è stata anche migliorato il calcolo del timeout sulle esecuzioni standalone riprendendo il meccanismo ideato per gli attacchi condivisi, studiato in maniera più metodica e sicuramente più efficiente di quello precedentemente utilizzato. Ne è risultato pertanto un fortissimo miglioramento della qualità del codice e ristrutturazione di alcune parti in classi che rendono il codice molto più facilmente integrabile e mantenibile rispetto a com'era strutturato prima del grande lavoro di refactoring eseguito, che è stato fondamentale per lo sviluppo delle nuove feature. Questo è stato causato anche dall'iniziale fretta necessaria allo sviluppo vista la deadline della competizione svoltasi questo luglio in cui il progetto era in uno stato intermedio e poco completo ma funzionale.
\subsection{Considerazioni finali}
Il progetto ha attualmente raggiungo i suoi obiettivi finali ed è attualmente alla sua versione 1.1.0, avrebbe bisogno di una fase di testing estensiva per assicurarne la stabilità nell'utilizzo reale, già parzialmente testato tramite dei test manuali eseguiti. Tuttavia è fondamentale assicurarne il completo funzionamento in delle casistiche reali che saranno possibili da eseguire nella prossima edizione di CyberChallenge durante le simulazioni delle Attack Defence per raccogliere punti di miglioramento dagli stessi partecipanti sul come rendere più intuitivo l'utilizzo, e l'individuazione di bug e ulteriori errori nelle varie parti sviluppate.
\subsection{Sviluppi Futuri}
\begin{itemize}
\item eliminare come single point of failure il server e permettere l'esecuzione di backend multipli e decentralizzati così da evitare in caso di problemi con uno dei server. La gestione di backend decentralizzati è di una complessità altissima e non strettamente necessario per gli obiettivi del progetto pertanto si lascia come sviluppo futuro.
\item Sviluppo dei test sulle API backend e integrarli nel rilascio delle release.
\end{itemize}
\subsection{Bibliografia}
\begin{itemize}
\item Progetto comparato: DestructiveFarm: \href{https://github.com/DestructiveVoice/DestructiveFarm}{https://github.com/DestructiveVoice/DestructiveFarm}
\item CyberChallenge: \href{https://cyberchallenge.it/}{https://cyberchallenge.it/}
\item FaustCTF: A/D for beginners \href{https://2024.faustctf.net/information/attackdefense-for-beginners/}{https://2024.faustctf.net/information/attackdefense-for-beginners/}
\item Pagina Github ExploitFarm: \href{https://github.com/Pwnzer0tt1/exploitfarm}{https://github.com/Pwnzer0tt1/exploitfarm}
\item CTFd: \href{https://github.com/CTFd/CTFd}{https://github.com/CTFd/CTFd}
\end{itemize}
\end{document}