Da denke ich dann mal eine Weile drauf herum ... solange File-I/O noch funktioniert (das nutzt AVM ja selbst - das Entfernen/Blockieren von
system()
-Calls auf anderen Wegen trägt nach meiner Überzeugung auch nicht wirklich zum Erhöhen der Sicherheit bei und ist eher ein "unfreundlicher Akt"), kann man auch ganz einfach eine Shell mit ihrem
STDIN
-Handle in einem (durchlaufenden) Service hinter eine Pipe legen:
Rich (BBCode):
~ # rm -f /var/run/shell.fifo; mknod /var/run/shell.fifo p; sh < /var/run/shell.fifo & printf "/usr/bin/gui_bootmanager debug" >/var/run/shell.fifo
system type = VR9
system selector = 1
system is switched = true
system branding = 1und1
system branding is changeable = true
active kernel = /dev/mtdblock0
active filesystem = /wrapper/filesystem_core.squashfs
active system version = 113.07.24-86493
active system date = 18.02.2021, 17:12:04 Uhr
active system modification date = 02.03.2021, 01:57:23 Uhr
active system modification source = modfs
brandings supported on active system = 1und1 avm avme
inactive kernel = /dev/mtdblock2
inactive system is installed = true
inactive filesystem = mount:/dev/mtdblock3:/filesystem_core.squashfs
inactive filesystem mounted on /var/tmp/9161_1644609859/alt_root
inactive system version = 113.07.19-77201
inactive system date = 06.04.2020, 20:59:45 Uhr
inactive system modification date = 12.06.2020, 17:45:47 Uhr
inactive system modification source = modfs
brandings supported on inactive system = 1und1 avm avme
inactive filesystem dismounted
^C
~ #
[2]+ Done sh 0</var/run/shell.fifo
~ #
So wäre also schon mal "komfortabel" der Zugriff auf eine Shell möglich (denn das Schreiben in die Pipe kann auch deutlich später und von anderer Stelle erfolgen) ... aber auch mit einiger Unsicherheit, denn da kann dann wieder jeder schreiben (und deshalb nimmt man da dann halt auch nicht direkt ein
/bin/sh
). Ich hoffe mal nicht, daß sich AVM auf einen "Kampf" einlassen würde, bei dem es um das komplette "Verhindern" von OS-Aufrufen geht ... irgendein Weg findet sich immer, solange man die Firmware modifizieren kann.
Und das sogar üblicherweise "nur mit Bordmitteln" (wozu ich alles zähle, was von AVM installiert wurde PLUS eigene Dateien, die aber keine Binaries sind) ... das
mknod
verwendet AVM selbst (u.a. beim Erzeugen der Minor-Nodes im TFFS) und das müßte man schon seiner Fähigkeiten mit dem Typ
p
berauben - wobei das ohnehin kein POSIX wäre, denn das kennt nur ein
mkfifo
(
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/mkfifo.html) und das
mknod
mit dieser Option ist "GNU-Slang".
Um das dann wieder sicherer zu bekommen, kann man sich einen Service erzeugen, dessen Shell-File die Daten ermittelt und dann in Schleife läuft, um diese Angaben einerseits in einen FIFO als Ausgabe zu schieben (woher der Lua-Code die Daten dann lesen kann) und parallel auf einem weiteren FIFO auf eine Eingabe zu lauschen, die dann eine Umschaltung triggert.
Das hätte sogar wieder den Vorteil, daß man diesen Trigger auch von anderer Stelle auslösen könnte (in
modfs
ist z.B. bisher ein zusätzlicher Aufruf von
gui_bootmanager
enthalten:
https://github.com/PeterPawn/modfs/blob/f3cff1971db83152aa949944b069e26994e5c156/modfs#L3579 - um die ausgeführten Änderungen durch
modfs
zu erfassen) und dieses Triggern auch den "internen Zustand" des Skripts dahingehend ändern kann, daß die ausgegebenen Daten (insbesondere die Zeile
system_is_switched
, die für die Auswahl des korrekten Radio-Buttons in der Browser-Anzeige erforderlich ist) automatisch angepaßt werden.
Wobei mich schon interessieren würde, was sich AVM beim "Stilllegen" der Shell-Aufrufe aus Lua heraus "gedacht" hat - mal unterstellt, daß das tatsächlich absichtlich erfolgte. Es gibt - wie gesagt: solange man die Firmware ändern kann - noch so viele andere Optionen, wie man wieder zu einem Shell-Zugriff gelangen kann (bis hin zum Start einer Shell (analog zu einem
rcmd
-Aufruf) über den
inetd
), die viel "gefährlicher" sind und von denen manche sogar "zur Laufzeit" funktionieren.
Wie z.B. der Weg über den
inetd
, denn dessen Control-File ist "writable" und wäre auch wieder über Lua-Code per
io.write
zu verändern. Ähnliches gilt sogar für die Utilities, die vom Kernel für bestimmte Zwecke aufgerufen werden ... z.B.
/proc/sys/kernel/hotplug
oder
/proc/sys/kernel/modprobe
, wo man durch einfachen Schreibzugriff (und das läuft nun mal bisher alles mit Root-Rechten, wenn AVM das nicht auch noch saniert) auch einfach ein eigenes "Programm" eintragen kann, was der Kernel dann an passender Stelle aufruft und da muß man sich nur überlegen, wie man das dann passend triggert.
Was bei
modprobe
noch schwerer ist als bei
hotplug
(denn ein
/sbin/hotplug
existiert in der originalen Firmware nicht und man muß das nicht mal als "Wrapper" konzipieren) - aber das dann zu triggern, gelingt tatsächlich sogar ohne Authentifizierung auf der LAN-Seite, weil ein per
ForceTermination
getriggerter Neuaufbau der Verbindung auch gleichzeitig dafür sorgt, daß die ganzen Storage-Geschichten neu initialisiert werden (auch wenn ich das Beenden der WAN-Verbindung hier über ein Shell-Kommando auslöse):
Rich (BBCode):
~ # echo -e "#!/bin/sh\necho 'hotplug' >/dev/console\n" >/var/hotplug.sh
~ # chmod a+x /var/hotplug.sh
~ # /var/hotplug.sh
hotplug
~ # echo /var/hotplug.sh >/proc/sys/kernel/hotplug
~ # msgsend -a dsld disconnect
Feb 11 22:07:32 multid[2473]: dhcp_reset_binary_options: iface lan not found
~ # Feb 11 22:07:32 multid[2473]: dhcp_reset_binary_options: iface lan not found
Feb 11 22:07:33 multid[2473]: dhcp_reset_binary_options: iface lan not found
hotplug
Feb 11 22:07:34 multid[2473]: dhcp_reset_binary_options: iface lan not found
[Supervisor] Info: stop smb2.service
---- NQ Server was shut down ---
[Supervisor] Info: smb2.service exit success
[Supervisor] Info: start smb2.service
Feb 11 22:07:38 wsdd[9889]: starting ... (normal)
NQSERVER: server is ready
[Supervisor] Info: stop smb2.service
---- NQ Server was shut down ---
[Supervisor] Info: smb2.service exit success
[Supervisor] Info: start smb2.service
Feb 11 22:07:45 wsdd[10105]: starting ... (normal)
hotplug
NQSERVER: server is ready
Ich weiß natürlich nicht genau, wieviele dieser Wege AVM parallel zu den Lua-Änderungen (die ich jetzt mal unterstelle, auch wenn ich sie selbst noch nicht "in Aktion" gesehen habe) noch verbauen will/würde - und ich hoffe natürlich auch, daß es sich dabei dann um "allgemeine Verbesserungen im Sinne der Sicherheit" handelt und nicht um gezielte Sabotage.
Vielleicht macht ja mal jemand mit der originalen BusyBox eine Liste der enthaltenen Applets - es wäre (wenn AVM da tatsächlich noch weiter die Axt anlegen will) ja auch interessant, was da überhaupt noch enthalten ist. So kann ja z.B. auch das
env
-Applet der BusyBox genutzt werden, um ein Programm zu starten (und nicht nur das
sh
-Applet) - auch das geht notfalls wieder über den
inetd
. Wobei man spätestens beim Modifizieren der Firmware ja auch wieder eine eigene BusyBox hinzufügen könnte - dann müßte man halt von der minimalinvasiven Doktrin (die ich für den Boot-Manager eigentlich verfolge) abweichen. Gleichzeitig setze ich da eigentlich ABSICHTLICH nur noch auf POSIX-Kommandos in den Shell-Skripten (zumindest in der neuen Version im gesonderten Branch), denn dann funktioniert das einigermaßen unabhängig von Modell und Architektur der Boxen (zumindest was die Byte-Order und den Prozessor angeht) und es müssen nicht zusätzlich noch gesonderte Binaries "verwaltet" werden.
Ich wäge das mal noch etwas ab, wie man es am besten umsetzt ... sollten sich noch weitere Infos finden lassen (u.a. die o.a. Liste der Applet und vielleicht auch mal ein eigener Versuch mit dem o.g. Einsatz von Pipes für den Shell-Interpreter, damit ich weiß, ob
mknod ... p
funktioniert), nehme ich die auch gerne, denn das beeinflußt dann die Entscheidung natürlich auch.