
Technische Analyse und Exploit-Demonstration von CVE-2022-32898, einer Kernel-Speicherkorruptions-Schwachstelle im Apple Neural Engine Treiber, mit detaillierten Reverse-Engineering- und Exploitation-Techniken für den iOS-Kernel.
Ich teile zwei weitere iOS-Kernel-Schwachstellen, die aus dem standardmäßigen App-Sandbox erreichbar sind und kein Öffnen eines UserClient erfordern:

+16 Kernel-Bugs, die ich an Apple gemeldet habe, wurden in iOS 16/16.1 behoben. Ich werde nächsten Monat auf der #POC2022 einen Vortrag darüber halten, wie ich einige Bugs zu Kernel r/w verknüpft habe, und der Kernel-Exploit für iOS 15 wird zusammen mit einigen anderen hochwirksamen Schwachstellen nach der Konferenz veröffentlicht.
Mein bisheriges Lieblingsfeature von IDA 8.0: künstliche Objective-C Methodenimporte

In iOS 15.5 Beta 3 entfernte Apple IOMallocAligned(KHEAP_DEFAULT,...) aus IOSharedDataQueue/IODataQueue::initWithCapacity() (verwendet jetzt kernel_memory_allocate() mit dem KMA_DATA-Flag). Es war eine elegante Technik, um den Standard-Kernel-Heap mit benutzergesteuerten Daten zu präparieren. RIP

Während ich den Prozess, mit dem die Apple Neural Engine ein Modell auf Kernel-Ebene lädt, rückentwickelte, identifizierte ich zwei interessante Speicherverfälschungsschwachstellen im Code, der für die Verarbeitung der neuronalen Netzwerkmerkmale in H11ANEIn::ANE_ProgramCreate_gated() verantwortlich ist. Diese Art von Schwachstellen sind meiner Meinung nach leicht zu finden, wenn man den Kernel-Treiber manuell auditiert, aber fast unmöglich mit Fuzzern zu entdecken, es sei denn, man baut etwas unglaublich Raffiniertes.
Die Funktionen ZinComputeProgramGetNamesFromMultiPlaneLinear() und ZinComputeProgramGetNamesFromMultiPlaneTiledCompressed() sind beide für das Parsen der Eingabe und Ausgabe der Prozedur verantwortlich, genauer gesagt, des LC_THREAD-Befehls mit Thread-Flavour 2 (ane_bind_state), dessen binding_type_info-Wert 4 und 5 ist.
Soweit ich das beurteilen kann, bedeutet binding_type_info = 4, dass die Eingabe einer Prozedur mehr als eine Ebene hat, und binding_type_info = 5 bedeutet, dass die Eingabe nicht nur mehr als eine Ebene hat, sondern auch komprimiert ist.
Die Funktion ZinComputeProgramGetNamesFromMultiPlaneLinear() benötigt beispielsweise 5 Argumente: einen Load-Command-Zeiger, einen Thread-Binding-Zeiger und drei zusätzliche Ausgabeargumente. Das letzte Ausgabeargument planes ist ein Array, das Ebenen oder Kernel-Zeiger aufnimmt, deren Inhalte vom Benutzer gesteuert werden, und das letzte Argument planeCount gibt an, wie viele Ebenen (oder Kernel-Zeiger) von der model.hwx-Datei in planes kopiert wurden. Nachfolgend die Funktionsdefinition:

Aufgrund des Fehlens einer Validierung, wie viele Ebenen ein Modell liefern kann, könnten Kernel-Zeiger außerhalb der Grenzen des planes-Arrays geschrieben werden, was potenziell zu vielen interessanten Speicherverfälschungsszenarien führen könnte.
Das planes-Array ist eine Stack-Variable in H11ANEIn::ANE_ProgramCreate_gated(), und durch Überlauf dieser Variable (die mehrere Ebenen bis zu 4 Elementen aufnehmen soll) mit mehr als 4 Ebenen könnten auch andere Stack-Variablen beschädigt werden, was zu weiteren Problemen wie Typverwirrung führen könnte, da die überschreibenden Kernel-Zeiger vollständig unter Benutzerkontrolle stehen.
Offensichtlich würde ein Überlauf des planes-Arrays mit zu vielen Einträgen wahrscheinlich das Stack-Cookie sowie den gespeicherten alten Stack-Frame-Zeiger überschreiben, was zu einem Kernel-Panic führt. Glücklicherweise liegt die Gesamtzahl der Ebenen vollständig in der Kontrolle des gegebenen Modells, sodass wir mehrere Stack-Variablen beschädigen könnten, ohne diese sensiblen Bereiche des Stacks zu beeinträchtigen.
Ein weiteres interessantes Szenario, wie unten im Bild dargestellt, ist es möglich, zwei Heap-Objekte zu überlaufen: H11ANEProgramBindingInfo (in Zeile 528) und H11ANEProgramCreateArgsStructOutput (in Zeile 533).

struct H11ANEProgramBindingInfo
{
struct {
uint32_t field_0;
char names[8][512];
uint32_t field_1004;
char *procedure_name;
} inputs[255], outputs[255];
};
Die Strukturdefinition von H11ANEProgramCreateArgsStructOutput ist oben gezeigt, und ihre Verfälschung könnte zu den folgenden Abstürzen führen:
"panicString" : "panic(cpu 4 caller 0xfffffe00112e6184): Kernel data abort. at pc 0xfffffe0010a8a48c, lr 0x03effe0011b1b47c (saved state: 0xfffffe6089dca980)
x0: 0x1122334411223344 x1: 0xfffffe3000ecff20 x2: 0x0000000000000040 x3: 0x0000000000000000
x4: 0x0000000000000000 x5: 0x0000000000000000 x6: 0x00000000000000e8 x7: 0x0000000000000830
x8: 0xfffffe608949c000 x9: 0xfffffe24cec0d1b0 x10: 0xfffffe24cd7d4010 x11: 0xfffffe1667fa93e0
x12: 0x0000000000000001 x13: 0x0000000000000858 x14: 0xfffffe3000ed0760 x15: 0x00292a20736d6172
x16: 0x5bd9fe0010a8a470 x17: 0xfffffe0013ad55d8 x18: 0x0000000000000000 x19: 0x0000000000000000
x20: 0x0000000000000001 x21: 0xfffffe1b33ee3860 x22: 0xfffffe299a621a00 x23: 0xfffffe2999c72208
x24: 0xfffffe3000ec0000 x25: 0x00000000e00002d1 x26: 0xfffffe608949c000 x27: 0xfffffe60895a2054
x28: 0xfffffe6089dcb850 fp: 0xfffffe6089dcacd0 lr: 0x03effe0011b1b47c sp: 0xfffffe6089dcacd0
pc: 0xfffffe0010a8a48c cpsr: 0x00401208 esr: 0x96000004 far: 0x1122334411223344
Was diese Schwachstellen interessant macht, ist, dass sie keine direkte Interaktion mit dem Kernel erfordern, mit anderen Worten, es ist nicht nötig, eine UserClient-Verbindung zu öffnen. Sie müssen lediglich ein bösartiges Modell kompilieren (oder erstellen) und aned in Ihrem Namen laden lassen.
Wie Sie vielleicht wissen, muss ein Modell, um über aned geladen zu werden, vom Systemdienst ANECompilerService kompiliert oder von Apple signiert sein. Mit anderen Worten, die App muss ein .mlmodelc-Verzeichnis an aned bereitstellen, das dann ANECompilerService auffordert, es mit zwei Frameworks namens Espresso und ANECompiler in model.hwx zu kompilieren. Wenn Sie nicht wissen, wovon ich spreche, werfen Sie gerne einen Blick auf die #POC2022-Folien hier, wo ich einen grundlegenden Überblick über die Funktionsweise von aned gegeben habe. Darüber hinaus erhalten Sie weitere Details zum Kompilierungsprozess in Wish Wus exzellentem BlackHat-Vortrag zu seiner Forschung über ANE sowie in seinem großartigen Tool, das genau nachahmt, was ANECompilerService tut.