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:
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:
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.
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.
Leave a comment