Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
blogpost_cve-2018-19987-analysis — Questo repository ha un post sul blog riguardante la mia analisi di CVE-2018-19987, un'iniezione di comandi del sistema operativo autenticata che colpisce diversi router D-Link. | Kitploit
Strumenti/GitHubGitHub/nahueldsanchez/blogpost_cve-2018-19987-analysis
Sicurezza IoTAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPaper e RicercaApprendimento e FormazioneAnalisi del Firmware
GitHubnahueldsanchez/blogpost_cve-2018-19987-analysis

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

blogpost_cve-2018-19987-analysis

Questo repository ha un post sul blog riguardante la mia analisi di CVE-2018-19987, un'iniezione di comandi del sistema operativo autenticata che colpisce diversi router D-Link.

Vedi Repository
2135 anni faNon ancora revisionato

Analisi di CVE-2018-19987 (Iniezione di comandi OS D-Link) Twitter URL

Twitter Follow

Ciao a tutti!

In questo breve post del blog analizzerò una rapida analisi che ho svolto per comprendere meglio i dettagli dietro CVE-2018-19987. All'inizio ho cercato questa CVE perché pensavo che non ci fossero informazioni pubbliche o exploit. Poco dopo aver eseguito una prima analisi, ho trovato due PoC pubblici su GitHub che potete trovare qui e qui.

Poiché avevo già fatto la maggior parte del lavoro e non avevo trovato un'analisi completa, ho deciso di scrivere comunque il post del blog.

Spero vi piaccia!

Aggiornamento: Beh... dopo aver cercato su Google mentre ero bloccato con questo post, ho trovato il seguente articolo che descrive una vulnerabilità molto simile (CVE-2018-19986) nel D-Link DIR-818. Analisi della vulnerabilità del router serie (5): CVE-2018-19986 analisi e riproduzione della vulnerabilità di iniezione di comandi DIR-818LW&828 (tradotto da Google) di Ogur1.

Analisi di CVE-2018-19987

Ho iniziato la mia analisi raccogliendo tutte le informazioni possibili sul dispositivo:

  • Nome commerciale: D-Link DIR-822-US
  • Pagina del prodotto: https://us.dlink.com/en/products/dir-822-d-link-wifi-router-ac1200-dual-band
  • Pagina(e) di supporto: https://support.dlink.com/ProductInfo.aspx?m=DIR-822-US
  • Modello: DIR-822 Revisione C (altri dispositivi sono stati interessati)
  • Versione firmware affetta: FW v3.01B02
  • Nome file firmware affetto: DIR822C1_FW301WWb02.bin (md5sum: 1bff7ec8b4da0643f65b4d44c630e92b)
  • Versione firmware corretta: FW v3.13
  • Nome file firmware corretto: DIR822C1_FW313WWb01.bin (md5sum: aa16c7016f67be384e0784e439ce26d2)
  • Pagina archivio firmware: ftp://ftp2.dlink.com/PRODUCTS/DIR-822-US/REVC/

Analisi della causa principale

Nota: ho eseguito tutta l'analisi con il firmware v3.01B02.

Le informazioni pubbliche per questa vulnerabilità, disponibili sulla pagina di Mitre, fornivano informazioni sufficienti per iniziare:

root@kitploit:~
I dispositivi D-Link DIR-822 Rev.B 202KRb06, DIR-822 Rev.C 3.10B06, DIR-860L Rev.B 2.03.B03, DIR-868L Rev.B 2.05B02, DIR-880L Rev.A 1.20B01_01_i3se_BETA e DIR-890L Rev.A 1.21B02_BETA gestiscono in modo errato IsAccessPoint in /HNAP1/SetAccessPointMode. Nel codice sorgente di SetAccessPointMode.php, il parametro IsAccessPoint viene salvato nel file script ShellPath senza alcuna verifica regex. Dopo l'esecuzione del file script, si verifica l'iniezione di comandi. Un messaggio XML /HNAP1/SetAccessPointMode vulnerabile potrebbe contenere metacaratteri shell nell'elemento IsAccessPoint come la stringa `telnetd`.

Per iniziare l'analisi avevo bisogno di qualcosa da esaminare, quindi ho proceduto a estrarre il FS del router.

root@kitploit:~
binwalk -eM DIR822C1_FW301WWb02.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             DLOB firmware header, boot partition: "dev=/dev/mtdblock/1"
10380         0x288C          LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 4213444 bytes
1376372       0x150074        PackImg section delimiter tag, little endian size: 10505216 bytes; big endian size: 5021696 bytes
1376404       0x150094        Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 5019773 bytes, 2282 inodes, blocksize: 131072 bytes, created: 2016-03-18 09:35:31

Come possiamo vedere, Binwalk rileva un filesystem Linux. Se diamo un'occhiata più approfondita alle informazioni che abbiamo, possiamo vedere che l'avviso menziona il percorso /HNAP1. Quindi, possiamo iniziare a esaminare come il router gestisce questi URL.

Gestione delle richieste HNAP1

Come spiegato nell'eccellente /dev/tty0 blog post, questi URL alla fine vengono gestiti da un binario chiamato cgibin, situato in htdocs/cgibin. Ma volevo capire meglio come era configurato e alla fine mi ha portato a dover capire come il server HTTP fosse configurato per elaborare le richieste. Ho proceduto a cercare il nome del file httpd.conf, supponendo che fosse usato per configurare il server HTTP, e ho trovato un file chiamato HTTP.php nella cartella /etc/services/, contenente tra le altre cose le seguenti righe interessanti:

root@kitploit:~
$httpd_conf = "/var/run/httpd.conf";
fwrite("a",$START, "xmldbc -P /etc/services/HTTP/httpcfg.php > ".$httpd_conf."\n");
fwrite("a",$START, "event PREFWUPDATE add /etc/scripts/prefwupdate.sh\n");
fwrite("a",$START, "httpd -f ".$httpd_conf."\n");
fwrite("a",$START, "event HTTP.UP\n");
fwrite("a",$START, "exit 0\n");

Ho supposto che a un certo punto questo file viene eseguito e scrive il file /var/run/httpd.conf. Per imparare come era configurato il server web, ho proceduto ad analizzare il file /etc/services/HTTP/httpcfg.php (ho incluso solo le parti rilevanti):

root@kitploit:~
	if ($hnap > 0)
	{
		echo
		"		Control".							"\n".
		"		{".									"\n".
		"			Alias /HNAP1".					"\n".
		"			Location /htdocs/HNAP1".		"\n".
		"			External".						"\n".
		"			{".								"\n".
		"				/usr/sbin/hnap { hnap }".	"\n".
		"			}".								"\n".
		"			IndexNames { index.hnap }".		"\n".
		"		}".									"\n";
	}

Ora abbiamo tutti i pezzi! Possiamo supporre che il server web sia configurato per gestire le richieste HTTP a /HNAP1 usando /usr/sbin/hnap, e basandoci sul blogpost di /dev/tty0 sappiamo che sarà un collegamento al binario htdocs/cgibin.

Il passo successivo è stato dare un'occhiata al binario cgibin per capire come gestiva le richieste HNAP. Nell'immagine seguente possiamo vedere parte della funzione main decompilata dove il percorso URL passato viene confrontato con diversi percorsi (come session.cgi, authentication.cgi, captcha.cgi, per citarne alcuni) fino a quando non viene trovato hnap e viene chiamata la nostra funzione hnap_main.

nota: Durante l'analisi della funzione main, ho avuto alcuni problemi nell'identificare la stringa hnap perché Ghidra non l'ha rilevata come stringa durante l'analisi iniziale.

Il passo successivo è stato capire cosa faceva questa funzione. Fornirò solo snippet di codice per le parti rilevanti che aiuteranno a comprendere meglio cosa fa la funzione, e completerò anche altre parti rilevanti con del pseudocodice —ho rinominato alcune variabili per chiarirne lo scopo.

root@kitploit:~
...
HTTP_SOAPACTION = getenv("HTTP_SOAPACTION");
REQUEST_METHOD = getenv("REQUEST_METHOD");
HNAP_AUTH = getenv("HTTP_HNAP_AUTH");
__haystack = getenv("HTTP_COOKIE");
pcVar1 = getenv("HTTP_REFERER");

...
if (HTTP_SOAPACTION != "") {
	if  (HTTP_SOAPACTION == GetDeviceSettings) {
		...
	} else {
		// Queste azioni si verificano durante l'autenticazione. Elaborazione.
		if ("GetCAPTCHAsetting" in HTTP_SOAPACTION) {
			sess_generate_captcha();
		} else {
			if ("Login" in HTTP_SOAPACTION) {
				perform_login();
			}
			// Arriveremo qui dopo l'autenticazione.
			if (HNAP_AUTH != "") {
				if ("uid=" in HTTP_COOKIE){
					is_valid_auth = perform_auth_process()
					if (is_valid_auth) {
						if("logout" in HTTP_SOAPACTION){
							perform_logout();
						// Se siamo autenticati e NON stiamo tentando di disconnetterci
						// il codice tenterà di eseguire l'azione
						// che abbiamo richiesto
						} else {
							// Se arriviamo qui abbiamo vinto
							// codice interessante qui sotto
							goto LAB_004141d4;
						}

					}
				}
			}
			// Se non siamo autenticati non possiamo fare nulla
			Return "È necessaria un'autorizzazione adeguata per utilizzare questa risorsa"
		}
	}
} else {
	...
}

LAB_004141d4:
    hnap_action = get_hnap_operation(HTTP_SOAPACTION);
    if (HTTP_SOAPACTION != "") {
    	hnap_action_len = strlen(hnap_action);
	}
	snprintf(path_to_hnap_php_file,0x100,"%s/%s.php","/etc/templates/hnap/",hnap_action);
	if (!check_file_access(path_to_hnap_php_file)){
		return "L'AZIONE HNAP NON ESISTE (FALLIMENTO)"
	}
	if (REQUEST_METHOD == "POST") {

		// Qui vengono estratti gli argomenti per il PHP
		parse_request_and_extract_xml()
    
		if (hnap_action == "GetFirmwareStatus") {
        	system("sh /etc/events/checkfw.sh > /dev/console");
		}

		// Qui vengono costruiti gli argomenti finali per xmldbc_ephp
        snprintf(ARGS_FOR_XMLDBC_PHP,0x100,"%s%s.php\nShellPath=%s%s.sh\nPrivateKey=%s\n",
                 "/etc/templates/hnap/", hnap_action, &ShellPath, hnap_action, &PRIVATE_KEY);

		// Il PHP viene eseguito (nel nostro caso SetAccessPointMode.php) e lo script shell
		// viene scritto in ShellPath 
        xmldbc_ephp(0,0,ARGS_FOR_XMLDBC_PHP,stdout);
        snprintf(hnap_action, 0x100, "%s", hnap_action);
       
	   	// Viene costruito il comando shell per eseguire il file shell precedentemente scritto
		// (File scritto dallo script PHP)
        shell_command = "sh %s%s.sh > /dev/console &";
        }
        snprintf(cmd_to_execute, 0x100, shell_command, &PATH, hnap_action);

		// Il file viene eseguito contenente l'iniezione di comandi
        system(cmd_to_execute);
    }
...

Una volta completata l'analisi di questa funzione, ho deciso di dare un'occhiata al file PHP SetAccessPointMode.php — che alla fine conteneva la falla — e ho cercato di mettere insieme tutti i pezzi:

root@kitploit:~
...
$IsAccessPoint	= query("/runtime/hnap/SetAccessPointMode/IsAccessPoint");
...
fwrite("w",$ShellPath, "#!/bin/sh\n");
fwrite("a",$ShellPath, "echo [$0] $1 ... > /dev/console\n");
fwrite("a",$ShellPath, "echo IsAccessPoint = ".$IsAccessPoint." > /dev/console\n");
fwrite("a",$ShellPath, "echo Result = ".$Result."\n");
...

Come possiamo vedere, abbiamo la nostra variabile $ShellPath che viene riempita dalla funzione hnap_main e la variabile $IsAccessPoint che è controllata dall'utente e passata nella richiesta XML inviata. Con questo possiamo corroborare come un'iniezione di comandi OS nella variabile scritta dal file PHP venga eseguita. Qui potete trovare un PoC completo sviluppato da pr0v3rbs per sfruttare questo problema.

Parleremo un po' più avanti delle versioni affette e corrette. Come si può vedere nella tabella sottostante, sembra che ci sia stata una sorta di regressione con la patch, che ha reintrodotto questa vulnerabilità in versioni che avrebbero già dovuto essere corrette.

Versioni firmware analizzate

(*) Non ho controllato queste versioni firmware poiché le loro controparti non crittografate erano vulnerabili.

Come possiamo vedere nella tabella sopra, la vulnerabilità è stata corretta in alcune versioni firmware rimuovendo il file PHP interessato SetAccessPointMode.php. Una volta che il file non esiste, i controlli eseguiti nella funzione falliranno e non verrà eseguito nulla. Ho confermato questo analizzando la hnap_function nelle versioni firmware FW v3.131 e 3.15B02 WW; il codice per hnap_main non è cambiato in relazione a questo problema, ma il file PHP non era più presente.

Cosa ancora più interessante è che in qualche modo questo bug è stato reintrodotto nella versione firmware FW v3.11 fino a FW v3.12B04, dopo essere stato corretto nella versione 3.11B01_icjg_WW.

Conclusioni e passi successivi

Come prima conclusione, direi: non fidarti mai di questi dispositivi come dispositivi realmente sicuri — ciò che è successo con gli aggiornamenti è un chiaro esempio del perché non si dovrebbe fare. Inoltre, dopo l'analisi eseguita, posso concludere che il primo PoC elencato in questo post del blog non funzionerà per questa versione specifica, poiché abbiamo visto che ci sono alcune condizioni che devono essere soddisfatte per eseguire il file PHP vulnerabile.

E la conclusione più importante: fai molta attenzione quando decidi quanto è critica una vulnerabilità basandoti sul suo punteggio CVSS. Ho deciso di analizzare questa CVE perché era valutata 9.8 (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) ed è chiaro che, almeno per questa versione, l'attaccante avrà bisogno di credenziali per poterla sfruttare.

Come passi successivi, lavorerò per essere in grado di emulare questo binario per sfruttare questa vulnerabilità senza avere accesso al router stesso, ma questo sarà materiale per un altro post!

Grazie per aver letto.

Riferimenti

  • Writeup di Ogur1 per CVE-2018-19986
  • /dev/tty0 Blogpost D-Link HNAP
  • Avviso HNAP di Pedro Ribeiro
  • CVE-2018-19987 PoC #0 di Mario Ceballos
  • CVE-2018-19987 PoC #1 di Mingeun Kim
  • Dettagli CVE-2018-19987 Link
  • Decriptazione firmware D-Link
  • Binwalk
  • PoC di pr0v3rbs
Scarica lo strumento
FirmwareVersioneHash MD5Data di rilascioVulnerabile
DIR822C1_FW315WWb02.bin3.15B02 WW7121771c3e1706ba76fbf244023efad306/11/2019NO
DIR822C1_FW313WWb01.binFW v3.13aa16c7016f67be384e0784e439ce26d210/07/2019NO
DIR822C1_FW303WWb04_i4sa_middle.binFW v3.12B04c3b9a3f115c02e739690616aba2f2d9926/04/2019SÌ
DIR822C1_FW312WWb04.binFW v3.12B04eb11afbd136a5b29cea18141f727bfa826/04/2019SÌ (*)
DIR822C1_FW311WWb01.binFW v3.116d7c90eaaae835667faea65c862b3c8201/01/2019SÌ
DIR822C1_FW311bWWb01_icjg.bin3.11B01_icjg_WW75e361e1465604aeda5d5dbcaecca97721/12/2018NO
DIR822C1_FW303WWb04_i4sa_middle.binFW v3.10B06c3b9a3f115c02e739690616aba2f2d9917/08/2018SÌ
DIR822C1_FW310WWb06.binFW v3.10B06e33db75d0801fddb1c90308982e69fe517/08/2018SÌ (*)
DIR-822_C1_FW302WWb05.binFW v3.020dbf840c0ff5d3a5b593d33690e15d8214/09/2017SÌ
DIR822C1_FW301WWb02.binFW v3.01B021bff7ec8b4da0643f65b4d44c630e92b27/04/2016SÌ