Verstecken von Informationen

Ich bin gerade durch Zufall auf einen Artikel gestoßen indem angeblich beschrieben wird, wie man Daten in Bildern verstecken kann. Der Titel mach neugierig: “Datenschutz-Paranoia: So verstecken Sie geheime Daten in Fotos”. Der Titel ist aber irreführend. Die Daten werden nicht in einem Foto versteckt, sondern an ein Foto angehängt. Der Ratschlag ist nämlich einfach ein Foto und eine Datei mit dem Befehl “cat” (unter Linux und OS X) zu verbinden und das Ergebnis wieder als Foto ausgeben zu lassen. Verstecken würde ich das also nicht nennen. Aber naja.

Hier mal ein Beispiel. Wir nehmen folgende Bilddatei (test.jpg):

Und eine Textdatei mit dem Namen text.txt und einem kurzen Text darin. Aus dieser wird eine zip-Datei erzeugt (text.zip; wichtig sonst kann man das Bild nicht öffnen). Jetzt noch der Befehl “cat test.jpg test.zip > neu.jpg” (wichtig ist die Reihenfolge der Eingabedateien, als erste muss zwingend die Bilddatei stehen). Als Resultat erhalten wird das Bild (neu.jpg):

Es sieht erstmal nicht anders aus als das ursprüngliche Bild. Schauen wir uns aber seine Größe an, stellen wir fest, dass es jetzt 1461 Byte groß ist, das ursprüngliche Bild aber nur 1283 Bytes. Wenn wir das Bild mit einem Texteditor öffnen und uns den Inhalt anschauen, dann sehen wir (der interessante Teil ist in der viert-letzten Zeile):

ÿØÿà JFIF  = =  ÿþ ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 82
ÿÛ C #!$.M2.**.^CG8Mobusmblj{Š±–{ƒ§„jlšÑœ§¶¼ÆÈÆw”Ùè×Àæ±ÂƾÿÛ C!##.(.Z22Z¾l¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾¾ÿ  : W ÿÄ                ÿÄ              ÿÚ    yHe`gRnÕ&2<€µ¦T†T¸ìË4È‹„€ Ž†X†»KR9    ®M˜`T»a)5†qÑ’€-h¡R
DZÒ@ˆd£    µYÿÄ               !01AÿÚ  XA"œÔ(Ùã…)J5^¦‚FÜ'
º}v¥B̤áüÇ.}4f¯¶+×Ú#Tk‰¢'OÞŒ\>ÿÄ               `ÿÚ ?&?ÿÄ             0@ !ÿÚ ?Ë—¦f|Ìíû3<ÿÄ              !@0ÿÚ  ?LPL-Ýã?ÿÄ             1Aq!a Q‘¡ÿÚ  ?!CÉ–$b}QD„©ð    ¡´CfÊöiWAó9nbL¶Ä«!‰‹Ù¸Nèý!QÅĬ%E¨j Œ®Ä<–{/4ÈÂÉC鏵1’.Y&¡É?    §$t†û£žÔ·P—HÙÆN¸0¡ÉÿÚ      úbíµÀW„Û “«Û¿·'/Zm7,Òùy~[Ý6!‰ŸßÿÄ              01ÿÚ ?€ñ4è×8®Ø˨iÛ5ŒqäÂ…CÚþKŸÿÄ            !A 01aqÿÚ ?¥¥(ëzíC‚D¹ŸÔ¢d‡V$άŸAª_2wéjí„s øA³ùò¨&,±¼ç‡P¿Ïq|ÿÄ "          !1AQq‘a¡Á±ÿÚ  ?
¬¾kô¥    :È—1TTî7ໂè‹œ?¾ÖíKâ+&±¸nâBl[ÑijNIAÛ¹U@]˜rÙ-jèª:±_L°¨_©kg²^¥ÉK°…©ÉëÔ³5£Ñ;Ük‹Œ®8pöNÊs×ÑÚ5eãüä
µæZý™gbªº…êç€WGˆaÓ°ØKúÊÙŹ
ÏÓ<¨|£wªNß0Ã5‹°cÄ~&GQáǹA«„”^Ÿ˜»
ûÌ!ð•æښѠõ(€ù…i³¶ã÷ð–ÚÞ¡w~¡ËûN¥qÔ £šŽ4,õ<šï.ˆGmv¡ÃÜþÓ‡æs}N_Øék6b³'ÿÙPK
     ÜjvJK~         test.txtDies ist ein geheimer Text!
PK? 
     ÜjvJK~       $               test.txt
         €ù£Ò€¾) £ÒÞUtC£ÒPK      Z   B

Am Anfang steht die Bilddatei und am Ende wurde einfach die zip-Datei angehängt, inklusive des im Klartext lesbaren Geheimnisses und des Dateinamens. Also verstecken sieht anders aus! Im Artikel fehlt auch jeglicher Hinweis auf diese einfache Möglichkeit an die Infos zu kommen. Wobei ich natürlich zugeben muss, dass die Anleitung nur auf einer Apple-Fan-Seite erschienen ist…

Der Weg der in der Anleitung eigentlich vorgesehen ist um an den geheimen Text zu kommen, ist die Bilddatei neu.jpg in neu.zip umzubenennen und dann als zip-Datei zu öffnen. Dies funktioniert allerdings nur unter Linux und OS X, aber nicht unter Windows. Das die Anleitung für Windows unbrauchbar ist, ist auch das einzig Gute an der Anleitung, so kommen wenigstens nicht so viele Leute auf die Idee das umzusetzen.

Man könnte natürlich die Ausgangsdatei verschlüsseln, damit nichts mehr in Klartext angezeigt wird. Man könnte auch das 7z-Format nehmen und den Inhalt sowie die Dateiliste verschlüsseln lassen. Es wäre aber immer noch relativ einfach zu erkennen, dass hier Dateien versteckt sind, da hinter dem eigentlichen Bild noch Daten hängen.

Wie könnte man jetzt automatisiert eine zip-Datei erkennen, die an eine jpg-Datei angehängt ist? Zunächst einmal muss man wissen, dass jede jpg-Datei mit den Bytes “\xFF\xD8” anfängt und mit den Bytes “\xFF\xD9” aufhört. Die Signatur eines zip-Files ist immer “\x50\x4b\x03\x04”. Da mit cat einfach die beiden Dateien hintereinander gehängt werden, müssen wir nur nach dieser Folge im Bild suchen. Dies funktioniert natürlich nur mit jpg- und zip-Dateien. Werden andere Dateiarten verwendet, müssen die Bytes angepasst werden. In Python würde dies folgendermaßen aussehen (Quick&Dirty-Variante):

with open('neu.jpg', 'rb') as f:
    h = f.read()
    for i, b in enumerate(h):
        if (b == 255 and h[i+1] == 217 and
            h[i+2] == 80 and h[i+3] == 75 and h[i+4] == 3 and h[i+5] == 4):
            print("found")
            print(i+2)
            with open("secret.zip", "wb") as zf:
                zf.write(h[i+2:])
            break

Dieses Vorgehen könnte man auch anwenden um einen Test zu schreiben, der nicht auf eine angehängt zip-Datei angewiesen ist. Dazu muss man aber beachten, dass die Bytes “\xFF\xD9” in einer jpg-Datei mehrfach vorkommen können. Man muss also bis an die richtige Stelle iterieren. In dem Code-Beispiel fehlt natürlich auch noch ein prinzipieller Test ob überhaupt eine jpg-Datei vorliegt (z.B. mit “imghdr.what(‘neu.jpg’)”), die Erweiterung auf andere Formate sowie die Verwendung von Informationen im Header der jpg-Datei zum Feststellen von “Anhängen”. Dies ist hier aber nicht so wichtig. Mir ging es viel mehr darum zu zeigen, dass ein einfach anhängen von Daten sehr einfach erkannt werden kann.

Steganographie

Ein besserer Weg um Daten in einem Bild zu verstecken ist die Steganographie. Dabei werden die Farbwerte einzelner Pixel des Bildes für das Verstecken von Informationen verwendet. Diese Veränderungen sind für den menschlicher Betrachter nicht zu erkennen, aber oftmals mit statistischen oder anderen Verfahren nachzuweisen. Dazu aber später mehr. Unter Linux sind mehrere Tools zur Steganographie in den Paketquellen enthalten. Ich verwendet steghide, es gibt aber noch eine ganze Reihe weiterer Programme.

LSB-Verfahren

Ein relativ einfaches Verfahren ist das LSB-Verfahren. Die Idee dahinter ist, die Nachricht im jeweils letzten Bit der Farbwerte eines Pixel zu verstecken. Dabei kann ausgewählt werden ob die Nachricht nur in einem Farbwert, z.B. dem Grünwert, oder in allen drei Farbwerten versteckt werden soll. An den Anfang der Nachricht hängt man noch die Länge der Nachricht. Dies wird für das Auslesen der Nachricht benötigt. Alternativ könnte man auch ein Zeichen festlegen, welches das Ende  der Nachricht anzeigt. Beim Einbetten eines Nachrichtenbits, wird das letzte Bit des Farbwertes mit dem entsprechenden Nachrichtenbit überschrieben. Beim Auslesen müssen somit einfach die letzten Bits der Farbwerte ausgelesen und aus ihnen die Nachricht wiederhergestellt werden.

Es ist auch möglich im LSB-Verfahren einen Passwortschutz einzubauen. Dabei wird aus dem Passwort mit Hilfe der ASCII-Tabelle eine Zahl berechnet und diese als Startwert für einen nichtlinearen Konguenzgenerator verwendet. Die so entstehenden Pseudozufallszahlen geben die Pixel im Bild an, die verändert werden sollen. Dabei muss darauf geachtet werden, dass ein Pixel nicht zweimal verändert wird. Es muss auch beachtet werden, dass die Nachricht hier nicht verschlüsselt wird, sondern nur scheinbar zufällig im Bild verteilt wird. Dies unregelmäßige Verteilung macht das LSB-Verfahren weniger anfällig für visuelle und statistische Angriffe.

Zusätzlich zu der normalen Repräsentation der Nachricht in Bitdarstellung, kann auch die Huffman-Kodierung ausgewählt werden. Hier werden zusätzlich zur Nachricht und der Länge, noch Informationen über die absoluten Häufigkeiten der vorkommenden Buchstaben gespeichert. Diese werden benötigt um den Huffmancode zur Dekodierung der Nachricht zu erzeugen. Die Länge und die Verteilung der Buchstaben werden weiterhin in einem 8-Bit-Code gespeichert. Die Human-Kodierung führt somit erst bei längeren Texten zu einer Speicherplatzersparnis. Mit dem LSB-Verfahren können auch Binärdateien eingebettet werden. Dafür wird zunächst die Binärdatei in die Bitdarstellung umgewandelt und anschließend eingebettet.

Mit bloßem Auge ist keine Unterschied zwischen Originalbild und dem Bild mit einer eingebetteten Nachricht zu erkennen (erstes Bild ist das Originalbild, das zweite Bild enthält eine Botschaft).

Ein visueller Angriff

Beim Angriff auf png- und bmp-Bilder werden die Farbwerte der einzelnen Pixel je nach Parität verändert und so die entstandene Struktur einer eventuellen Einbettung sichtbar. Auch hier können entweder alle drei oder nur ein Farbwert des jeweiligen Pixels verändert werden. Im Algorithmus wird in jedem Pixel der Farbwert auf 0 gesetzt wenn er geradzahlig ist und auf 255 wenn der Farbwert ungerade ist. Hier entsteht, falls eine Nachricht eingebettet ist, eine regelmäßige Struktur, die auf die Einbettung hinweist. Im ersten Bild ist keine Nachricht eingebettet. Im zweiten Bild ist deutlich eine Struktur zu erkennen.

Diese Erkennung funktioniert aber nur, wenn die veränderten Farbwerte nicht zufällig im Bild verteilt sind. Es gibt noch weitere Verfahren um festzustellen ob Informationen in einem Bild versteckt sind. Es würde hier aber zu weit führen diese zu behandeln.

Als Trägerdateien können überings nicht nur Bilddateien dienen, sondern auch Audio- und Videodateien. Interessant ist es auch einen Live-Chat  in einem Live-Video zu verstecken. Hier braucht man aber ein Video bei dem sich möglichst viele Pixel ständig verändern, da normalerweise nur die Änderungen von einem Frame zum anderen übertragen werden und somit die Kapazität davon abhängt.

Ich hoffe mal, dass euch der kleine Ausflug in die Welt der Steganographie gefallen hat!

 


Wie hat dir der Artikel gefallen? 1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Bisher keine Bewertungen)

Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Ich akzeptiere

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.