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
ctl_ctloutput-leak — CVE-2017-13868: Informationsleck uninitialisierter Kernel-Heap-Daten in XNU. | Kitploit
Tools/GitHubGitHub/bazad/ctl_ctloutput-leak
SpeicherforensikSchwachstellenanalyseExploitationInformationsbeschaffungBinary-Exploitation
GitHubbazad/ctl_ctloutput-leak

ctl_ctloutput-leak

CVE-2017-13868: Informationsleck uninitialisierter Kernel-Heap-Daten in XNU.

Repository anzeigen
2752vor 8 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

ctl_ctloutput-leak

Die Funktion ctl_ctloutput unter macOS High Sierra 10.13 ignoriert den Rückgabewert eines Aufrufs von sooptcopyin, wodurch ein Race-Fenster entsteht, um nicht initialisierte Kernel-Heap-Daten an den Benutzerbereich preiszugeben. ctl_ctloutput-leak ist ein Proof-of-Concept-Exploit, der versucht, diesen Informationsleck auszulösen. Für die Ausnutzung sind Root-Rechte erforderlich.

Dieser Exploit wurde erfolgreich unter macOS High Sierra 10.13.1 Beta 17B25c und iOS 10.1.1 14B100 (unter mach_portal) getestet.

Die Schwachstelle: CVE-2017-13868

Hier ist der relevante Teil von ctl_ctloutput unter macOS High Sierra 10.13:

root@kitploit:~
if (sopt->sopt_valsize && sopt->sopt_val) {
	MALLOC(data, void *, sopt->sopt_valsize, M_TEMP,	// (a) data is allocated
		M_WAITOK);					//     without M_ZERO.
	if (data == NULL)
		return (ENOMEM);
	/*
	 * 4108337 - copy user data in case the
	 * kernel control needs it
	 */
	error = sooptcopyin(sopt, data,				// (b) sooptcopyin() is
		sopt->sopt_valsize, sopt->sopt_valsize);	//     called to fill the
}								//     buffer; the return
len = sopt->sopt_valsize;					//     value is ignored.
socket_unlock(so, 0);
error = (*kctl->getopt)(kctl->kctlref, kcb->unit,		// (c) The getsockopt()
		kcb->userdata, sopt->sopt_name,			//     implementation is
			data, &len);				//     called to process
if (data != NULL && len > sopt->sopt_valsize)			//     the buffer.
	panic_plain("ctl_ctloutput: ctl %s returned "
		"len (%lu) > sopt_valsize (%lu)\n",
			kcb->kctl->name, len,
			sopt->sopt_valsize);
socket_lock(so, 0);
if (error == 0) {
	if (data != NULL)
		error = sooptcopyout(sopt, data, len);		// (d) If (c) succeeded,
	else							//     then the data buffer
		sopt->sopt_valsize = len;			//     is copied out to
}								//     userspace.

Dieser Code führt Folgendes aus:

  1. Es wird ein Kernel-Heap-Puffer für den Datenparameter von getsockopt allokiert, ohne das Flag M_ZERO zu setzen, um die allokierten Bytes zu nullen.
  2. Es kopiert die getsockopt-Daten aus dem Benutzerbereich mittels sooptcopyin in den gerade allokierten Datenpuffer. Diese Kopieraktion soll die allokierten Daten vollständig überschreiben, weshalb das Flag M_ZERO nicht benötigt wurde. Allerdings wird der Rückgabewert von sooptcopyin nicht überprüft, was bedeutet, dass das Kopieren fehlschlagen kann und nicht initialisierte Daten im Puffer zurückbleiben. Das Kopieren könnte fehlschlagen, wenn das Programm beispielsweise eine nicht abgebildete Adresse an getsockopt übergibt.
  3. Der Code ruft dann die tatsächliche getsockopt-Implementierung für diesen Kernel-Steuerungssocket auf. Diese Implementierung sollte den Eingabepuffer verarbeiten, möglicherweise modifizieren und verkürzen, und einen Ergebnis-Code zurückgeben. Die Implementierung darf jedoch davon ausgehen, dass der bereitgestellte Puffer bereits initialisiert ist (da er theoretisch aus dem Benutzerbereich stammt), und daher ändern mehrere Implementierungen den Puffer gar nicht. Die NECP-Funktion necp_ctl_getopt gibt beispielsweise einfach 0 zurück, ohne den Datenpuffer zu verarbeiten.

Indem wir also eine nicht abgebildete Datenadresse an getsockopt übergeben, können wir einen Heap-Puffer kontrollierter Größe allokieren, verhindern, dass der Inhalt dieses Puffers initialisiert wird, und dann einen Aufruf von sooptcopyout erreichen, der versucht, diesen Puffer zurück an die nicht abgebildete Adresse zu schreiben. Damit das Kopieren gelingt, müssen wir diese Adresse zwischen den Aufrufen von sooptcopyin und sooptcopyout neu abbilden. Wenn uns das gelingt, geben wir nicht initialisierte Kernel-Heap-Daten an den Benutzerbereich preis.

Es stellt sich heraus, dass dieses Rennen recht einfach zu gewinnen ist. Bei Tests auf meinem MacBook Pro von 2015 lag die durchschnittliche Anzahl der Versuche, das Rennen zu gewinnen, nie über 600, und der Median lag nie über 5. Unter iOS 10.1.1 auf einem iPhone 7 war das Rennen sogar noch einfacher zu gewinnen, typischerweise mit nicht mehr als 2 Versuchen. (Diese Tests wurden mit deaktiviertem DEBUG durchgeführt, da die printfs den Exploit drastisch verlangsamen.)

Verwendung

Zum Bauen führen Sie make aus. Siehe die Spitze der Makefile für verschiedene Bauoptionen.

Führen Sie den Exploit aus, indem Sie die Ziel-Leak-Größe in der Befehlszeile angeben:

root@kitploit:~
$ sudo ./ctl_ctloutput-leak 128
000000:  ef be ad de ef be ad de  00 00 00 00 00 00 00 00
000010:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000020:  00 00 00 00 00 00 00 00  01 00 00 00 40 80 00 00
000030:  de 28 45 00 04 00 00 00  a0 ff 4a 26 80 ff ff ff
000040:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000050:  08 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000060:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
000070:  00 00 00 00 00 00 00 00  ef be ad de ef be ad de

Zeitplan

Ich habe dieses Problem am 7. Oktober 2017 an Apple gemeldet. Es wurde die CVE‑ID CVE-2017-13868 zugewiesen. Apple behob die Probleme in macOS 10.13.2 und iOS 11.2.

Lizenz

Der ctl_ctloutput-leak-Code wird in die Public Domain entlassen. Als Höflichkeit bitte ich darum, dass Sie, falls Sie auf diesen Code verweisen oder ihn verwenden, mich als Urheber nennen.

Tool herunterladen
  • Schließlich ruft ctl_ctloutput sooptcopyout auf, um den Datenpuffer zurück in den Benutzerbereich zu kopieren, falls die eigentliche getsockopt-Implementierung keinen Fehler zurückgibt.