September 2008 Archives

Panasonic - eine Hass Liebe

| | Comments (0) | TrackBacks (0)
Ich habe mir letztes Jahr einen 720p HD Beamer (PT-AX100E) bei Digitec gekauft, für den stolzen Preis von etwa 2000SFr (passend zu der PS3). Schon nach 2 Monaten hat er nicht mehr richtig funktioniert, und schaltete nach 5 Minuten betrieb einfach wieder aus. Anstatt Digitec oder Panasonic war aber die John Lay Electronics AG für die Reperatur zuständig. Nach einem Mail sagten die mir, dass ihnen den Fehler bekannt wäre und ich solle ihnen den Beamer zuschicken. Eine Woche bangte ich darum, ob ich das Ding jemals wieder sehen werde, Geschichten aus der C't ("Achtung Kunde!") im Hinterkopf . Ich sah ihn auch nicht wieder, sondern war nach der besagten Woche im Besitz eines brandneuen Austauschgerätes. w00t!

Nun, etwa 1 1/2 Jahre später, hatte dieses Gerät fast den gleichen Fehler. Ich schrieb wieder ein Mail, ala "Beamer putt", sie "schicken!", ich "ok!", nach 2 Tagen sie "Gerät in Kulanz repariert, ist auf der Post". Woooow!

Der Beamer ist Top, aber dieser Bug nervt doch ungemein. Normalerweise würde ich kein Panasonic mehr kaufen, bei einem so fehlerhaft produziertem Gerät.
Bei so einem schnellen, freundlichen und effizientem Support könnte ich aber das nächste mal wieder auf Panasonic setzen.

Danke, John Lay!
Ich habe den DNS Channel PoC mässig implementiert:

Kelvin:
kelvin-01.png


TCPDUMP:

15:36:11.832808 IP 192.168.1.1.1234 > 192.168.1.47.53:  666+ A? 2.1.666.20201.6.encKey. (40)
15:36:11.838413 IP 192.168.1.47.53 > 192.168.1.1.1234:  666 1/0/0 CNAME[|domain]

Wireshark Capture vom Reply Packet:
View image

UDP Packete, welche von einem Netzwerkinterface empfangen werden, abzufangen ist einfach:
inetsw[ip_protox[IPPROTO_UDP]].pr_input = input_hook_udp;
UDP Packete, welche von einem Prozess gesendet werden, abzufangen ist auch einfach:
inetsw[ip_protox[IPPROTO_UDP]].pr_usrreqs->pru_send = udp_send_hook;
So konnte ich sehr schnell den DNS Channel mit "Packet Exchange" implementieren. Den Packetinhalt auszutauschen erschien mir aber zu komplex, umständlich und unsicher, also wollte ich direkt vom input_hook_udp() die Antwort zurücksenden.
Ich habe die letzten paar Tage den Kernel studiert und bemerkt, dass das doch nicht so trivial ist wie ichs mir vorgestellt habe.
Letzendlich habe ich darauf verzichtet, einen eigenen Socket zu erstellen und wollte udp_output() benutzen (nicht etwa ip_output()). udp_output() braucht aber als Parameter einen Thread, welchen aber die Funktion input_hook_udp() nicht besitzt.
Mithilfe der unten aufgezählten Bücher fand ich schlussendlich heraus, wie ich an den Thread td kommen kann:
Einfach über alle vorhandenen Prozesse laufen (curthread->td_proc->p_list), und auf jedem solchen Thread all seine Files (proc->p_fd) die Sockets finden, und vergleichen ob der Prozess den richtigen Socket besitzt. Richtig heisst: identisch mit inpcb->inp_socket (inpcb kann man leicht min inpcb_lookup_hash() finden).

Nebenbei bemerkte ich aber, dass die udp_output() Funktion nur beschränkt auf die Thread Struktur zugreift, eigentlich nur auf td.td_ucred. Ein einfaches Fake-Argument (welches nur aussagt, dass der Fake-Thread nicht Jailed ist):

struct thread td;
struct ucred cred;
cred.cr_prison = NULL;
td.td_ucred = &cred;

und schon läufts mit udp_output(). Eine sehr viel einfachere Lösung als die Doppelschleife der korrekten Lösung, und um einiges performanter


Unglaublich nützliche Bücher:

TCP/IP Illustrated Volume 1: The Protocols (W. Richard Stevens) (amazon)
Beschreibt detailiert viele Protokolle, unter anderem DNS. Sehr nützlich um Covert Channels zu implementieren.

TCP/IP Illustrated Volume 2: The Implementation (W. Richard Stevens) (1995) (amazon)
The Design and Implementatiuon of the 4.4BSD Operating System (McKusick, Bostic, Karels, Quarterman) (1996) (amazon)
Ich finde es erstaunlich, fast schon unglaublich, dass die Beschreibung von 4.4BSD (aus dem FreeBSD entstanden ist) und seiner TCP/IP Implementierung heute noch in FreeBSD 6.3 ohne Probleme als Referenz gebraucht werden kann. Der Code hat sich fast nicht verändert, er wurde bloss erweitert; die wichtigsten Funktionen heissen immer noch gleich, die Parameter sind diesselben oder nur leicht anders. Und dass bei Büchern und Software, die über 10 Jahre alt sind (eine Ewigkeit in der Informatik).

Ich freue mich, dass diese exzellenten Standardwerke immer noch aktuell sind.

Moviezz

| | Comments (0) | TrackBacks (0)
Also, mit der IMDB Reihenfolge der Marvel Comics verfilmungen bin ich einverstanden:
Batman (9.1), Iron Man (8.2), The Hulk (7.5)
Wobei man aber jedem Film noch ein zwei Punkte abziehen könnte.

District 13 (7.1) fand ich besonders Unterhaltsam. Viel coole Action, tolle Charaktere, nice Story, typisch Französisch. Auf youtube kann man die Chase Szene bewundern (nach Banlieu 13 suchen). Der "beste" Film, den ich in letzter Zeit gesehen habe.

Black Mask (5.7): billiger Actionfilm, nichtsdestotrotz unterhaltsam, da mit Jet Li. Ich hatte eine Version mit sehr entfremdeter Englischer Übersetzung, wahr sehr seltsam anzuhören. Trotzdem, very Cool. Beta Version der Action Szenen von Matrix.

Hell Ride (5.8): Eine Art Biker Roadmovie mithilfe von Quentin Tarantino. Erfreulich viele sehr schöne sehr Nackte Frauen, primitives "Lets Fuck" gelaber wie ein Porno und viele "wir drehen die Szene nur weil er so cool dasteht". Schauspieler unüberzeugend, Geschichte verwirrt und irrelevant, Null Spannung. Übel.

Eden Log (5.0): Einfach *anders*. No Budget Movie, bei dem man die Fast-Forward Taste immer in Reichweite haben sollte. Aber sehr Cyberpunkig.

The Objective (5.6): Wirklich gute erste Hälfte, hält aber leider nicht was er da verspricht, sehr schade.

Die Einzige Serie, die ich verfolge und aktuell läuft, ist leider nur Naruto.
Damn you, Hollywood!
Ein Problem das Rheya hat: Welche Packete gehören nun zum "normalen" Traffic und sollten ignoriert werden, und welche sind vom Client und sollten von Rheya interpretiert werden?

Ich implementiere Zwei Mechanismen zur Unterscheidung:


a) IP Identification Mode

Rheya interpretiert alle Packets von bestimmten IPs als Requests von Kelvin und versucht sie zu verarbeiten.
Das funktioniert nur gut, falls wirklich alle Packets dieser IP von Kelvin stammen. Meist jedoch möchte ein Angreifer das System auch noch anderweitig brauchen, und nicht nur sein Rootkit fernsteuern. Die Lösung heisst Magic Mode, welche aber mehr Angriffsfläche zur maschinellen Identifizierung bietet.

Gebraucht wird:
  • Offset into Packet für Request Payload + Enkodierung
  • Liste der möglichen Client Source IP Addressen

b) Magic Mode

Falls an einer eindeutigen stelle im Packet eine bestimmte Byte Sequenz steht, stammt das Packet von Kelvin. Ein statischer Offset genügt bei den meisten Protokollen, um einen Wert eindeutig zu lokalisieren.

Gebraucht wird:
  • Offset in Packet für Request Payload + Enkodierung
  • Offset in Packet für Magic
  • Magic Byte Sequenz

Exchange or Drop

Bei ICMP, UDP und anderen Verbindungslosen Protokollen ist es möglich, das Packet gar nicht erst den Userspace erreichen zu lassen, sondern die Antwort direkt im Kernel zurücksendet. Dies hat Vorteile, wie dass ein lokale Sniffer die Pakete nicht sieht. Bei Verbindungsorientierten Protokollen wie TCP würde das aber auffallen, und man könnte das Packet noch vor der weitergabe an den Userspace säubern oder austauschen.

Protokoll Beispiele

ICMP:
Kelvin schickt ICMP Echo Request, Server antwortet mit ICMP Echo Reply.
Der Offset für den Request und das Magic zeigt irgendwo in den ICMP Payload.
Die Antwort von Rheya wird wieder als ICMP Payload mitgeführt.
Derzeit verändert Rheya die ICMP Daten bevor das Packet verarbeitet wird, was den Vorteil hat dass ein Lokaler Sniffer das korrekte verhalten sieht (der ICMP Payload des Echo Request- und Reply Packetes sollte identisch sein. Ein Host jedoch welcher den Netzwerkverkehr abhört, kann die Differenz und damit vielleicht das Backdoor erkennen).

DNS:
Kelvin schickt ein DNS Request (QR=1) Packet, mit einem geeignetem Query Type (A, CNAME, HINFO...). Der eigentliche Solyaris Request wird als Domain encodiert und als Query Name gesendet. Er könnte etwa so aussehen:
Format: <serviceid>.<commandid>...<uuencodet arguments>.google.ch
Beispiel: 1.3...passwort.google.ch

Die Antwort des Server beinhaltet ein oder mehrere Ressource Records (RR), welche genügend Platz für die Antwort lassen.

Das Magic ist entweder auch Teil der Domain des Query Name, oder in einem anderem Feature des DNS Protokolls (z.B. dem Zero Field).

Zukunft

Wenn das umwandeln des Requests in einen Domain Namen geschickt gewählt wird (möglich wäre auch für eine ID: 1 = www, 2 = ftp, 3 = pop usw), ist dieser Covert Channel noch schwerer zu entdecken, sogar mit blossem Auge.

Das Magic könnte später von einem PRNG bei jedem Request neu generiert werden. Dazu müsste aber Client und Server synchron sein.

Später könnte man die Daten auch nicht mehr an statischen Offsets suchen, sondern könnte das zugrundeliegende Protokoll Ganz oder Teilweise analysieren. Dies würde jedoch nicht gut mit dem Magic Mode funktionieren, da sonst z.B. bei einem Webserver jedes HTTP Packet zuerst analysiert werden muss, und das im Kernel Mode. UDP und ICMP Requests sind recht selten, jedoch auch recht statisch.

Die Daten werden bisher auch noch unverschlüsselt übertragen. Bei einer Verschlüsselung müsste man den Request jedoch UUEncoden, was die Verfügbare Kapazität etwa halbiert. Evntl ist es machbar, nur die Argumente zu verschlüsseln, die Request Header Daten jedoch mit einem (frei wählbaren, individuellen, Passwort artigem) Offset zu verschieben (Abgesehen von "offensichtlichen" Befehlen wie connect, der bei jedem Verbindungsstart gesendet wird).

Es wäre wünschenswert, mehrere mögliche DNS Query Types zu unterstüzen. Dann könnte zu sendende Host einen davon nach einer prozentuellen Chance auswählen.

Hier eine FAQ, warum ich mich entschieden habe ein Rootkit zu entwickeln.

Was ist ein Rootkit?

Auf Wikipedia steht: Ein Rootkit ist dafür da, Root zu behalten. (1)
Es stellt also erstens Möglichkeiten bereit, auf ein System zuzugreifen, z.B. per Network Backdoor, oder ein Lokales Backdoor zur Rechteerhöhung. Zweitens soll es dem Angreifer seine Präsenz auf dem System verbergen, indem es Prozesse, Dateien und Netzwerkverbindungen versteckt. Drittens kann es noch Tools beinhalten, welche den Angreifer unterstützen, z.B. Log Cleaner oder Password Sniffer.

Es ist also ein Werkzeug, um mit dem kompromitierten System arbeiten zu können.


Was sind die Ziele von Solyaris?

Stealth.

Alle bisherigen Rootkits verstehen unter Stealth, dass sie sich möglichst nicht lokal entdecken lassen. Diese Gebiet ist gut erforscht und sehr interessant, aber es wird wohl immer möglich sein, Kernel Rootkits zu entdecken.
Aber: wer lässt schon regelmässig einen rootkitchecker auf seinen Servern laufen?

Wie sieht es aber mit der Kommunikation des Backdoors des Rootkits aus? Diese könnte einfach entdeckt werden, wenn ein Host anfängt, Packete an nicht offenen Ports zu empfangen oder Packete zu senden, welche der Firewall blockt und loggt.
Die Lösung heisst Covert Channels, also das übertragen von Daten über bestehende Kanäle, die eigentlich nicht dafür gedacht sind. Zusätzlich sollte nicht nur ein Covert Channel benutzt werden, sondern möglichst viele auf einmal (Channel Hopping)

Usability.

Es gibt viele Rootkits, aber keines scheint wirklich aktuell, benutzerfreundlich, stabil und einfach brauchbar zu sein. Gewünschte Features wären hier noch: Encryption, Authentifizierung, Packet Forwarding, guter Client.
Was Metasploit für Exploits ist, soll Solyaris für Rootkits werden.


Was sind spezifische Features von Solyaris?

Snaut

Rheya ist ein Kernel Rootkit. Kernel programming ist aber mühsam, nur schon das auflisten aller Dateien eines Verzeichnisses bräuchte hunderte Zeilen Code.
Andere Rootkits umgehen das mit Syscall Proxying/Forwarding, oder eigenen VM's.
Ich habe mich entschieden, einfach eine Userspace Komponente zu integrieren, welche ich Snaut getauft habe. Snaut ist ein normaler Prozess, wird vom Kernel Rootkit versteckt, welcher auch über ein Chardevice mit ihm kommuniziert.

Der Client kann dann entweder mit Rheya kommunizieren, und das Rootkit dadurch konfigurieren und rudimentäre Funktionen ansteuern.
Oder er redet mit Snaut, indem er Rheya veranlasst, die Daten zu Snaut zu forwarden. Da Snaut im Userspace läuft, kann man durch ihn jegliche gewünschte Funktionalität implementieren, ohne durch den Kernelspace eingeschränkt zu sein.

Covert Channel Hopping

Die Kommunikation soll so versteckt wie möglich stattfinden. Solyaris wird so entwickelt, dass die Kommunikation mit Rheya genau so wie ganz Normaler Traffic aussieht. Es ist sogar so, dass das Backdoor nur über Covert Channels anzusprechen ist, der legetimate Channel muss also vorhanden sein!
Das Bedeutet: Falls Solyaris auf einem Webserver installiert wird, wird der HTTP Covert Channel verfügbar, ist es auf einem DNS Server installiert, der DNS Covert Channel etc.
Siehe auch: Protocol Hopping Covert Channels


Vielleicht werde ich später noch ausführlichere Artikel über diese Themen schreiben.

(1) Die Englische Wikipedia hat es wieder mal falsch

Solyaris #2

| | Comments (0) | TrackBacks (0)
Update on Rheya, dem FreeBSD Kernel Backdoor:
  • ICMP Channel implementiert
  • Command Interpreter funktioniert (Befehle: connect, test, disconnect)
  • Session Handling implementiert
Update on Kelvin:
  • Auch das Session Handling implementiert
  • DNS Request/Reply Channel PoC
Die Kommunikation zwischen Client und Server über den ICMP Channel funktioniert jetzt also schonmal, das ganze ist aber noch unbrauchbar.

Als nächstes kommt:
  • Packet Identifikation: per Magic und IP
  • DNS Channel

About this Archive

This page is an archive of entries from September 2008 listed from newest to oldest.

August 2008 is the previous archive.

October 2008 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Pages