- Mitglied seit
- 10 Mai 2006
- Beiträge
- 15,267
- Punkte für Reaktionen
- 1,750
- Punkte
- 113
Nachdem hier bei mir eine 7580 (1&1) mit Firmware 06.54 eintrudelte, stand ich vor der Frage, wie ich auf diesem Gerät zu meinem ersten Shell-Zugang gelangen könnte.
Es gibt zwar die Möglichkeit, sich eine interne Version von AVM (inkl. ShellInABox und Telnet-Service) zu besorgen und diese als Update zu installieren ... das widerstrebt mir aber, weil ich einen solchen Zugang immer über den kleinstmöglichen Eingriff in das originale Gerät erhalten will, um soviel wie möglich vom ursprünglichen Zustand des Gerätes zu konservieren. Da ist die Installation einer neuen Firmware nun nicht gerade ein Eingriff, der zu dieser Intention passen würde.
Der Weg über das Ändern der "/etc/inittab" in einer yaffs2-Partition, wie er bei den VR9-Modellen i.d.R. machbar ist (so arbeitete ja "modfs-Starter"), fällt bei der 7580 und der 7560 ebenfalls aus, da diese Modelle eben keine solche Partition verwenden - dort kommt direkt ein SquashFS-Image auf dem UBI-Layer für den NAND-Flash zum Einsatz. Dieser Weg ist bei den anderen (VR9-)Modellen mit Wrapper-Partition zwar auch nicht "ganz sauber", wenn man streng nach Forensik-Regeln vorgehen will, aber zumindest kann man mit Retten alter Inhalte des yaffs2-Dateisystems die Beeinträchtigungen des Untersuchungsgegenstandes in Grenzen halten. Aber wie gesagt ... das funktioniert bei der 7580 so nicht.
Aber wie bei anderen Modellen mit NAS-Funktion gibt es natürlich auch hier die Möglichkeit, sich auf einem USB-Speicher ein entsprechendes Skript vorzubereiten und dann muß man nur noch die Frage klären (das machen wir im Anschluß), wie man die Ausführung dieses Skripts nun anstoßen könnte.
Widmen wir uns erst einmal der Frage, was es für die Installation eines Shell-Zugangs (mit kleinstmöglichem Aufwand, also ohne großes Nachladen von Binaries) braucht ... da ist ja schon seit langem bekannt, daß seitens AVM der Zugriff auf das "telnetd"-Applet der BusyBox nur durch eine zusätzliche Abfrage, ob "/usr/sbin/telnetd" existiert und ein symbolischer Link ist (wohin, ist sogar egal), verhindert wird. Hier hilft also wieder das alte Spiel, die paar Dateien in "/usr/sbin" komplett an eine beschreibbare Stelle im "tmpfs" zu kopieren und dann dieses Verzeichnis mittels der "bind"-Option über das ursprüingliche Verzeichnis "/usr/sbin" zu mounten. In dem damit nun beschreibbaren Verzeichnis kann man dann den notwendigen Symlink anlegen und dann muß man sich nur noch überlegen, auf welchem Weg man den "telnet"-Daemon nun gerne starten möchte. Dafür bietet sich zwar der passende Telefon-Code (#96*7*) auch an, aber es geht auch anders und so nutze ich hier einfach mal einen solchen anderen Weg.
Eine andere Herausforderung ist es, eine Änderung so herbeizuführen, daß diese auch nach einem Neustart der Box noch greift - u.a. auch deshalb, weil einige der möglichen RCE-Lücken (über die man das Skript dann aufrufen kann) erst im Rahmen des Neustarts der Box aufgerufen werden oder die benutzten Funktionen ihrerseits einen solchen Neustart nach sich ziehen.
Daher greife ich hier wieder auf eine bereits bekannte Lücke (die in der 06.54 noch existiert) zurück und benutze die "provideraddtive.tar" zum Start eines Telnet-Services nach jedem Neustart. Zuvor habe ich mich natürlich vergewissert, daß die verwendete FRITZ!Box nicht bereits eine "provideradditive.tar" enthält - ansonsten könnte man diese auch über die "erweiterten Support-Daten" vorher extrahieren oder sogar im Skript zuvor noch gesondert sichern (auf dem verwendeten USB-Stick), bevor man sie überschreiben läßt.
Das "fertige" Skript zum Kopieren auf den USB-Stick sieht dann so aus (im Anhang gibt es das auch noch ohne Zeilennummern, die hier nur zur besseren Orientierung enthalten sind):
Was passiert da nun genau?
In den Zeilen 1 und 2 wird ein Verzeichnis im beschreibbaren Speicher der FRITZ!Box angelegt und in dieses gewechselt. Von Zeile 3 bis 11 wird eine Datei "/var/start_telnet" erzeugt, die später Bestandteil der "provideradditive.tar" werden soll. Analoges erfolgt in den Zeilen 13 bis 16 für eine neue Datei "/var/tmp/inetd.conf", nachdem zuvor in Zeile 12 die existierende Datei gesichert wurde. Nachdem nun diese beiden Dateien existieren, wird in Zeile 17 ein Symlink für das "/var"-Verzeichnis erzeugt, der zusammen mit den beiden erzeugten Dateien in ein "tar"-Archiv verpackt wird, welches dann gleich in den richtigen TFFS-Node für die "provideradditive.tar" geschrieben wird. Das erfolgt in Zeile 19, nachdem dieser Node zuvor in Zeile 18 angelegt wurde. Anschließend wird noch die zuvor gesicherte Kopie der "inetd.conf" restauriert und das in Zeile 1 angelegte Verzeichnis wieder entfernt. Damit steht an dieser Stelle jetzt in der "provideradditive.tar" ein Archiv, welches beim Auspacken durch die AVM-Komponenten die Dateien "/var/start_telnet" und "/var/tmp/inetd.conf" erzeugt.
Das erfolgt dann unmittelbar beim nächsten Start des Systems und dann enthält die "inetd.conf" des Systems zunächst zwei zusätzliche Einträge, die beim Herstellen einer TCP-Verbindung auf Port 23 (das ist der Telnet-Port) oder auf Port 514 (das ist "rexec" bzw. "rcmd" und hier wird einfach eine Shell aufgerufen, die das Kommando auf STDIN ausführt und den Inhalt von STDOUT über das Netzwerk ausgibt) die Ausführung eigener Kommandos ermöglichen. Allerdings führt so ein Eintrag in der "inetd.conf" ja noch nicht zur Ausführung des dort angegebenen Kommandos ... dazu braucht es erst die eingehende TCP-Verbindung. Daher steht direkt nach dem Auspacken aus der "provideradditive.tar" für den Telnet-Service auch noch die Ausführung der Datei "/var/start_telnet" in der "inetd.conf" ... damit wird diese Datei beim ersten Verbindungsversuch gestartet. Diese führt dann die weiter oben erwähnten Aktionen aus (Kopieren des Inhalts von "/usr/sbin", Mounten des Verzeichnisses und Anlegen des Symlinks für "telnetd") und ändert anschließend den Eintrag für Port 23 dahingehend ab, daß dort direkt ein Telnet-Daemon mit einer Shell ohne jede Notwendigkeit einer Anmeldung (damit auch ohne Ausführung der "/etc/profile" und ohne Setzen des "Vom Hersteller nicht unterstützte Änderungen"-Flags) gestartet wird, bevor zuletzt noch der "inetd"-Service zum neuen Einlesen seiner Konfiguration überredet wird und für diesen ersten Verbindungsversuch die Nachricht "Telnet support initialized" zum Aufrufer geschickt wird.
Beim nächsten Aufruf eines Telnet-Clients wird dann ganz normal der Telnet-Dienst verwendet ... das ist (gerade beim Editieren von Kommandos) um einiges komfortabler als die Verwendung von "rexec" auf Port 514.
Bleibt also noch die Aufgabenstellung, dieses Skript (nachdem es auf den USB-Stick kopiert wurde) irgendwie aufzurufen ... dafür bietet sich z.B. diese Lücke an, bei der das auszuführende Kommando (in der Form "/bin/sh /var/media/ftp/usb_volume/script_name", was dann auch gleich noch das "noexec"-Flag umgeht - logischerweise an die eigenen Gegebenheiten angepaßt) in das Kennwort für den automatischen Export der Einstellungen eingebettet wird. Eine andere Alternative ist diese Lücke, bei der das auszuführende Kommando in der URL für den Download einer neuen Firmware eingebettet wird. Diese Lücke ist von AVM in der 06.83 nunmehr auch gefixt ... daher (und weil sie ohnehin nur per TR-069 (das müßte ich erst noch einmal ausführlich testen) und TR-064 ausgenutzt werden kann) spricht nichts dagegen, dafür ein passendes PowerShell-Skript zu veröffentlichen (die Policy besagt ja, nach 90 Tagen oder nach der Veröffentlichung einer korrigierten Version durch den betroffenen Hersteller).
Beide Lücken ziehen aber einen Neustart nach sich (sofern man den nicht abbricht, was aber wegen des zuvor erfolgten Aufrufs von "prepare_fwupgrade" wieder einen Heidenaufwand nach sich ziehen würde) und daher eignen sie sich wirklich nur für Kommandos, die ihrerseits eine (zumindest semi-)permanente Änderung herbeiführen, die auch nach dem Neustart noch greift.
Jedenfalls kann man dann nach dem Neustart im zweiten Verbindungsversuch problemlos eine Telnet-Session benutzen und sich die FRITZ!Box näher ansehen ... und das alles mit nur sehr marginalen Änderungen an der Firmware (praktisch wurde nur die "provideradditive.tar" hinzugefügt), die den Gegenstand der Untersuchung eben auch nur minimal verändern (anders als es eine neue Firmware mit einem Shell-Zugang machen würde - die braucht ja dann den Platz in ihrer Partition und überschreibt dort ggf. schon liegende Daten).
Es gibt zwar die Möglichkeit, sich eine interne Version von AVM (inkl. ShellInABox und Telnet-Service) zu besorgen und diese als Update zu installieren ... das widerstrebt mir aber, weil ich einen solchen Zugang immer über den kleinstmöglichen Eingriff in das originale Gerät erhalten will, um soviel wie möglich vom ursprünglichen Zustand des Gerätes zu konservieren. Da ist die Installation einer neuen Firmware nun nicht gerade ein Eingriff, der zu dieser Intention passen würde.
Der Weg über das Ändern der "/etc/inittab" in einer yaffs2-Partition, wie er bei den VR9-Modellen i.d.R. machbar ist (so arbeitete ja "modfs-Starter"), fällt bei der 7580 und der 7560 ebenfalls aus, da diese Modelle eben keine solche Partition verwenden - dort kommt direkt ein SquashFS-Image auf dem UBI-Layer für den NAND-Flash zum Einsatz. Dieser Weg ist bei den anderen (VR9-)Modellen mit Wrapper-Partition zwar auch nicht "ganz sauber", wenn man streng nach Forensik-Regeln vorgehen will, aber zumindest kann man mit Retten alter Inhalte des yaffs2-Dateisystems die Beeinträchtigungen des Untersuchungsgegenstandes in Grenzen halten. Aber wie gesagt ... das funktioniert bei der 7580 so nicht.
Aber wie bei anderen Modellen mit NAS-Funktion gibt es natürlich auch hier die Möglichkeit, sich auf einem USB-Speicher ein entsprechendes Skript vorzubereiten und dann muß man nur noch die Frage klären (das machen wir im Anschluß), wie man die Ausführung dieses Skripts nun anstoßen könnte.
Widmen wir uns erst einmal der Frage, was es für die Installation eines Shell-Zugangs (mit kleinstmöglichem Aufwand, also ohne großes Nachladen von Binaries) braucht ... da ist ja schon seit langem bekannt, daß seitens AVM der Zugriff auf das "telnetd"-Applet der BusyBox nur durch eine zusätzliche Abfrage, ob "/usr/sbin/telnetd" existiert und ein symbolischer Link ist (wohin, ist sogar egal), verhindert wird. Hier hilft also wieder das alte Spiel, die paar Dateien in "/usr/sbin" komplett an eine beschreibbare Stelle im "tmpfs" zu kopieren und dann dieses Verzeichnis mittels der "bind"-Option über das ursprüingliche Verzeichnis "/usr/sbin" zu mounten. In dem damit nun beschreibbaren Verzeichnis kann man dann den notwendigen Symlink anlegen und dann muß man sich nur noch überlegen, auf welchem Weg man den "telnet"-Daemon nun gerne starten möchte. Dafür bietet sich zwar der passende Telefon-Code (#96*7*) auch an, aber es geht auch anders und so nutze ich hier einfach mal einen solchen anderen Weg.
Eine andere Herausforderung ist es, eine Änderung so herbeizuführen, daß diese auch nach einem Neustart der Box noch greift - u.a. auch deshalb, weil einige der möglichen RCE-Lücken (über die man das Skript dann aufrufen kann) erst im Rahmen des Neustarts der Box aufgerufen werden oder die benutzten Funktionen ihrerseits einen solchen Neustart nach sich ziehen.
Daher greife ich hier wieder auf eine bereits bekannte Lücke (die in der 06.54 noch existiert) zurück und benutze die "provideraddtive.tar" zum Start eines Telnet-Services nach jedem Neustart. Zuvor habe ich mich natürlich vergewissert, daß die verwendete FRITZ!Box nicht bereits eine "provideradditive.tar" enthält - ansonsten könnte man diese auch über die "erweiterten Support-Daten" vorher extrahieren oder sogar im Skript zuvor noch gesondert sichern (auf dem verwendeten USB-Stick), bevor man sie überschreiben läßt.
Das "fertige" Skript zum Kopieren auf den USB-Stick sieht dann so aus (im Anhang gibt es das auch noch ohne Zeilennummern, die hier nur zur besseren Orientierung enthalten sind):
Code:
1 mkdir /var/pad
2 cd /var/pad
3 cat >/var/start_telnet <<'EOT'
4 umount /usr/sbin 2>/dev/null
5 rm -r /var/usrsbin 2>/dev/null
6 cp -a /usr/sbin /var/usrsbin
7 mount /var/usrsbin /usr/sbin -o bind
8 ln -s ../../bin/busybox /usr/sbin/telnetd
9 sed -e '/^23 /d' -e '$a23 stream tcp6 nowait root /bin/busybox telnetd -l /bin/sh -i -K' /var/tmp/inetd.conf >/var/tmp/inetd.conf.new && mv /var/tmp/inetd.conf.new /var/tmp/inetd.conf && kill -HUP $(pidof inetd)
10 echo "Telnet support initialized"
11 EOT
12 mv /var/tmp/inetd.conf /var/inetd.conf.bak
13 cat >/var/tmp/inetd.conf <<'EOT'
14 23 stream tcp6 nowait root /bin/sh sh /var/start_telnet
15 514 stream tcp6 nowait root /bin/sh sh
16 EOT
17 ln -s /var v
18 mknod node c $(sed -ne 's|^[ ]*\([0-9]*\)[ \t]tffs.*$|\1|p' /proc/devices) 29
19 tar -c -O v v/start_telnet v/tmp/inetd.conf >node
20 mv /var/inetd.conf.bak /var/tmp/inetd.conf
21 cd /
22 rm -r /var/pad
In den Zeilen 1 und 2 wird ein Verzeichnis im beschreibbaren Speicher der FRITZ!Box angelegt und in dieses gewechselt. Von Zeile 3 bis 11 wird eine Datei "/var/start_telnet" erzeugt, die später Bestandteil der "provideradditive.tar" werden soll. Analoges erfolgt in den Zeilen 13 bis 16 für eine neue Datei "/var/tmp/inetd.conf", nachdem zuvor in Zeile 12 die existierende Datei gesichert wurde. Nachdem nun diese beiden Dateien existieren, wird in Zeile 17 ein Symlink für das "/var"-Verzeichnis erzeugt, der zusammen mit den beiden erzeugten Dateien in ein "tar"-Archiv verpackt wird, welches dann gleich in den richtigen TFFS-Node für die "provideradditive.tar" geschrieben wird. Das erfolgt in Zeile 19, nachdem dieser Node zuvor in Zeile 18 angelegt wurde. Anschließend wird noch die zuvor gesicherte Kopie der "inetd.conf" restauriert und das in Zeile 1 angelegte Verzeichnis wieder entfernt. Damit steht an dieser Stelle jetzt in der "provideradditive.tar" ein Archiv, welches beim Auspacken durch die AVM-Komponenten die Dateien "/var/start_telnet" und "/var/tmp/inetd.conf" erzeugt.
Das erfolgt dann unmittelbar beim nächsten Start des Systems und dann enthält die "inetd.conf" des Systems zunächst zwei zusätzliche Einträge, die beim Herstellen einer TCP-Verbindung auf Port 23 (das ist der Telnet-Port) oder auf Port 514 (das ist "rexec" bzw. "rcmd" und hier wird einfach eine Shell aufgerufen, die das Kommando auf STDIN ausführt und den Inhalt von STDOUT über das Netzwerk ausgibt) die Ausführung eigener Kommandos ermöglichen. Allerdings führt so ein Eintrag in der "inetd.conf" ja noch nicht zur Ausführung des dort angegebenen Kommandos ... dazu braucht es erst die eingehende TCP-Verbindung. Daher steht direkt nach dem Auspacken aus der "provideradditive.tar" für den Telnet-Service auch noch die Ausführung der Datei "/var/start_telnet" in der "inetd.conf" ... damit wird diese Datei beim ersten Verbindungsversuch gestartet. Diese führt dann die weiter oben erwähnten Aktionen aus (Kopieren des Inhalts von "/usr/sbin", Mounten des Verzeichnisses und Anlegen des Symlinks für "telnetd") und ändert anschließend den Eintrag für Port 23 dahingehend ab, daß dort direkt ein Telnet-Daemon mit einer Shell ohne jede Notwendigkeit einer Anmeldung (damit auch ohne Ausführung der "/etc/profile" und ohne Setzen des "Vom Hersteller nicht unterstützte Änderungen"-Flags) gestartet wird, bevor zuletzt noch der "inetd"-Service zum neuen Einlesen seiner Konfiguration überredet wird und für diesen ersten Verbindungsversuch die Nachricht "Telnet support initialized" zum Aufrufer geschickt wird.
Beim nächsten Aufruf eines Telnet-Clients wird dann ganz normal der Telnet-Dienst verwendet ... das ist (gerade beim Editieren von Kommandos) um einiges komfortabler als die Verwendung von "rexec" auf Port 514.
Bleibt also noch die Aufgabenstellung, dieses Skript (nachdem es auf den USB-Stick kopiert wurde) irgendwie aufzurufen ... dafür bietet sich z.B. diese Lücke an, bei der das auszuführende Kommando (in der Form "/bin/sh /var/media/ftp/usb_volume/script_name", was dann auch gleich noch das "noexec"-Flag umgeht - logischerweise an die eigenen Gegebenheiten angepaßt) in das Kennwort für den automatischen Export der Einstellungen eingebettet wird. Eine andere Alternative ist diese Lücke, bei der das auszuführende Kommando in der URL für den Download einer neuen Firmware eingebettet wird. Diese Lücke ist von AVM in der 06.83 nunmehr auch gefixt ... daher (und weil sie ohnehin nur per TR-069 (das müßte ich erst noch einmal ausführlich testen) und TR-064 ausgenutzt werden kann) spricht nichts dagegen, dafür ein passendes PowerShell-Skript zu veröffentlichen (die Policy besagt ja, nach 90 Tagen oder nach der Veröffentlichung einer korrigierten Version durch den betroffenen Hersteller).
Beide Lücken ziehen aber einen Neustart nach sich (sofern man den nicht abbricht, was aber wegen des zuvor erfolgten Aufrufs von "prepare_fwupgrade" wieder einen Heidenaufwand nach sich ziehen würde) und daher eignen sie sich wirklich nur für Kommandos, die ihrerseits eine (zumindest semi-)permanente Änderung herbeiführen, die auch nach dem Neustart noch greift.
Jedenfalls kann man dann nach dem Neustart im zweiten Verbindungsversuch problemlos eine Telnet-Session benutzen und sich die FRITZ!Box näher ansehen ... und das alles mit nur sehr marginalen Änderungen an der Firmware (praktisch wurde nur die "provideradditive.tar" hinzugefügt), die den Gegenstand der Untersuchung eben auch nur minimal verändern (anders als es eine neue Firmware mit einem Shell-Zugang machen würde - die braucht ja dann den Platz in ihrer Partition und überschreibt dort ggf. schon liegende Daten).
Anhänge
Zuletzt bearbeitet: