{"id":16714042,"url":"https://github.com/therealdreg/ftdibrick","last_synced_at":"2025-10-14T23:18:30.877Z","repository":{"id":239554241,"uuid":"788919994","full_name":"therealdreg/ftdibrick","owner":"therealdreg","description":"FTDI bricker just for fun - malware POC+hardware hacking CTF","archived":false,"fork":false,"pushed_at":"2024-09-23T11:31:56.000Z","size":10495,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-13T20:49:02.179Z","etag":null,"topics":["brick","bricker-breaker","freebsd","ftdi","ftdi-232h","ftdi-232r","ftdi-chip","ftdi-devices","ftdi-eeprom","linux","poc","windows"],"latest_commit_sha":null,"homepage":"https://rootkit.es/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/therealdreg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"publiccode":null,"codemeta":null},"funding":{"github":["therealdreg"],"patreon":"dreg","custom":["https://www.paypal.me/therealdreg","https://www.paypal.me/therealdreg"]}},"created_at":"2024-04-19T10:52:16.000Z","updated_at":"2024-10-08T08:40:42.000Z","dependencies_parsed_at":"2024-08-16T04:54:03.829Z","dependency_job_id":null,"html_url":"https://github.com/therealdreg/ftdibrick","commit_stats":null,"previous_names":["therealdreg/ftdibrick"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealdreg%2Fftdibrick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealdreg%2Fftdibrick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealdreg%2Fftdibrick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therealdreg%2Fftdibrick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/therealdreg","download_url":"https://codeload.github.com/therealdreg/ftdibrick/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221818878,"owners_count":16885846,"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":["brick","bricker-breaker","freebsd","ftdi","ftdi-232h","ftdi-232r","ftdi-chip","ftdi-devices","ftdi-eeprom","linux","poc","windows"],"created_at":"2024-10-12T20:48:58.986Z","updated_at":"2025-10-14T23:18:30.800Z","avatar_url":"https://github.com/therealdreg.png","language":"C","funding_links":["https://github.com/sponsors/therealdreg","https://patreon.com/dreg","https://www.paypal.me/therealdreg"],"categories":[],"sub_categories":[],"readme":"# `FTDIBRICK`\n@FTDIChip How dangerous do you consider it that a non-admin user running a user-space program can communicate with the FTDI driver, program the EEPROM, and brick it? Does that seem normal to you?\n\nWe made some POC's to brick the original FT232R when it doesn't use an external clock (almost all boards, right?) FreeBSD+Windows+Linux. On Windows from non-admin user. The unique way to reverse this is to solder a proper 12Mhz clock to the OSCO and OSCI pins of the chip:\n\n![buspirate](assets/media/buspirate.jpeg)\n\nProject by https://github.com/S0S4 \u0026 https://github.com/therealdreg\n\n---\n\n# WHAT IS FTDI?\n\nFTDI is a semiconductor company. It is heavily known for it's USB-UART chips (FTDI 232R, FTDI 245R ...) among other stuff like the well known USB MPSSE Cable Series (CH232HM) etc.\n\n# FTDI DRIVER BRICKING FAKE CHIPS\nBack in 2014 FTDI, manufacturers of the most popular USB to serial conversion chip, **released an update to their drivers that bricked FTDI fakes**. These fakes were extremely common in the supply chain, even if you bought a cheap arduino you probably have one of this fake chips. When you buy electronics, you don't know if the chips they are using are original or not. This new driver could break their new stuff! Even for advanced users, detecting if a FTDI chip is fake or not can be a jigsaw puzzle.\n\nFTDI was heavily criticized because of this. Not only for refusing to talk to counterfeit chips, but for deliberately bricking the chinese fakes without a clear announcement (They advised the bricking of counterfeit chips in the Terms and Conditions, which was tucked away inside the driver file). After the critics they backed off and proceed with a new idea, this driver was eliminated from Windows update.\n\n![term](assets/media/termsandcoditions.png)\n\nWeeks later, After a CEO statement, they launched the `ftdi-gate v2.0` a new driver that will inject garbage data into the fake chip so the Windows FTDI driver will output \"NON GENUINE DEVICE FOUND\" and will refuse to talk to the chip.\n\n![ceostatement](assets/media/ftdiceomsg.png)\n\n### How FTDI brick devices?\nEvery USB device has a pair of IDs. One, the Vendor ID (VID), which is given by the [USB Group](https://usb.org/). The second is a Product ID, allocated by the vendor, with each distinct chip type having its own PID. Windows uses this VID/PID to figure out which driver the hardware needs. This fake chips uses the FTDI VID and set the PID to the PID of the chip they are cloning.\n\nBack in 2014, the driver was on Windows update, when you connected your fake FTDI into Windows, It will start downloading the latest driver for the FTDI, in this case, the bricker driver.\n\nWhat this driver did was to reprogram the EEPROM of this counterfeit chips and set the PID to 0000. This PID does not match with any FTDI part, so Windows drivers no longer recognize the chip. As the PID is on the EEPROM, the programming to 0000 is persistent.\n\n### Diving deep\nWe have superficially explained how the brick process work, but let's get our hands dirty and go a bit deeper.\n\nThe user [marcan](https://marcan.st) reverse engineered the FTDI driver. The source code of the brick was kind of clever, the code exploits the differences found in the silicon of the counterfeit chips compared to the legit ones.\n\n![ftdidriver](assets/media/driverftdi.png)\n\nThe eeprom needs to be written in 32-bit units, writes to even addresses are buffered and writes to odd addresses writes the 32 bits at once, the 16 buffered bits and the supplied 16 bits. The function does a 16 bit time transfer, on an official FTDI you need to write the EEPROM sequentially by writing 32 bits at a time, so, when using this function on an official FTDI you will send the first 16 bits to a buffer then buffer other 16 bits and then writing to the eeprom, meanwhile, the counterfeit FTDI's issues 16-bit writings (following the documentation on FTDI this should be the case for official FTDI, but the clones implemented the command interface better than FTDI, kind of hilarous).\n\nFor the checksum they did something smart, they don't create a new checksum and write it on the FTDI,**but find the value required to make the existing checksum match and write it on the previous address to the checksum**\n\n---\n\n## Windows\n\nFor Windows we decided to use their driver as it let us brick the chip without administrator privileges.\n\nsrc/windows_ftdibrick -\u003e Assembly POC tested and fully working\n\nsrc/ftdibrickerd2xx\n\nsrc/ftdibrickerd2xx_static\n\nsrc/ftdibrickwin32_dreg_zadig_winusb -\u003e POC for using with zadig, WinUSB\n\nsrc/ftdibrickwin32_dreg_devicecontrol\n\n(Dreg's note about devicecontrol: I've only been with the debugger and IDA for a few hours! But the communication part of the driver works... None of this is documented on the internet or public ;-D)\n\n## FreeBSD\n\nsrc/main.asm\n\nsrc/freebsd_dreg\n\n## Linux\n\nsrc/fedora_ftdibrick\n\nsrc/libusb_ftdibrick -\u003e POC using LibUsb for a generic linux FTDI brick!\n\n# FTDI EXTERNAL OSCILLATOR\n\nFT232R and FT245R devices have an integrated oscillator to simplify USB designs and reduce component count. When the internal oscillator is enabled, both the `OSCI` and `OSCO` pins are disconnected from the signals internally to the chip. After the use of `FTDIBRICK` we are making the FTDI chip to use an external clock connected to OSCI and OSCO pins and so disabling the internal oscillator, making the chip useless as there is no external oscillator.\n\n# HOW DOES FTDIBRICK WORKS?\n\nFor the sake of simplicity, I'll be explaining how the POC's work without deepening in the OS used.\n\nFirst we search for our FTDI to brick by doing a look-up of the devices using `open()`, iterating through the devices and calling `ioctl(fd, USB_GET_DEVICEINFO, \u0026buffer)` until we find the VID and PID that correspond to the FTDI232R (0x04036001), if you change the VID and PID for the one on the FT245R code should also work, we didn't test nor investigated about it.\n\nOnce we find our vulnerable FTDI, we start our brick sending some USB packets to the device:\n\n#### USB PACKETS\nFor bricking the FTDI Chip we need to overwrite the EEPROM configuration, before writing we must send three USB packets for the correct writing process:\n\n* RESET: Reset both RX and TX buffer\n\n![resetpcap](assets/media/resetpcap.png)\n\n* POLL MODEM: Get poll modem status info\n\n![pollmodem](assets/media/pollmodem.png)\n\n* LATENCY: Set latency (When latency is set to 0x77 it allows you to write without any issue, if you try to write without this packet the whole eeprom will become 0xFF)\n\n![latencypcap](assets/media/latencypcap.png)\n\nWe send this USB packets via `ioctl()`:\n\n#### IOCTL SYSCALL FREEBSD/LINUX\n\nThe ioctl syscall sends two or more arguments, depending on the ioctl request you send. In our case, we send three arguments because of `USB_GET_DEVICEINFO` :\n\n* The address of a buffer\n\n* Request type\n\n* File descriptor\n\n![ioctl](assets/media/ioctl.png)\n\nYou may be wondering what the hell is 0x41705570?\n\n0x41705570 it's the `USB_GET_DEVICEINFO` packet with all the information ioctl needs to know for doing the work.\n\nThis is the structure of ioctl() packets.\n```\n        31   29 28                     16 15            8 7             0\n *\t+---------------------------------------------------------------+\n *\t| I/O | Parameter Length        | Command Group | Command       |\n *\t+---------------------------------------------------------------+\n```\n31 - 29 bits: Defines whether you copy parameters in, or you copy them out, in our case the value of these bits is: 0b100\n\n28 - 16 bits: Basically defines the buffer size ioctl needs to work, in this case, 0x170\n\n15 - 8 bits: Represent the command group, in this case is 0x55 which in ascii is the character 'U', this specifies that the command group is for USB protocol\n\n7 - 0 bits: Simply the command, in this case is 0x70 (112 in decimal), in this case USB_GET_DEVICEINFO:\n\n![define](assets/media/define.png)\n\nAs you can see, ioctl() requests has cool stuff, and so we made a deserializer for you to see the packet more clear, you can find it on `stuff/serializer`.\n\n#### WRITING THE BRICK\n\nOnce we send the three USB packets seen before, we are ready to write to the eeprom, basically we iterate through the contents of our `bad_eeprom` so that a word is written to the eeprom for each iteration (remember we have to write 16 bits in 16 bits), the checksum is included on the variable.\n\n#### Delta Offset\n\nWe used an old technique called `delta offset` in which basically we can use EBP as a base offset and to allow data without breaking anything, because of this we can use the POC's as shellcodes if we want to.\n\nDISCLAIMER: On Linux you need to run the process as root to execute the POCs!\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherealdreg%2Fftdibrick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftherealdreg%2Fftdibrick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherealdreg%2Fftdibrick/lists"}