Bedrohungsanalyse

    Mimecast entdeckt Use-After-Free Zero-Day-Schwachstelle in Adobe Reader

    Adobe Acrobat Reader ist ein beliebtes Ziel für Angriffsversuche. Mimecast Threat Research Labs hat eine neue Zero-Day-Schwachstelle entdeckt, die sich auf Anmerkungen und Kommentare in der Anwendung auswirkt.

    by Gil Mansharov
    92BLOG_1.jpg

    Wichtige Punkte

    • Die Mimecast Threat Research Labs haben eine Use-After-Free-Schwachstelle in der neuesten Version von Adobe Acrobat Reader entdeckt. Die Schwachstelle liegt in der Implementierung und Verwendung von Anmerkungen in PDF-Dokumenten.
    • Die Schwachstelle ermöglicht zwar keine Codeausführung, aber wenn sie von Angreifern ausgenutzt wird, könnte sie in Kombination mit zusätzlichen Techniken dazu beitragen, die Kontrolle über betroffene Systeme zu erlangen.
    • Zum Zeitpunkt der Erstellung dieses Berichts waren noch keine Unternehmen von der Sicherheitslücke betroffen.  

    Adobe Acrobat Reader ist einer der am weitesten verbreiteten PDF-Reader, und als solcher bleibt er ein Ziel für potenzielle Angriffsversuche. 

    In diesem Artikel wird beschrieben, wie das Team von Mimecast Threat Research Labs und ich mit der Beseitigung einer Zero-Day-Schwachstelle begonnen haben, die bei einer Untersuchung zur Reproduktion von 1-Day-Schwachstellen in Adobe Acrobat Reader entdeckt wurde. 

    Anatomie der PDF-Anmerkungen in Adobe Reader

    Die meisten modernen Dokumentenleser, einschließlich Adobe Acrobat Reader und Microsoft 365, verfügen über Funktionen für Anmerkungen und Kommentare.

    In Adobe Acrobat Reader ist die Funktionalität für Annotationen in einer DLL-Datei mit dem Namen Annots.api implementiert.

    Im Zuge unserer laufenden Forschung haben wir beschlossen, die Interaktion mit der Anmerkungsfunktion mit JavaScript für PDF zu versuchen. Glücklicherweise dokumentiert Adobe die API für Acrobat's Javascript Engine (basierend auf der SpiderMonkey Engine) und weist darauf hin, dass die folgenden Methoden relevant sein könnten:

    Methode

    Beschreibung

    Doc.addAnnot

    Erstellen Sie eine Anmerkung im Dokument

    Doc.addField

    Ein Feld im Dokument erstellen

    Feld.setAction

    Eine Aktion für einen bestimmten Auslöser für das Feld festlegen

    Annotation.destroy

    Zerstören Sie die Anmerkung und entfernen Sie sie von der Seite

    Auslösen eines Absturzes

    Beim Testen von Kommentaren mit einer veralteten Version von Adobe haben wir ein Skript getestet, das einen Absturz für eine bestehende 1-Day-Schwachstelle auslösen sollte, und beim Debuggen kam es zu einem unerwarteten Absturz. Das grundlegende Skript hatte die folgende Logik.

    Wir haben ein Anmerkungsobjekt erstellt:

    var annot = this.addAnnot({})

    Dann fügten Sie dem Anmerkungsobjekt ein Textfeld hinzu:

    var f = annot.addField("some_name", {"cFieldType":"text"}, etwas, etwas)

    Schließlich wurde ein Auslöser festgelegt: Das Anmerkungsobjekt würde zerstört werden, wenn das Textfeld verschwimmt.

    f.setAction("OnBlur", "annot.destroy()")

    Beim programmatischen Zugriff auf das Anmerkungsobjekt wurde kein ungewöhnliches Verhalten dokumentiert.

    Das Anklicken des Textfeldes zeigte jedoch, dass Adobe Acrobat Reader irgendwie auf das Anmerkungsobjekt zugreifen konnte, wodurch ein Use-After-Free-Fehler ausgelöst wurde und die Anwendung abstürzte.

    Wir haben einen klassischen Use-After-Free-Fehler festgestellt:

    • Frei: Das Anmerkungsobjekt wird bei einem OnBlur Ereignis auf dem Textfeld freigegeben.

    f.setAction("OnBlur", "annot.destroy()")

    • Verwendung: Das Klicken auf die Anmerkung nach dem Klicken auf das Textfeld löste das Ereignis OnBlur aus und gab das UI-Objekt der Anmerkung frei, aber gleichzeitig wurde auf das UI-Objekt der Anmerkung durch Klicken darauf zugegriffen.

    Technische Analyse

    Um die Ursache des Absturzes (Use-After-Free) zu überprüfen, haben wir Acrobat Reader mit WinDBG debuggt und GFlags aktiviert, um den Fehler zu beheben. Um die Fehlersuche zu erleichtern, waren wir gezwungen, den geschützten Modus in Adobe Acrobat Reader zu deaktivieren.

    Beim Debuggen der POC-Datei zum Auslösen der Schwachstelle kam es erwartungsgemäß zu einer Zugriffsverletzungsausnahme aufgrund des Zugriffs auf zuvor freigegebenen Speicher.

    Mit einem einfachen Heap-Spray in unserem Javascript-Code ist es uns auch gelungen, die Kontrolle über EIP zu erlangen, indem wir einen Funktionszeiger in einem der internen Objekte von Acrobat Reader beschädigt haben.

    In unserem Javascript-Code haben wir den Heap mit 0x0c0d Bytes besprüht und damit den Wert des ESI-Registers verändert.

    Außerdem zeigte das EIP-Register auf die Adresse 0x0, und wir konnten sehen, dass die Ursache dafür in einem Aufruf einer Funktion an ESI+0x20 lag.

    Der Wert an der Adresse ESI+0x20 war 0x0, was bedeutete, dass der Befehlszeiger auf diesen Wert gesetzt werden würde, und da wir die Kontrolle über ESI hatten, konnten wir auch die aufzurufende Funktionsadresse kontrollieren.

    Die Kontrolle über EIP zu erlangen, reichte für einen erfolgreichen Angriff nicht aus, da das Team in solchen Szenarien zusätzliche Schutzmaßnahmen wie ASLR, DEP und die Sandbox von Acrobat Reader umgehen musste.

    Tieferes Eintauchen

    Bei der Analyse und der potenziellen Ausnutzung von Heap-Schwachstellen ist es wichtig, die Interna des Heaps zu verstehen und zu wissen, wie die Objekte, die wir beschädigen können, strukturiert sind.

    Die internen Objekte von Acrobat Reader zu verstehen, ist nicht so einfach, da das Programm keine veröffentlichten Symbole hat (im Gegensatz zu Microsoft Office), und es erfordert zusätzliches Reverse Engineering.

    Nach einer ersten Analyse der Schwachstelle und der Ursache der Schwachstelle beschlossen wir, tiefer zu gehen.

    Für diese Aufgabe haben wir uns zwei Module angesehen, die wir für diese Schwachstelle als besonders relevant erachteten: Annots.api und AcroRd32.dll.

    Um die Analyse zu erleichtern, haben wir WinDBG Preview verwendet und unsere POC-Datei mit Gflags und Time Travel Debugging ausgeführt.

    Auf diese Weise können wir eine Trace-Datei der Ausführung aufzeichnen und sie mit dem Debugger vorwärts und rückwärts abspielen.

    Wir setzten einen Haltepunkt beim ersten Zugriff auf das beschädigte Objekt, und wenn wir den Haltepunkt erreichten, wollten wir Details über den beschädigten Heap-Chunk sehen.

    Die folgende Abbildung zeigt, wie wir sehen konnten, dass der Aufruf der Funktion 0x710e7b70 den Inhalt des Puffers, auf den EDI zeigt, verändert hat, und wie wir erkennen konnten, dass dies unser beschädigter Puffer war.

    Bei der Untersuchung des Heap-Chunks, auf den EDI+0x7A zeigt, konnten wir sehen, dass der Chunk-Eintrag bei 0xb7c8010 lag.

    Nun wollten wir einen Hardware-Haltepunkt an dieser Adresse setzen, die Ausführung zurückspulen (mit Time Travel Debugging) und alle Zugriffe auf diese Adresse überprüfen, einschließlich der Freigabe und Zuweisung von Speicher an dieser Adresse.

    Abbildung 1: Erster Zugriff auf das beschädigte Objekt durch unseren POC.

    Nachdem wir die Ausführung zurückgespult und die Trace-Datei mit den von uns gesetzten Haltepunkten debuggt hatten, untersuchten wir alle Zugriffe auf die Adresse des beschädigten Heap-Chunk-Eintrags.

    Wir wollten besser verstehen, welcher freie Heap-Chunk verwendet wird, welches Objekt er darstellt, wie groß das Objekt ist und (vorzugsweise) welche Eigenschaften es hat.

    Nachdem wir die Zugriffe auf den freigegebenen Heap-Chunk untersucht und diejenigen herausgefiltert hatten, die sich auf Speicherzuweisungen/-freigaben bezogen, konnten wir die Zuweisungsgröße des Chunks durch den Benutzer im Aufruf von RtlAllocateHeap mit dem Argument 0x2D0 als Größe sehen.

    An diesem Punkt wussten wir also, dass das Programm 0x2D0 Bytes für das beschädigte Objekt zugewiesen hatte, wenn wir die zusätzlichen 0x18 Bytes ignorierten, die vom Heap-Manager zugewiesen wurden.

    Zur Erinnerung: Das Objekt wurde mit Hilfe des folgenden Javascript-Codes zugewiesen:

    var annot = this.addAnnot({})

    Da wir nun den Aufrufstapel der Zuweisung hatten, konnten wir sehen, wo das Objekt von Acrobat Reader konstruiert wurde.

    Wenn wir einen Blick auf den Code an der Adresse AcroRd32!AIDE::PixelPartInfo::operator=+0x4e697f werfen, können wir den zugewiesenen Puffer und die Puffergröße sehen, und wir können auch einen Aufruf zu einer Funktion (create_CommentContainerView_object_internal) sehen, die das Objekt selbst mit Anfangswerten konstruiert. 

    Sobald wir wussten, wie das Objekt konstruiert wurde, konnten wir sehen, dass wir es mit der Aktion, die wir in der OnBlur Ereignis mit dem folgenden Javascript-Code festgelegt freigegeben:

    f.setAction("OnBlur", "annot.destroy()")

    Durch Überprüfen des Aufrufstapels während des Freigabevorgangs des Objekts konnten wir auch sehen, dass es durch den Aufruf der destroy() API in der Annots.api Bibliothek freigegeben wurde: 

    Im Aufrufstapel konnten wir sehen, dass die Ausführung von Code an der Adresse Annots!PlugInMain+0xabadf vom EScript Modul (Acrobat Reader Javascript Engine) aufgerufen wurde.

    Anhand der Zeichenkette "destroy" " in der Funktion konnten wir feststellen, dass der Chunk durch den Aufruf der API destroy() freigegeben wurde.

    Nun, da wir wussten, dass das Objekt freigegeben worden war, konnten wir sehen, dass es uns gelungen war, die Kontrolle über das freie Objekt zu übernehmen, indem wir generische Javascript-Funktionen für Speicherzuweisungen verwendeten (wie die Erstellung von ArrayBuffer und DataView Objekten): 

    Wir konnten auch sehen, dass sich der Aufrufstapel in diesem Szenario von dem unterscheidet, den wir im this.addAnnot API-Aufruf gesehen haben, und in diesem Aufrufstapel kam die Zuweisung vom EScript-Modul von Acrobat Reader (der Javascript-Engine) und nicht wie zuvor vom Annots-Modul.

    Um über die Schwachstelle Code ausführen zu können, mussten wir lediglich Sicherheitsmaßnahmen wie DEP, ASLR, Acrobat Sandbox und andere umgehen.

    Um diese Abhilfemaßnahmen zu umgehen, mussten in den meisten Fällen weitere Schwachstellen gefunden und miteinander verknüpft werden.

    Zeitplan für die Offenlegung von CVE-2022-38437

    Die Sicherheitslücke wurde Adobe über den HackerOne-Dienst gemeldet.

    • 24. August - Die Sicherheitslücke wurde Adobe über den HackerOne-Dienst gemeldet
    • 25. August - HackerOne-Analysten haben die Sicherheitslücke erfolgreich reproduziert und an Adobe weitergeleitet
    • 14. Oktober - Adobe hat die Sicherheitslücke gepatcht und ihr den Code CVE-2022-38437 zugewiesen

    Die Quintessenz

    In dieser Untersuchung war es unser Ziel, 1-Day-Schwachstellen in Acrobat Reader zu reproduzieren, um ihn besser zu verstehen und potenzielle Fuzzing-Ziele zu finden. Letztendlich fanden wir jedoch eine Zero-Day-Schwachstelle, die wir mit Fuzzing wahrscheinlich nicht erreichen könnten, da sie eine spezielle Benutzerinteraktion mit der GUI von Acrobat Reader in Kombination mit Javascript erfordert. Diese Schwachstelle könnte Angreifern helfen, die Kontrolle über betroffene Systeme zu erlangen. Wir hoffen, dass die Entdeckung und Weitergabe unserer Forschungsergebnisse zu dieser Schwachstelle dazu beitragen wird, dies zu verhindern.

     

    Abonnieren Sie Cyber Resilience Insights für weitere Artikel wie diesen

    Erhalten Sie die neuesten Nachrichten und Analysen aus der Cybersicherheitsbranche direkt in Ihren Posteingang

    Anmeldung erfolgreich

    Vielen Dank, dass Sie sich für den Erhalt von Updates aus unserem Blog angemeldet haben

    Wir bleiben in Kontakt!

    Zurück zum Anfang