Il Code Injection è l’inserimento di codice malevolo tramite barra degli indirizzi nel vostro browser o altri metodi ma tipicamente comunque tramite http ed è tanto più efficace quando il codice che viene passato non viene controllato o in questo caso si parla di validazione.
Facciamo un esempio
/** * Get the code from a GET input * Example - http://example.com/?code=phpinfo(); */ $code = $_GET['code']; /** * Unsafely evaluate the code * Example - phpinfo(); */ eval("\$code;");
Supponiamo che un utente malentenzionato digiti da barra degli indirizzi del browser il seguente codice
http://example.com/?code=phpinfo();
Ma questo è ovviamente il migliore dei casi . Potrebbe infatti anche inserire il comando shell whoami scrivendo
http://example.com/?code=system('whoami');
Ottenendo l’esecuzione del comando OS l’utente malintenzionato potrebbe tentare di ottenere persistenza utilizzando una webshell o installando altro malware. Da lì, un attaccante può persino tentare di ruotare su altri sistemi interni che di solito non vengono esposti pubblicamente. Che è un po’ la base per aprire le backdoors dei virus trojans.
Come prevenire questo tipo di attacco? C’è un solo metodo ossia una validazione molto stretta dei dati ricevuti sul comando GET del php.
Consideriamo la sottocategoria ancora comando Code Injection Execution.
Passiamo adesso ad analizzare la nota vulnerabilità del Code Injection Execution ossia sul versante PHP. Per rendere meglio l’idea traduciamo in italiano. Ossia vi stiamo parlando dell’esecuzione del codice iniettato .
Quindi si tratta di ricevere una stringa di codice , ancora una volta dalla barra degli indirizzi del browser con il metodo GET e mandare in esecuzione la stessa.
Per questo avremo bisogno del comando exec di PHP.
Spesso si genera un po’ di confusione fra Code Injection e Command Injection . Il primo è limitato al linguaggio da cui effettua l’attacco. Il secondo non lo è.
Consideriamo il seguente esempio
exec("ping -c 4 " . $_GET['host'], $output); echo "<pre>"; print_r($output); echo "</pre>";
Se lo mando in esecuzione pingando www.google.com
ottengo qualcosa del genere .
In questo caso la vulnerabilità sta nel comando exec che se non esattamente parsato è vulnerabile al simbolo ; per esempio se invece di www.google.com inserisco nella stringa
www.google.com;whoami
In uscita avrei in esecuzione anche il comando whoami.
Ovviamente qui siamo nel lecito, ma altrettanto ovviamente un maleintenzionato proverebbe a questo punto a scalare la shell.
Come vi ho già tempo la sicurezza in questi casi passa attraverso la validazione dei dati.
Quindi ogni caso è specifico. In questo ci vengono in aiuto le funzioni
escapeshellcmd() che esamina la stringa passata al fine di individuare tutta una serie di caratteri che potrebbero portare ad una vulnerabilità dello script. Come nel caso in questione. E lo marca con uno slash. Per esempio
Input: ping -c 4 www.google.com;comando^malevolo
Output: ping -c 4 www.google.com\;comando\^malevoloescapeshellarg() aggiunge virgolette singole attorno a una stringa e sfugge a tutte le virgolette singole esistenti in modo che l’intera stringa venga passata come singolo argomento a un comando di shell.
Quindi potremmo riscrivere il tutto come
Esempio di codice sicuro Code Injection
// #1 Restrict multiple commands exec(escapeshellcmd("ping -c 4 " . $_GET['host']), $output); // #2 Restrict multiple commands and multiple arguments exec(escapeshellcmd("ping -c 4 " . escapeshellarg($_GET['host'])), $output);