zurück zum Artikel

Tatort Internet: Angriff der Killervideos

Hintergrund

„Hast du den Rechner schon wieder kaputt gemacht? Er spielt das Video einfach nicht ab!“ Es war ein langer Tag und eigentlich hab ich keine Lust auf Fehlersuche. Aber wenn sie diesen Ton anschlägt, springt der Admin lieber. Und der Admin zu Hause bin nun mal ich.

Irgendwie kann ich aber nicht so recht glauben, dass die Ursache auf unserem PC zu suchen ist. Vielleicht ist ja das Video selbst kaputt. Im Quelltext der immer noch offenen Webseite findet sich ein <Object>-Tag mit einem Link zu einer SWF-Datei – also einem Video im Shockwave-Flash-Format, das sich im Web weitgehend durchgesetzt hat. Da die URL schon recht komisch aussieht, schwant mir Übles und ich lade es für weitere Untersuchungen auf meinen Rechner herunter.

Für ein SWF-File ist die Datei mit gerade mal 846 Bytes ziemlich klein. Da lässt sich nicht allzu viel Sinnvolles unterbringen. Obwohl es eine Multimedia-Datei ist, werfe ich wie üblich als erstes einen Blick mit dem Hex-Editor darauf. Gerade wenn eigentlich nur rohe, unleserliche Daten zu erwarten sind, geben eventuell trotzdem vorhandene Strings oft nützliche Hinweise.

So auch hier: Was hat ein Verweis auf die Windows-Bibliothek urlmon.dll in einer Flash-Datei zu suchen? In Kombination mit der ebenfalls sichtbaren URL und dem Dateinamen c:\6123t.exe erzählt das schon fast die ganze Geschichte – jedenfalls wenn man mal ein paar Exploits analysiert hat.

Die Müdigkeit ist verflogen, jetzt will ich es genau wissen. Von meinen letzten Experimenten mit Flash erinnere ich mich noch an die SWFTools [1], die mir damals gute Dienste geleistet haben. Sie lassen mich auch diesmal nicht im Stich. Der Befehl

swfdump -D -d -u exploit.swf 

verrät mir als erstes, dass es sich um eine Datei im Flash-Format 9 handelt – aktuell ist Version 10. Doch das hat noch nichts zu bedeuten, denn Flash ist rückwärtskompatibel und Version 9 wird immer noch häufig eingesetzt. Dahinter folgen die sogenannten Tags mit den eigentlichen Inhalten. Weiter unten sehe ich, dass Pfadangabe, URL und der Verweis auf die Bibliothek Bestandteil eines Blocks mit der Bezeichnung DEFINEBITSJPEG sind. JPEG? Wer’s glaubt!

Meine Aufmerksamkeit wecken die nächsten beiden Datenblöcke:

[056] 40 SCENEDESCRIPTION 
=> 99 b4 8e a0 08 20 20 20 20 20 20 20 20 20 20 20
=> 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
=> 20 20 20 20 20 20 20 43
[056] 12 SCENEDESCRIPTION
=> 01 00 e5 9c ba e6 99 af 20 31 00 00

Eine SCENEDESCRIPTION aus lauter 0x20-Zeichen? Der Datentyp 0x56, also dezimal 86, sagt mir nichts, deshalb ziehe ich die Beschreibung des SWF-Dateiformats [2] zu Rate, die Adobe zum Glück öffentlich verfügbar gemacht hat. Typ 86 steht für DefineSceneAndFrameLabelData und enthält „Daten für Szenen und Rahmen eines MovieClips“. Also Verwaltungsinformationen für ein Flash-Filmchen, die hauptsächlich aus 0x20-Zeichen bestehen. Ja, nee, is klar! Ich wittere eine Spur – das seh ich mir genauer an.

[pagebreak Bit-Schubser]

Bit-Schubser

Laut Spezifikation stehen die ersten zwei Bytes des Datenblocks für den RECORDHEADER. Bei der Lektüre zur Definition dieses Datentyps stehen mir die Haare zu Berge: Warum diese Knauser bei Datenbrocken, die längst nach Megabytes bemessen werden, immer noch an einzelnen Verwaltungs-Bits sparen, wird mir wohl ewig ein Rätsel bleiben. Jedenfalls enthalten die oberen 10 Bits den Tag-Typ – der sollte hier 0x56 sein – und die restlichen 6 Bit dessen Länge.

Da man auch noch die Byte-Reihenfolge der Architektur zu berücksichtigen hat, die nach Intel-Art dafür sorgt, dass das höherwertige Byte hinten steht, muss ich mir das aufzeichnen.

Demnach ergeben die RECORDHEADER der beiden Datenblöcke A8 15 und 8C 15 jeweils den von swfdump angezeigten Tag-Typ 0x56 und die Länge von 40 beziehungsweise 12. So weit, so gut. Danach kommt die Anzahl der Szenen im Datentyp EncodedU32.

Was haben sie sich denn da wieder einfallen lassen? Die Spezifikation liest sich wie aus dem letzten Jahrtausend. EncodedU32 enthält demnach einen vorzeichenlosen 32-Bit-Integer-Wert, der je nach Größe mit einer variablen Länge von ein bis fünf Bytes kodiert wird – „um Platz zu sparen“, wie die Adobe-Doku freundlicherweise erklärt.

Kein Wunder, dass die Flash-Sicherheitslücken kein Ende nehmen. Statt mit regulären Datentypen wie unsigned int zu arbeiten, versuchen sie, ein paar Bytes einzusparen. Doch Komplexität ist der natürliche Feind von Sicherheit – und das schreit geradezu nach Ärger. Man stelle sich nur mal vor, die Designer des Formats für ausführbare EXE-Dateien oder für CPU-Befehle hätten solche Datentypen eingesetzt – wir könnten uns heute vor Sicherheitslücken überhaupt nicht mehr retten.

Außerdem ist es auch noch langsam, weil bei jedem Zugriff auf einen EncodedU32-Wert statt einer einfachen Leseoperation die Dekodier-Routine ausgeführt werden muss. Vollends unverständlich wird die Bitknauserei, wenn man bedenkt, dass SWF-Dateien ohnehin noch komprimiert werden können, was deutlich effizienter Platz spart.

Doch ich rege mich schon wieder auf; zurück zum SceneCount des angeblichen iPhone-Videos. Ist das jeweils höchste Bit eines Bytes gesetzt, muss man das nächste Byte noch dazunehmen. Ein Blick auf den Hex-Dump verrät mir, dass im ersten Datenblock die vier Bytes hinter dem RECORDHEADER alle das höchste Bit gesetzt haben. Also muss ich die maximalen fünf Bytes richtig zusammenzählen. Praktischerweise liefert Adobe gleich eine Referenzimplementierung zum Auspacken der EncodedU32-Werte als C-Code mit. Bevor ich jetzt anfange, selber Bits zu schieben, jag ich die schnell durch den Compiler.

Der Test von GetEncodedU32.exe mit den Daten des kürzeren, zweiten Datenblocks ergibt einen plausiblen SceneCount von 1. Doch beim ersten Datenblock spuckt es für \xa6\xe1\x8a\xa0\x08 den Wert 0x84039a19 aus. Über 2 Milliarden Szenen? Unmöglich! Meine Nase hat mich also nicht getäuscht. Da arbeitet jemand ganz offensichtlich mit schmutzigen Tricks.

[pagebreak Null-Zeiger]

Null-Zeiger

Ich muss nicht lange suchen, um bei Mark Dowds wegweisendem Paper Leveraging the ActionScript Virtual Machine [3] zu landen, das genau dieses Problem als Beispiel anführt. Ich erinnere mich zwar noch an die Aufregung in der Security-Szene, als er diesen Exploit veröffentlichte – weiß aber nicht mehr so genau, um was es dabei ging. „Kann ich wieder an den Rechner?“ ertönt es aus dem Hintergrund. „Einen kleinen Moment noch. Ich muss das hier nur eben schnell noch zu Ende bringen. Bin fast fertig.“

Zurück zu Dowds Flash-Exploit: Adobes Flash-Implementierung verwendet SceneCount, um Speicher zu reservieren. Damit da kein Unsinn passiert, führen sie davor Checks durch. Allerdings benutzt Adobe dafür einen vorzeichenbehafteten Vergleich „größer als“. Und weil beim EncodedU32-Wert 0x84039a19 das höchste Bit – das „Vorzeichen-Bit“ – gesetzt ist, ergibt der eine negative Zahl.

Das Resultat: Der Check funktioniert nicht wie geplant und der Flash-Interpreter versucht, mit dem Wert aus SceneCount Speicher zu reservieren – was natürlich fehlschlägt. Das Programm bemerkt das jedoch nicht und benutzt den NULL-Zeiger, der den Fehler signalisieren soll, trotzdem: Bumm!

Doch ganz so einfach ist es dann doch wieder nicht. Denn lange Zeit dachte man, so ein Fehler führte lediglich zum Programmabsturz und ließe sich nicht ausnutzen, um kontrolliert eingeschleusten Code auszuführen. Mark Dowd bewies jedoch an diesem Beispiel, dass das sehr wohl möglich ist. Grob vereinfacht funktioniert das so, dass der Flash-Interpreter etwas später an die Adresse 0+SceneCount einen Wert schreibt, den der Angreifer kontrolliert. Kombiniert mit dem bösartigen ActionScript-Bytestream kann er dann einen Adresszeiger für einen Sprungbefehl mit einem passenden SceneCount-Wert so überschreiben, dass sein eingeschleuster Code aktiviert wird.

Derartige Sicherheitsprobleme werden im Rahmen von normalen Stabilitätstests kaum gefunden. Der Entwickler befindet sich in einer ähnlichen Situation wie ein Ingenieur, der die Tragfähigkeit einer Brücke berechnet und zu dem Schluss kommt, dass sie problemlos hundert Leute aushalten sollte. Er hat dabei jedoch nicht bedacht, dass auch 100 Soldaten so im Gleichschritt über die Brücke marschieren könnten, dass sie dabei die Resonanzfrequenz der Brücke treffen. Die Erschütterungen schaukeln sich dann immer weiter auf, bis die Brücke schließlich einstürzt. Solche Resonanzkatastrophen haben tatsächlich im 19. Jahrhundert in England und Frankreich zum Einsturz zweier Brücken geführt und dabei viele Opfer gefordert.

Genau genommen ist die Situation für Software-Entwickler sogar noch schwieriger: Sie müssen nämlich davon ausgehen, dass die „bösen Jungs“ absichtlich im Gleichtakt springen – und zwar so lange, bis sie die kritische Frequenz finden. Dann machen sie so lange weiter, bis sie die Brücke zum Einsturz bringen oder, um das Bild zu verlassen: bis sie mit einem speziell präparierten Filmchen den Flash-Interpreter dazu bringen, eingebetteten Code anzuspringen und auszuführen.

Apropos Code – das erinnert mich an das Tag DEFINEBITSJPEG, in dem sich der Verweis auf urlmon.dll, die URL und der komische Dateiname befinden.

[pagebreak Ein Bilderrätsel]

Bilderrätsel

Meine Theorie ist, dass der SceneCount-Exploit dafür sorgt, dass das Programm mitten in die Daten des angeblichen JPEG-Bildchens springt und den dort stehenden Code ausführt.

Du meine Güte! Die Uhr ist bereits Viertel vor zwei – aber das lässt mir jetzt keine Ruhe. Wenn das also Code ist, sollte es ein Disassembler auch als solchen interpretieren und darstellen können. Also extrahiere ich die 336 Bytes des Datenblocks in eine Datei und werfe IDA Pro [4] an. Das sollte auch mit der auf diesem PC installierten kostenlosen Version gehen.

Beim Öffnen der Datei beschwert sich IDA zunächst, dass er keinen gültigen PE-Header [5] gefunden habe. Damit fehlt ihm der dort definierte Einsprungspunkt, an dem der Programmcode beginnt. Er weiß folglich nicht, wo genau er denn anfangen soll, zu disassemblieren. Dann sag ich ihm das eben selber, setze den Cursor auf das erste Daten-Byte – das mit dem 0xAA – und drücke „C“.

Bingo – das ist der Shellcode. Denn die Chance, dass beim Disassemblieren von reinen Daten etwas so offensichtlich Sinnvolles rauskommt, ist recht gering. Am Anfang steht zwar ein bisschen Müll, aber dann kommt eine kurze Tu-NIX-Rutsche aus NOPs. Entweder musste der Exploit-Schreiber noch ein paar Bytes füllen, um auf eine bestimmte Blockgrenze zu kommen, oder er wusste doch nicht so ganz genau, wo er mit seinem umgebogenen Sprung schließlich landen würde.

Eindeutig zu erkennen ist der darauffolgende, charakteristische FS:30-Code zum Ermitteln der Basis-Adresse von kernel32.dll (siehe auch Zeig mir das Bild vom Tod [6]). Das vorangestellte XOR und der Zugriff auf ecx+30h vermeidet die Erkennung durch einfache Signaturen, die auf Verweise auf FS:30h anspringen. Dann arbeitet der Code die Export-Tabelle von kernel32.dll und urlmon.dll ab, um die relativen lokalen Adressen (RVAs) einer Reihe von Funktionen zu ermitteln, die dort abgelegt sind.

Dabei greift der Autor zu einem verbreiteten Trick: Statt die Klartextnamen der gesuchten Funktionen zu suchen, erzeugt er aus den Namen in der Export-Tabelle einen Hash-Wert und vergleicht diesen mit den hinterlegten Hash-Werten. Sind die beiden gleich, hat er eine der benötigten Funktionen gefunden.

Dieser Hash-Vergleich ist zum einen kompakter als ein Vergleich von Strings – und bei Shellcode kommt es oft auf die Länge an. Die Eigenheiten einer Sicherheitslücke beschränken nicht selten die Zahl der Bytes, die man für seinen Code zur Verfügung hat. Und zum anderen tauchen damit die verräterischen Zeichenketten nicht im Shellcode auf – das Risiko einer Entdeckung ist geringer.

Der Shellcode im Flash-Filmchen hier sucht sich damit kernel32.dll->LoadLibrary(), kernel32.dll->WinExec() und urlmon.dll->URLDownloadToFile() zusammen und geht damit dann seinen finsteren Plänen nach: Er lädt vermutlich ein Spionage- oder Bot-Netz-Programm aus dem Internet nach und installiert das auf dem Rechner seines Opfers.

Das ist aber in diesem Fall gescheitert, weil der Exploit nur bei älteren Flash-Versionen funktioniert, die noch diese Sicherheitslücke aufweisen. Wie mir der Aufruf von about:plugins in Firefox versichert, habe ich das aktuelle Flash-Plug-in installiert. Trotzdem gab es natürlich in dem angeblichen Video nichts zu sehen. Doch als ich mich umdrehe, um ihr das zu erklären, stelle ich fest, dass sie schon längst ins Bett gegangen ist. (ju [7])

Diskutieren Sie mit im Forum zu Tatort Internet [8] oder werden Sie Fan von Tatort Internet auf Facebook [9]

Über „Tatort Internet“

Die Serie "Tatort Internet" wurde ursprünglich im c't magazin [10] ab Heft 13/2010 veröffentlicht. In den Artikeln können Sie Experten über die Schulter schauen, wie sie verdächtige Dateien analysieren und Schädlingen auf die Schliche kommen. Alle in der Serie vorgestellten Malware-Samples stammen aus echten Angriffen und wurden unter anderem mit den hier vorgestellten Methoden entlarvt. Die Geschichten "drumherum" wurden durch reale Vorkommnisse inspiriert ;-)

Der Autor dieser Folge, Sergei Shevchenko, kann mehr als 10 Jahre praktische Erfahrung in der Analyse von Schädlingen vorweisen. Er ist einer der Autoren des automatisierten Bedrohungsanalysesystems ThreatExpert [11] , von dem unter anderem auch die Verhaltenserkennung Threatfire abstammt. Sergei arbeitet als „Leading Malware Analyst“ bei PC Tools in Sydney, Australien. In der nächsten Episode bekommt er es mit einem noch raffinierteren Flash-Exploit zu tun.

Übersicht aller Folgen:

  1. Alarm beim Pizzadienst [12]
  2. Zeig mir das Bild vom Tod [13]
  3. PDF mit Zeitbombe [14]
  4. Angriff der Killervideos [15]
  5. Matrjoschka in Flash [16]

URL dieses Artikels:
http://www.heise.de/-1047129

Links in diesem Artikel:
[1] http://www.swftools.org/
[2] http://download.macromedia.com/pub/flash/licensing/file_format_specification_v9.pdf
[3] http://documents.iss.net/whitepapers/IBM_X-Force_WP_final.pdf
[4] http://www.hex-rays.com/idapro/idadown.htm
[5] http://de.wikipedia.org/wiki/Portable_Executable
[6] https://www.heise.de/security/artikel/Tatort-Internet-Zeig-mir-das-Bild-vom-Tod-1028204.html
[7] mailto:ju@heisec.de?subject=Tatort%20Internet
[8] http://www.heise.de/security/foren/S-Tatort-Internet/forum-181148/list/
[9] http://www.facebook.com/pages/Tatort-Internet/116558001722926
[10] http://www.heise.de/ct/
[11] http://www.threatexpert.com/
[12] https://www.heise.de/security/artikel/Tatort-Internet-Alarm-beim-Pizzadienst-1017983.html
[13] https://www.heise.de/security/artikel/Tatort-Internet-Zeig-mir-das-Bild-vom-Tod-1028204.html
[14] https://www.heise.de/security/artikel/Tatort-Internet-PDF-mit-Zeitbombe-1036564.html
[15] https://www.heise.de/security/artikel/Tatort-Internet-Angriff-der-Killervideos-1047129.html
[16] https://www.heise.de/security/artikel/Tatort-Internet-Matrjoschka-in-Flash-1052848.html