OS command injection (iniezione di comando del sistema operativo o semplicemente iniezione di comando ) è un tipo di vulnerabilità injection. Il payload inserito dall'utente malintenzionato viene eseguito come comando del sistema operativo. Gli attacchi di inserimento di comandi del sistema operativo sono possibili solo nel caso in cui il codice dell'applicazione Web include chiamate al sistema operativo e l'input dell'utente viene utilizzato nella chiamata. Essi non hanno un linguaggio specifico - vulnerabilità di iniezione di comando possono apparire in tutti i linguaggi che consentono di chiamare un comando della shell di sistema: C, Java, PHP, Perl, Ruby, Python, e molti alti.
Il sistema operativo esegue i comandi arbitrari inseriti con i privilegi del server web. Pertanto, di per sé, la vulnerabilità di iniezione di comando non porta alla compromissione completa del sistema. Tuttavia, gli aggressori potrebbero essere in grado di utilizzare l'escalation dei privilegi e altre vulnerabilità per ottenere più accesso.
Nota: L'iniezione di comando è spesso confusa con l'iniezione di codice . Le vulnerabilità di inserimento di codice consentono all'utente malintenzionato di inserire un codice nel linguaggio di programmazione in cui è compilata l'applicazione Web.
Esempio di inserimento dei comandi
Lo sviluppatore dell'applicazione PHP di esempio desidera che l'utente sia in grado di visualizzare l'output del comando Windows ping nell'applicazione web. L'utente deve inserire l'indirizzo IP e l'applicazione invia ping ICMP a tale indirizzo. Sfortunatamente, lo sviluppatore considera troppo attendibile l'utente e non esegue la convalida dell'input. L'indirizzo IP viene passato utilizzando il metodo GET e quindi utilizzato nella riga di comando.
Codice: Seleziona tutto
<?php
Codice: Seleziona tutto
$address = $_GET["address"];
Codice: Seleziona tutto
$output = shell_exec("ping -n 3 $address");
Codice: Seleziona tutto
echo "<pre>$output</pre>";
Codice: Seleziona tutto
?>
L'utente malintenzionato abusa di questo script manipolando la richiesta GET con il seguente payload:
Codice: Seleziona tutto
http://example.com/ping.php?address=8.8.8.8%26dir
La funzione shell_exec esegue il comando del sistema operativo seguente: ping -n 3 8.8.8.8&dir. Il simbolo & in Windows separa i comandi del sistema operativo. Di conseguenza, l'applicazione vulnerabile esegue un comando aggiuntivo (dir) e visualizza l'output del comando (elenco directory) sullo schermo:
Codice: Seleziona tutto
Pinging 8.8.8.8 with 32 bytes of data:
Codice: Seleziona tutto
Reply from 8.8.8.8: bytes=32 time=30ms TTL=56
Codice: Seleziona tutto
Reply from 8.8.8.8: bytes=32 time=35ms TTL=56
Codice: Seleziona tutto
Reply from 8.8.8.8: bytes=32 time=35ms TTL=56
Codice: Seleziona tutto
Ping statistics for 8.8.8.8:
Codice: Seleziona tutto
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Codice: Seleziona tutto
Approximate round trip times in milli-seconds:
Codice: Seleziona tutto
Minimum = 30ms, Maximum = 35ms, Average = 33ms
Codice: Seleziona tutto
Volume in drive C is OS
Codice: Seleziona tutto
Volume Serial Number is 1337-8055
Codice: Seleziona tutto
Directory of C:\Users\Noob\www
code[/code]
Caratteri speciali di iniezione di comando
È possibile utilizzare caratteri speciali diversi per inserire un comando arbitrario. Il più semplice e più comune per Linux è il punto e virgola (;) e per Windows, la e commerciale (&). Tuttavia, anche i seguenti payload per lo script ping.php funzioneranno:
address=8.8.8.8%3Bwhoami ( carattere;, solo Linux)
address=8.8.8.8&26whoami ( carattere & , solo Windows)
address=8.8.8.8%7Cwhoami (carattere |)
address=invalid%7C%7Cwhoami ( caratteri ||, il secondo comando viene eseguito solo se il primo comando ha esito negativo)
address=8.8.8.8&26&26whoami (caratteri && )
%3E(whoami) (carattere > , solo Linux)
%60whoami%60 ( solo carattere` , solo Linux, il risultato verrà segnalato dal comando ping come errore)
Comando Prevenzione dell'iniezione
Esistono diversi metodi per garantire la sicurezza dell'applicazione e impedire l'esecuzione arbitraria di comandi tramite inserimento di comandi. Il più semplice e sicuro è quello di non utilizzare mai chiamate come shell_exec in PHP per eseguire i comandi del sistema operativo host. È invece necessario utilizzare i comandi equivalenti del linguaggio di programmazione. Ad esempio, se uno sviluppatore desidera inviare posta utilizzando PHP su Linux/UNIX, potrebbe essere tentato di utilizzare il comando mail disponibile nel sistema operativo. Dovrebbero invece utilizzare la funzione mail() in PHP.
Questo approccio può essere difficile se non esiste un comando equivalente nel linguaggio di programmazione. Ad esempio, non esiste un modo diretto per inviare pacchetti ping ICMP da PHP. In questi casi, è necessario utilizzare l'igienizzazione dell'input prima di passare il valore a un comando della shell. Come con tutti i tipi di iniezioni, il modo più sicuro è quello di utilizzare una whitelist. Ad esempio, nello script ping.php, è possibile verificare se la variabile address è un indirizzo IP:
Codice: Seleziona tutto
$address = filter_var($_GET["address"], FILTER_VALIDATE_IP);
Si sconsiglia di utilizzare le liste nere perché gli aggressori potrebbero trovare un modo per aggirarle. Tuttavia, se è assolutamente necessario utilizzare una lista nera, è necessario filtrare o eseguire l'escape dei seguenti caratteri speciali:
Windows: ( ) < /> & = ? ; [ ] ^ ~ ! . " % / : : , '
Linux: ( ) < /> & = ? ; [ ] : – : ! . " % / : : , '