{"id":13463809,"url":"https://github.com/seemoo-lab/frankenstein","last_synced_at":"2025-04-05T04:13:49.087Z","repository":{"id":43808909,"uuid":"254191670","full_name":"seemoo-lab/frankenstein","owner":"seemoo-lab","description":"Broadcom and Cypress firmware emulation for fuzzing and further full-stack debugging","archived":false,"fork":false,"pushed_at":"2024-02-07T21:31:59.000Z","size":10428,"stargazers_count":442,"open_issues_count":8,"forks_count":65,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-03-29T03:09:12.663Z","etag":null,"topics":["arm","bluetooth","broadcom","cypress","heap","qemu","threadx"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seemoo-lab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-04-08T20:19:06.000Z","updated_at":"2025-03-04T18:06:03.000Z","dependencies_parsed_at":"2024-01-14T17:04:32.398Z","dependency_job_id":"dabb2b63-1fb5-45be-87cf-a6d8156c7b1a","html_url":"https://github.com/seemoo-lab/frankenstein","commit_stats":{"total_commits":73,"total_committers":5,"mean_commits":14.6,"dds":0.5205479452054795,"last_synced_commit":"9b955a7f9de63f0c6d6b6913ee9392ebc0d25c14"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seemoo-lab%2Ffrankenstein","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seemoo-lab%2Ffrankenstein/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seemoo-lab%2Ffrankenstein/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seemoo-lab%2Ffrankenstein/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seemoo-lab","download_url":"https://codeload.github.com/seemoo-lab/frankenstein/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284951,"owners_count":20913704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arm","bluetooth","broadcom","cypress","heap","qemu","threadx"],"created_at":"2024-07-31T14:00:28.848Z","updated_at":"2025-04-05T04:13:49.065Z","avatar_url":"https://github.com/seemoo-lab.png","language":"C","readme":"![alt text](doc/images/logo.jpg)\n\n*Frankenstein* provides a virtual environment to fuzz wireless firmwares.\nFirmwares can be hooked during runtime to extract their current state (i.e., `xmitstate` through *InternalBlue*).\nThen, they can be re-executed in a virtual environment for fuzzing.\nTo do so, the firmware image needs to be reassembled to an ELF file that can be\nexecuted with QEMU. The firmware image reassembly is simplified by a web-based UI.\n \n*Frankenstein* is currently optimized for the *CYW20735* Bluetooth evaluation board. \nThe slightly newer *CYW20819* Bluetooth evaluation board is already partially supported.\nThe port to the *CYW20819* evaluation board is required due to [CVE-2019-18614](doc/CVE_2019_18614.md), \nwhich prevents further fuzzing of connection states such as music streaming or tethering.\nWe are working on support for the *Samsung Galaxy S10/S20*—all of the European *S10e/S10/S10+/Note 10/S20* models\nfeature the same chip.\nIf you already have symbols for one chip but are missing symbols for a chip that had similar compiler options,\nyou might find using [Polypyus](https://github.com/seemoo-lab/polypyus) before running BinDiff helpful.\n\n\nTable of Contents\n------------\n *  Getting Started\n    * [Basic Setup](#basic-setup)\n    * [Attach Firmware to Host](#attaching-the-firmware-to-a-host)\n    * [Reproducing CVEs](#reproducing-cves)\n    * [Custom Firmware States](#dumping-custom-states)\n    * [Heap Sanitizer](#live-heap-sanitizer)\n    * [Dependencies](#important-notes--dependencies)\n    * [Start Your New Project](doc/projects.md)\n\n *  Vulnerabilities\n    * [ThreadX Heap Exploitation](doc/heap.md)\n    * [EIR RCE Exploit (CVE-2019-11516)](doc/CVE_2019_11516.md)\n    * [LE Heap Overflow  (CVE-2019-13916)](doc/CVE_2019_13916.md)\n    * [Device to Host and Host to Device Buffer Misconfiguration (CVE-2019-18614)](doc/CVE_2019_18614.md)\n    * [BlueFrag (CVE-2020-0022)](https://insinuator.net/2020/04/cve-2020-0022-an-android-8-0-9-0-bluetooth-zero-click-rce-bluefrag/) - Fixed in the Android February 2020 release. Look at our ACL [fuzzer](projects/CYW20735B1/patch/aclfuzz.c).\n\n  * Miscellaneous\n    * Master [Thesis](doc/Thesis.pdf) by Jan Ruge\n\n\nBasic Setup\n------------\n\nThis tool contains a web-based UI to configure the build.\nThis includes management of symbols and memory dumps.\nThe Makefile and linker scripts are generated automatically by the build system.\nThe build system can be launched by the following command and navigating the browser to [http://127.0.0.1:8000/](http://127.0.0.1:8000)\n\n\n    python3 manage.py runserver\n\n\n\nThe build system already contains symbols and an initial memory dump. You can browse through the available projects\nand the dump without having the actual hardware, *IDA Pro* or *Ghidra* database, etc. Symbols are truncated to the first 1k\nsymbols, so do not worry if something you know does not show up in the list immediately.\n\n\nEach firmware version is located in a different project stored in `projects`.\nA project contains the file `project.json`, which holds the symbol names and the memory layout including memory dumps.\nThe available symbols can be used to generate patches in C as well as for firmware emulation.\nTo build all patches and emulators for the *CYW20735* evaluation board run:\n\n\n    make -C projects/CYW20735B1\n\n\nIn general, having the project built is sufficient to run emulation with QEMU. However, for fuzzing it can\nbe quite interesting to hold the firmware at a different state and continue fuzzing from there. So, if you currently\ndo not have any of our supported hardware, you can skip the `xmitstate` step later.\n\nAfter rebuilding the project using `make -C projects/CYW20735B1`, the firmware state can be emulated, until the `Idle` thread is entered.\nFor this, execute:\n\n    qemu-arm projects/CYW20735B1/gen/execute.exe\n\nOr execute it from the web frontend and get even more insights:\n\n![alt text](doc/images/webui.png)\n\nAttaching the Firmware to a Host\n---------------------------------\n\nThe basic `execute.exe` ELF file does not communicate to the outside world. Thus, it terminates in the\n`Idle` thread. However, for fuzzing the firmware, it needs to be attached to a real host and obtain random\n\"wireless\" inputs.\n\nWe provide an additional patch in `hci_attach.exe` that abstracts the calling conventions for the *Bluetooth Core Scheduler (BCS)*.\nThe BCS normally takes inputs from the hardware registers that contain decoded packets from the physical layer.\nWe replace the invocation of the interrupt handler `bluetoothCoreInt_C` that calls the BCS every 312.5µs (1/2 Bluetooth clock cycle).\nThis interrupt handler is now reading data from standard input (STDIN) of the *Linux* host.\nYou can feed arbitrary inputs, i.e., data from `/dev/urandom`.\n\n    cat /dev/urandom | qemu-arm projects/CYW20735B1/gen/hci_attach.exe\n\nNote that `hci_attach.exe` also calls the `btattach` command on the host, which is part of the *Linux Bluez* Bluetooth\nstack. Once you run this file, your host will have a new Bluetooth device. You can list the current devices\nwith `hciconfig`. The hook to pass UART data from the emulated device to the *Linux* host is installed in the\nfirmware functions `uart_directWrite` and similar functions.\n\n\nDepending on the host's exact behavior, you might need to reset the chip immediately after starting QEMU.\nOtherwise, emulation will get stuck or segfault. On a current (September 2019) Debian testing, this is not\ndone automatically by the host and can be done manually as follows:\n\n    hcitool -i hci1 cmd 0x03 0x03\n        \u003c HCI Command: ogf 0x03, ocf 0x0003, plen 0\n        \u003e HCI Event: 0x0e plen 4\n          01 03 0C 00 \n\n    \nAfter successful reset, the emulation keeps running, which means that you will see a lot of output within\nshort time on the terminal that started the `hci_attach.exe`.\nNow you can start actions on the host that cause interaction with the emulated Bluetooth firmware.\nFor example, you can scan for Bluetooth LE devices:\n\n    hcitool -i hci1 lescan\n\nIf you open Wireshark while doing so, you will notice a lot of weird and invalid packets. Nonetheless,\nthe scanning output will show a lot of devices with random addresses within short time,\nwith some of these even returning mal-formatted names.\n\nReproducing CVEs\n----------------\n\nTo trigger [CVE-2019-11516](doc/CVE_2019_11516.md), run `hcitool -i hci1 scan` and wait a couple of seconds to minutes.\n\n    Context switch idle -\u003e lm\n    lr=0x02d12f lm_handleInqFHS(0x40)lr=0x02cc53 lc_handleInqResult(0x21fb1c)lr=0x041d91 inqfilter_isBdAddrRegistered(0x21fb24, 0x0);\n    lr=0x041dc3 inqfilter_registerBdAddr(0x21fb24, 0x0);\n    lr=0x041dfb bthci_event_SendInquiryResultEvent(0x21fb1c)lr=0x024e49 dynamic_memory_AllocateOrDie(0x19)Heap Corruption Detected\n    pool = 0x20d368\n    pool-\u003esize = 0x0180\n    free_chunk = 0x221c04\n    7f7fb0c9 | a3e4b4aa4242424242424242424242424242424242424242424242424242424242424242\n        4242424242424242424242424242424242424242424242424242424242424242424242424242424\n        2424242424242424242424242424242424242424242424242424242424242424242424242424242\n        4242424242424242424242424242424242424242424242424242424242424242424242424242424\n        2424242424242424242424242424242424242424242424242424242424242424242424242424242\n        4242424242424242424242424242424242424242424242424242424242424242424242424242424\n        2424242424242424242424242424242424242424242424242424242424242424242424242424242\n        4242424242424242424242424242424242424242424242424242424242424242424242424242424\n        2424242424242424242424242424242424242424242424242424242424242424242424242424242\n        4242424242424242424242424242424242424242424242424242424242424242\n    qemu: uncaught target signal 11 (Segmentation fault) - core dumped\n\nFor debugging purposes, our heap sanitizer is currently writing `0x42` to released memory.\n \n\nNow let's trigger [CVE-2019-13916](doc/CVE_2019_13916.md). As this vulnerability is within parsing of BLE PDUs,\nall you need to do is to successfully establish a connection to another LE device. If you\nconnect to random addresses, this will succeed at some point in time. Usually, this takes \na couple of minutes and in some cases the emulator crashes instead and you need to restart\nthe emulation. Be patient!\n\n    while true; do hcitool -i hci1 lecc ca:fe:ba:be:13:37; done\n    \nThis results in:    \n\n    lr=0x08ee3d bcsulp_getPktLength(0x854cfecd, 0x0) = 0xfe;\n    lr=0x08ed33 bcsulp_getPktLength(0x05, 0x0) = 0x0;\n    lr=0x08ec11 bcsulp_getPktLength(0x05, 0x0) = 0x0;\n    lr=0x08ebc1 dhmulp_getTxBuffer(0x281704, 0x1b, 0x0148001b);\n    lr=0x041e95 bcsulp_getPktLength(0x854cfecd, 0x0) = 0xfe;\n    lr=0x08f115 bcsulp_procRxPayload(0x281618, 0x854cfecd)lr=0x08e9c3 bcsulp_getPktLength(0x854cfecd, 0x0) = 0xfe;\n    lr=0x08ea2f bcsulp_getPktLength(0x854cfecd, 0x0) = 0xfe;\n    lr=0x08ea4b utils_memcpy8(0x2232d0, 0x370c00, 0xfe)Heap Corruption Detected\n    pool = 0x20d38c\n    pool-\u003eblock_start = 0x2232c0\n    pool-\u003ecapacity = 0x0f\n    pool-\u003esize = 0x0108\n    free_chunk = 0x1010a9a8\n\n    qemu: uncaught target signal 11 (Segmentation fault) - core dumped\n\n\n\nDumping Custom States\n---------------------\n\nTo dump a custom state, the most important patch is `patch/xmit_state.h`.\nIt generates re-executable firmware states.\nIt is used in a custom *InternalBlue* extension `internalBlueMod.py`.\nIf you are running on a native *Linux* and want to access the raw HCI device,\nyou need superuser rights.\n\n    (sudo) python3 internalBlueMod.py\n\nIn this extension, we can run the following command to generate a re-executable state:\n\n\n    \u003e xmitstate target_function\n\nDepending on the target function, this might crash sometimes. Just try again.\nOnce you successfully dumped a state, *InternalBlue* will finish with \n\n    [*] Received fuill firmware state\n    \nIf the firmware crashes afterwards, you can ignore this.\n\n\nNow, reload the web UI running on [http://127.0.0.1:8000/](http://127.0.0.1:8000/).\nIt will list your new dump in the *Segment Groups* view, i.e., `internalBlue_09.24.2019_18.32.09`.\nThe most recent dump will automatically be set to the *Active* state. You can now build the project\nagain.\n\n\nIf you were running *InternalBlue* with `sudo`, you might need to adjust access rights to the\ngenerated state. To do so, run:\n\n    sudo chown -R $USER:$USER projects/CYW20735B1/segment_groups/\n\nNow, build the project again:\n\n    make -C projects/CYW20735B1\n    \n\nLive Heap Sanitizer\n-------------------\n\nRun our customized *InternalBlue* script on real hardware:\n\n    (sudo) python3 internalBlueMod.py\n    \nLoad the heap sanitizer patch on top:\n\n    \u003e loadelf projects/CYW20735B1/gen/heap_sanitizer.patch\n    \nNow you will get detailed output about heap violations, i.e., caused by `memcpy` and the function\nwhich called it. Depending on what you debug, you might need to adjust the definitions in `patch/heap_sanitizer.c`.\n\n\n\n\n\nImportant Notes \u0026 Dependencies\n------------------------------\n\n*Frankenstein* depends on *InternalBlue*. Projects must be named by the chip descriptions in the *InternalBlue*\nfirmware files. For example, `internalblue/fw/fw_0x4208.py` contains the firmware for the *CYW20735* evaluation\nboard and contains the identifier `FW_NAME = \"CYW20735B1\"`. Thus, the *Frankenstein* project name is `CYW20735B1`.\n\nFor QEMU, you need to install the `qemu-user` package.\nCompilation of the project requires `gcc-arm-none-eabi`.\n\n    apt install qemu-user gcc-arm-none-eabi gcc-multilib\n\nTested with `qemu-user (1:3.1+dfsg+8+deb10u2)` and `gcc-arm-none-eabi (15:7-2018-q2-6)` and `gcc-multilib (4:8.3.0-1)`. \n\nThe following Python 3 packets are required:\n\n    pip3 install django pyelftools==0.24\n    \nTested with `django-1.11.24`.\n\nWe thank Anna Stichling for creating the *Frankenstein* logo.\n\n","funding_links":[],"categories":["C","\u003ca name=\"bluetooth_security_tools\"\u003e\u003c/a\u003eBluetooth Security Tools","Tools"],"sub_categories":["Firmware Analysis","Fuzzing Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseemoo-lab%2Ffrankenstein","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseemoo-lab%2Ffrankenstein","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseemoo-lab%2Ffrankenstein/lists"}