Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
blogpost_cve-2018-19987-analysis — Dieses Repo enthält einen Blogbeitrag über meine Analyse zu CVE-2018-19987, einer authentifizierten OS-Befehlsinjektion, die mehrere D-Link-Router betrifft. | Kitploit
Tools/GitHubGitHub/nahueldsanchez/blogpost_cve-2018-19987-analysis
IoT-SicherheitSchwachstellenanalyseExploitationWebanwendungs-ExploitationPapers & ForschungLernen & BildungFirmware-Analyse
GitHubnahueldsanchez/blogpost_cve-2018-19987-analysis

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

blogpost_cve-2018-19987-analysis

Dieses Repo enthält einen Blogbeitrag über meine Analyse zu CVE-2018-19987, einer authentifizierten OS-Befehlsinjektion, die mehrere D-Link-Router betrifft.

Repository anzeigen
21vor 5 JahrenNoch nicht geprüft

CVE-2018-19987 (D-Link OS command injection) – Analyse Twitter URL

Twitter Follow

Hallo zusammen!

In diesem kurzen Blogbeitrag stelle ich eine schnelle Analyse vor, die ich durchgeführt habe, um die Details hinter CVE-2018-19987 besser zu verstehen. Zunächst bin ich dieser CVE nachgegangen, weil ich dachte, dass es keine öffentlichen Informationen oder Exploits dazu gäbe. Kurz nach einer ersten Analyse fand ich zwei öffentliche PoCs auf GitHub, die ihr hier und hier finden könnt.

Da ich den Großteil der Arbeit bereits erledigt hatte und keine vollständige Analyse gefunden hatte, beschloss ich, den Blogbeitrag trotzdem zu schreiben.

Ich hoffe, er gefällt euch!

Aktualisierung: Nun ja, nachdem ich gegoogelt hatte, während ich an diesem Blogbeitrag festhing, fand ich den folgenden Artikel, der eine sehr ähnliche Schwachstelle (CVE-2018-19986) im D-Link DIR-818 beschreibt. Router-Schwachstellenanalyse-Serie (5): CVE-2018-19986 DIR-818LW&828 Command-Injection-Schwachstellenanalyse und -Reproduktion (Google-Übersetzung) von Ogur1.

CVE-2018-19987 – Analyse

Ich begann meine Analyse, indem ich alle verfügbaren Informationen über das Gerät sammelte:

  • Produktname: D-Link DIR-822-US
  • Produktseite: https://us.dlink.com/en/products/dir-822-d-link-wifi-router-ac1200-dual-band
  • Support-Seite(n): https://support.dlink.com/ProductInfo.aspx?m=DIR-822-US
  • Modell: DIR-822 Revision C (Andere Geräte waren betroffen)
  • Betroffene Firmware-Version: FW v3.01B02
  • Dateiname der betroffenen Firmware: DIR822C1_FW301WWb02.bin (md5sum: 1bff7ec8b4da0643f65b4d44c630e92b)
  • Behobene Firmware-Version: FW v3.13
  • Dateiname der behobenen Firmware: DIR822C1_FW313WWb01.bin (md5sum: aa16c7016f67be384e0784e439ce26d2)
  • Firmware-Archivseite: ftp://ftp2.dlink.com/PRODUCTS/DIR-822-US/REVC/

Analyse der Grundursache

Hinweis: Ich habe die gesamte Analyse mit der Firmware v3.01B02 durchgeführt.

Öffentliche Informationen zu dieser Schwachstelle, verfügbar auf Mitres Seite, lieferten genügend Informationen für den Einstieg:

root@kitploit:~
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, and DIR-890L Rev.A 1.21B02_BETA devices mishandle IsAccessPoint in /HNAP1/SetAccessPointMode. In the SetAccessPointMode.php source code, the IsAccessPoint parameter is saved in the ShellPath script file without any regex checking. After the script file is executed, the command injection occurs. A vulnerable /HNAP1/SetAccessPointMode XML message could have shell metacharacters in the IsAccessPoint element such as the `telnetd` string.

Um die Analyse zu beginnen, brauchte ich etwas, das ich untersuchen konnte, also extrahierte ich das Dateisystem des Routers.

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

Wie wir sehen können, erkennt Binwalk ein Linux-Dateisystem. Wenn wir die vorhandenen Informationen genauer betrachten, sehen wir, dass das Advisory den Pfad /HNAP1 erwähnt. Wir können also damit beginnen zu untersuchen, wie der Router diese URLs verarbeitet.

Behandlung von HNAP1-Anfragen

Wie in dem exzellenten /dev/tty0-Blogbeitrag erklärt, werden diese URLs letztendlich von einer Binärdatei namens cgibin verarbeitet, die sich unter htdocs/cgibin befindet. Ich wollte jedoch besser verstehen, wie dies konfiguriert war, und das führte mich schließlich dazu, verstehen zu müssen, wie der HTTP-Server konfiguriert war, um Anfragen zu verarbeiten. Ich suchte nach dem Dateinamen httpd.conf und nahm an, dass er zur Konfiguration des HTTP-Servers verwendet wird. Dabei fand ich eine Datei namens HTTP.php im Ordner /etc/services/, die unter anderem die folgenden interessanten Zeilen enthielt:

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");

Ich nahm an, dass diese Datei irgendwann ausgeführt wird und die Datei /var/run/httpd.conf schreibt. Um zu erfahren, wie der Webserver konfiguriert war, analysierte ich die Datei /etc/services/HTTP/httpcfg.php (ich habe nur die relevanten Teile aufgenommen):

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";
	}

Jetzt haben wir alle Puzzleteile! Wir können annehmen, dass der Webserver so konfiguriert ist, dass er HTTP-Anfragen an /HNAP1 mithilfe von /usr/sbin/hnap verarbeitet, und basierend auf dem /dev/tty0-Blogbeitrag wissen wir, dass es sich um einen Link auf die Binärdatei htdocs/cgibin handelt.

Der nächste Schritt war, die Binärdatei cgibin zu untersuchen, um zu verstehen, wie sie HNAP-Anfragen verarbeitet. Im folgenden Bild sehen wir einen Teil der dekompilierten main-Funktion, in der der übergebene URL-Pfad mit verschiedenen Pfaden verglichen wird (z. B. session.cgi, authentication.cgi, captcha.cgi, um nur einige zu nennen), bis hnap gefunden wird und unsere Funktion hnap_main aufgerufen wird.

Hinweis: Bei der Analyse der main-Funktion hatte ich einige Probleme, den hnap-String zu identifizieren, da Ghidra ihn während der ersten Analyse nicht als String erkannt hatte.

Der nächste Schritt war zu verstehen, was diese Funktion tut. Ich werde nur Codeausschnitte für die relevanten Teile bereitstellen, die helfen, besser zu verstehen, was die Funktion tut. Außerdem werde ich andere relevante Teile mit etwas Pseudocode vervollständigen — ich habe einige Variablen umbenannt, um ihren Zweck zu verdeutlichen.

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 {
		// These actions will occur during auth. Process
		if ("GetCAPTCHAsetting" in HTTP_SOAPACTION) {
			sess_generate_captcha();
		} else {
			if ("Login" in HTTP_SOAPACTION) {
				perform_login();
			}
			// We'll land here once auth.
			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();
						// If we are auth. and NOT trying to logout
						// the code will try to perform the action
						// we requested
						} else {
							// If we arrive here we win
							// interesting code below
							goto LAB_004141d4;
						}

					}
				}
			}
			// If we are not authenticated we can't do anything
			Return "You need proper authorization to use this resource"
		}
	}
} 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 "HNAP ACTION DOES NOT EXIST (FAIL)"
	}
	if (REQUEST_METHOD == "POST") {

		// Here arguments for the PHP are extracted
		parse_request_and_extract_xml()
    
		if (hnap_action == "GetFirmwareStatus") {
        	system("sh /etc/events/checkfw.sh > /dev/console");
		}

		// Here the final arguments for the xmldbc_ephp are crafted
        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);

		// PHP is executed (in our case SetAccessPointMode.php) and the shell
		// script is written to ShellPath 
        xmldbc_ephp(0,0,ARGS_FOR_XMLDBC_PHP,stdout);
        snprintf(hnap_action, 0x100, "%s", hnap_action);
       
	   	// Shell command is built to run the previously written shell file
		// (File written by the PHP script)
        shell_command = "sh %s%s.sh > /dev/console &";
        }
        snprintf(cmd_to_execute, 0x100, shell_command, &PATH, hnap_action);

		// File is executed containing the command injection
        system(cmd_to_execute);
    }
...

Nachdem die Analyse dieser Funktion abgeschlossen war, beschloss ich, einen Blick auf die PHP-Datei SetAccessPointMode.php zu werfen — die letztendlich die Datei mit dem Fehler war — und versuchte, alle Puzzleteile zusammenzusetzen:

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");
...

Wie wir sehen können, haben wir unsere Variable $ShellPath, die von der Funktion hnap_main gefüllt wird, und die Variable $IsAccessPoint, die vom Benutzer gesteuert und in der gesendeten XML-Anfrage übergeben wird. Damit können wir bestätigen, wie eine OS-Command-Injection in der von der PHP-Datei geschriebenen Variable ausgeführt wird. Hier findet ihr einen vollständigen, von pr0v3rbs entwickelten PoC, um dieses Problem auszunutzen.

Wir werden später noch etwas mehr über die betroffenen und behobenen Versionen sprechen. Wie ihr in der folgenden Tabelle sehen könnt, scheint es eine Art Regression mit dem Patch gegeben zu haben, die diese Schwachstelle in Versionen wieder einführte, die eigentlich bereits gepatcht sein sollten.

Analysierte Firmware-Versionen

(*) Ich habe diese Firmware-Versionen nicht überprüft, da ihre unverschlüsselten Gegenstücke verwundbar waren.

Wie wir in der obigen Tabelle sehen können, wurde die Schwachstelle in einigen Firmware-Versionen behoben, indem die betroffene PHP-Datei SetAccessPointMode.php entfernt wurde. Sobald die Datei nicht mehr existiert, schlagen die in der Funktion durchgeführten Prüfungen fehl und es wird nichts ausgeführt. Ich habe dies durch die Analyse der hnap_function in den Firmware-Versionen FW v3.131 und 3.15B02 WW bestätigt; der Code für hnap_main hat sich in Bezug auf dieses Problem nicht geändert, aber die PHP-Datei war nicht mehr vorhanden.

Noch interessanter ist, dass dieser Fehler irgendwie in den Firmware-Versionen FW v3.11 bis FW v3.12B04 wieder eingeführt wurde, nachdem er in Version 3.11B01_icjg_WW behoben worden war.

Schlussfolgerungen und nächste Schritte

Als erste Schlussfolgerung würde ich sagen: Betrachtet diese Geräte niemals als wirklich sichere Geräte — was mit den Updates passiert ist, ist ein klares Beispiel dafür, warum ihr das nicht tun solltet. Außerdem kann ich nach der durchgeführten Analyse schlussfolgern, dass der erste in diesem Blogbeitrag aufgeführte PoC für diese spezifische Version nicht funktionieren wird, da wir gesehen haben, dass bestimmte Bedingungen erfüllt sein müssen, um die verwundbare PHP-Datei auszuführen.

Und die wichtigste Schlussfolgerung: Seid sehr vorsichtig, wenn ihr entscheidet, wie kritisch eine Schwachstelle basierend auf ihrem CVSS-Score ist. Ich habe mich entschieden, diese CVE zu analysieren, da sie mit 9.8 bewertet wurde (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), und es ist klar, dass der Angreifer, zumindest für diese Version, Zugangsdaten benötigt, um sie ausnutzen zu können.

In den nächsten Schritten werde ich daran arbeiten, diese Binärdatei emulieren zu können, um diese Schwachstelle auszunutzen, ohne Zugriff auf den Router selbst zu haben, aber das wird Material für einen weiteren Beitrag sein!

Danke fürs Lesen.

Referenzen

  • Writeup von Ogur1 für CVE-2018-19986
  • /dev/tty0 D-Link HNAP Blogbeitrag
  • Pedro Ribeiros HNAP-Advisory
  • CVE-2018-19987 PoC #0 von Mario Ceballos
  • CVE-2018-19987 PoC #1 von Mingeun Kim
  • CVE-2018-19987 Details-Link
  • Entschlüsseln von D-Link-Firmware
  • Binwalk
  • pro0v3rbs PoC
Tool herunterladen
FirmwareVersionMD5-HashVeröffentlichungsdatumVerwundbar
DIR822C1_FW315WWb02.bin3.15B02 WW7121771c3e1706ba76fbf244023efad306/11/2019NEIN
DIR822C1_FW313WWb01.binFW v3.13aa16c7016f67be384e0784e439ce26d210/07/2019NEIN
DIR822C1_FW303WWb04_i4sa_middle.binFW v3.12B04c3b9a3f115c02e739690616aba2f2d9926/04/2019JA
DIR822C1_FW312WWb04.binFW v3.12B04eb11afbd136a5b29cea18141f727bfa826/04/2019JA (*)
DIR822C1_FW311WWb01.binFW v3.116d7c90eaaae835667faea65c862b3c8201/01/2019JA
DIR822C1_FW311bWWb01_icjg.bin3.11B01_icjg_WW75e361e1465604aeda5d5dbcaecca97721/12/2018NEIN
DIR822C1_FW303WWb04_i4sa_middle.binFW v3.10B06c3b9a3f115c02e739690616aba2f2d9917/08/2018JA
DIR822C1_FW310WWb06.binFW v3.10B06e33db75d0801fddb1c90308982e69fe517/08/2018JA (*)
DIR-822_C1_FW302WWb05.binFW v3.020dbf840c0ff5d3a5b593d33690e15d8214/09/2017JA
DIR822C1_FW301WWb02.binFW v3.01B021bff7ec8b4da0643f65b4d44c630e92b27/04/2016JA