{"article":{"slug":"keyless-entry-hacking-switchbot-smart-locks","title":"Keyless Entry: Hacking SwitchBot Smart Locks","subtitle":null,"summary":"Neodyme's security team reverse-engineered the SwitchBot Lock Pro and found several vulnerabilities, the worst a misuse of AES-CTR in its Bluetooth protocol that lets anyone nearby silently unlock the door in a software-only attack. The write-up walks through the firmware analysis, the attacks, disclosure, and the fixed firmware and app versions.","content_type":"research","language":"en","canonical_url":"https://neodyme.io/en/blog/switchbot","author":{"name":"Neodyme security team","url":null,"person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Neodyme","url":"https://neodyme.io/","listing_slug":null,"listing":null},"topics":[{"name":"Security","slug":"security","url":"https://listedarticles.com/topics/security"},{"name":"Hardware","slug":"hardware","url":"https://listedarticles.com/topics/hardware"},{"name":"IoT","slug":"iot","url":"https://listedarticles.com/topics/iot"}],"about_listings":[],"cover_image_url":null,"license":"all-rights-reserved","word_count":2293,"reading_minutes":10,"published_at":"2026-10-26T00:00:00.000Z","added_at":"2026-10-27T11:12:33.655Z","updated_at":"2026-10-27T11:12:33.655Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/keyless-entry-hacking-switchbot-smart-locks","markdown_url":"https://listedarticles.com/articles/keyless-entry-hacking-switchbot-smart-locks.md","example":false,"citation":"Neodyme security team, Neodyme. \"Keyless Entry: Hacking SwitchBot Smart Locks.\" 26 Oct 2026. https://neodyme.io/en/blog/switchbot (all-rights-reserved)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://neodyme.io/en/blog/switchbot"},"body_markdown":"# Keyless Entry: Hacking SwitchBot Smart Locks\n\n*Tobias, Aaron, Justin and Ruben · Neodyme · October 26, 2026*\n\n## TL;DR\n\nWe’ve identified multiple vulnerabilities in devices of the popular [SwitchBot](https://eu.switch-bot.com/) Lock Pro smart lock series.\nThe most critical, a cryptographic flaw in their bluetooth communication, allows everyone to silently open smart locks in a software-only attack.\nNo physical tampering is required.\nBelow is a video of the attack in action.\n\n## Introduction\n\nSmart locks have become very popular in recent years.\nEspecially when it comes to AirBnB-style apartment sharing, but also in corporate environments and private accommodation, people enjoy having locks that don’t require physical keys.\nSo when it came to selecting targets for our regular IoT hacking team event, smart locks were a natural choice.\n\nAfter some research we cam across the highly praised [Switchbot Lock Pro Combo](https://www.amazon.de/Lock-Pro-Touch-Fingerprint-Matter/dp/B0CR67GWML/?), including a key actuator, pin pad and smartphone app.\nIt is one of the best-rated and most-sold smart locks on Amazon.\nFor roughly 240€ (at the time of writing) it comes with a lot of features - and the Amazon reviewers are happy to share that it works as intended.\n\nFeatures aside, our main interest was, of course, the device’s security.\nSo we ordered one and had a look.\nHere is what we found out.\n\n## Reversing the Lock\n\nAs usual when inspecting IoT devices, we wanted to get our hand on the firmware.\nBut before we dive into that, let’s first look into the target’s features and architecture.\n\n### The Switchbot Pro Lock\n\nThe bundle comes with two hardware devices, an actuator and a key pad. The lock can further be controlled and configured via a smartphone app.\n\n![Switchbot Pro Lock Bundle on Amazon](https://neodyme.io/blog/switchbot/switchbot_amazon.png)\n\nSwitchbot Pro Lock Bundle on Amazon\n\nThe actuator is mounted onto the inside of the door and encloses the door’s key.\nWhen the door is supposed to open, the actuator simply turns the key in the lock.\n\n![Switchbot Pro Lock Actuator Promotional Material](https://neodyme.io/blog/switchbot/actuator.jpg)\n\nSwitchbot Pro Lock Actuator Promotional Material\n\nThe key pad is kept outside the door and communicates with the actuator over [Bluetooth Low Energy](https://de.wikipedia.org/wiki/Bluetooth_Low_Energy) (BLE).\nA person can authenticate itself to the system either using a smart card/key fob, using a fingerprint, or - most commonly - by supplying a PIN.\nThe whole system can also be added to a WiFi network, making it possible to control the lock over the Internet.\n\nNow that we have an idea of the feature set, we can start digging.\n\n### Firmware Reversing\n\nWhen hacking a device, it is usually a good idea to first get your hands on its firmware.\nThere are various techniques for accomplishing this, [FLASH Dumping](https://neodyme.io/en/blog/drone_hacking_part_1/) for example.\nBefore starting to desolder chips, however, it makes sense to scrape the web for firmware artifacts.\n\nWith SwitchBot we got lucky, as the Android app contained the URL for a public S3 bucket containing firmware files.\nDownloading and analysing these files we found two surprising architectural choices.\nFirst, the key pad on the **outside** of the door actually controls the actuator on the **inside**, not the other way around.\nMeaning that the key pad decides if a PIN, fingerprint or key fob is valid and then issues an “UNLOCK” command to the actuator.\nSecondly, the communication between the key pad and actuator relies on an unprotected, clear-text BLE connection.\nAuthentication between key pad and actuator is done solely on the application level using a home-brewed mechanism.\n\nWhile the first point already yields a significant attack surface (i.e. let’s dump the key pad and open the door), the second offers a code smell too good to pass up.\nSo we focussed our main energy on exploiting the BLE communication between key pad and actuator.\n\n### Key Pad Communications\n\nOnce the key pad and actuator are paired, they communicate using unprotected BLE.\nMeaning that all security of the system depends on application-level protections.\nSo let’s find out how these protections work.\n\nUpon pairing, the key pad and actuator agree on a *secret key*.\nThen, everytime the key pad becomes active, it requests a so-called “[nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)” value from the actuator.\nFor our attack this does not matter.\nIt is noteworthy however, that the nonce is supposed to provide “freshness” between invocations of the protocol but that this implementation uses the same nonce for an entire “session” which can last for multiple commands.\nAfter the nonce is received, the key pad encrypts a command, using the secret key and nonce, and sends said command over the BLE connection.\nSuch a command could, for example, be “lock the door”.\n\nThe following diagram illustrates how the BLE communication works.\n\n![Communication between key pad and actuator (simplified)](https://neodyme.io/blog/switchbot/Comms_Switchbot.png)\n\nCommunication between key pad and actuator (simplified)\n\nSimply by looking at the communication diagram we can see a potential problem: We might be able to simply replay previous “unlock” commands that we have captured.\nHowever, that would require us to be within Bluetooth range, sniff the command, and then somehow replay it before the session ends.\nSince we aren’t writing an academic paper but do actual research: This is boring.\n\n**We want to be able to open the lock, first shot, without any physical tampering and without leaving traces.**\n\nAnd, as it turns out, we can accomplish this. But first need some more background on the implementation.\n\n### Communication Protection\n\nSo the key pad/actuator communication is protected using secret-key encryption and a nonce.\nDigging further into the implementation, and with the help of [community-developed libraries](https://github.com/jonghwanhyeon/python-switchbot), we found out how the encryption is done.\n\nThe commands are encrypted using the [AES](https://de.wikipedia.org/wiki/Advanced_Encryption_Standard) block cipher in counter (CTR) mode.\nNow, counter mode is an interesting choice, because it doesn’t actually offer any integrity protection.\nFurthermore, because of its design, turning a block cipher into a stream cipher, bit flips propagate 1:1 from ciphertext to plaintext.\n\n![Counter mode encryption](https://neodyme.io/blog/switchbot/CTR.png)\n\nCounter mode encryption\n\nMeaning that: If we change a bit in a ciphertext, upon decryption by the actuator, this exact bit will also be changed in the decrypted plaintext.\nThis is a little-known, but often encountered vulnerability class.\nSo, let’s exploit this fact and open some doors!\n\n## Exploiting the Lock\n\nA key observation helps us to mount our attack.\nThe key pad’s lock button always sends an encrypted LOCK command, even if the door is already locked.\nExploiting the fact that AES CTR is used, we only need to compute the difference between an encrypted LOCK and UNLOCK command.\nWhen we XOR this difference (flipping all corresponding bits) into an encrypted LOCK command, the result will be a validly encrypted UNLOCK command.\nIt’s important to note here that this difference has to be computed only once, as it is identical across sessions and devices!\nWe therefore split the attack into a setup phase, run once, and an attack phase that opens a specific lock.\n\nAfter the one-time setup, the attack works as follows:\n\n- Press the lock button\n- Sniff an encrypted LOCK command send via BLE\n- Bit-flip the encrypted LOCK command into an encrypted UNLOCK command\n- Send the bit-flipped command to the actuator\n- The door opens\n\nAs we suspect a lot of vulnerable devices out there, we won’t publish our full exploit here.\nBut using an individual example, you can see why our attack works.\nSo, let’s work through it.\n\n### Setup Phase\n\nUsing one pair of encrypted LOCK and UNLOCK commands, intercepted via BLE, we can compute their XOR difference.\nThis difference is identical across all sessions and all locks using the same firmware.\nTherefore, we can use this difference as a sort of “master key” to open all SwitchBot Pro locks.\n\nSniffing an encrypted LOCK and UNLOCK command is done easily using our acquired lock.\nThen, we simply compute:\n\n```\ndiff = ENCRYPTED_LOCK_COMMAND ^ ENCRYPTED_UNLOCK_COMMAND\n```\n\n### Attack Phase\n\nApplying (XORing) this difference `diff` to the encryption of any LOCK command, independent of secret key and nonce, will yield an encrypted unlock command, which we can then send to the actuator.\n\n```\nCRAFTED_ENCRYPTED_UNLOCK = ENCRYPTED_LOCK ^ diff\n```\n\nSo, simply by applying our pre-computed, lock-independent, difference vector, we can turn *every* SwitchBot Pro LOCK command into an UNLOCK command.\nAnd we can always capture encrypted LOCK commands on any key pad, simply by pressing the lock button.\nNeat!\n\n### Proof of Concept Exploit\n\nWe’ve recorded our attack in action.\nThe video shows the components and our Bluetooth antenna used for sniffing the encrypted LOCK command.\nOn the left you can see the Python script applying the difference to the encrypted LOCK command and sending the crafted encrypted UNLOCK command.\nThe right side of the screen shows that the attack worked:\nFirst, a LOCK command is issued by pressing the lock button.\nThen, the crafted UNLOCK command is send and the actuator turns the key, opening the door `\\o/`.\n\nIt all happens very fast, so maybe you have to re-watch a couple of times to grasp everything.\n\n### Responsible Disclosure and Insufficient Fix\n\nIn accordance with our responsible disclosure guidelines, we notified the SwitchBot team of our findings.\nThey were very responsive (kudos!) and seemed to take the vulnerability seriously.\nThey awarded us a 100€ Amazon voucher for our work.\n\nBefore they rolled out a firmware patch, they allowed us to have a look at the updated firmware files.\n\nAfter we reversed the new firmware, we discovered that they now append a “checksum” to every command.\nWe reimplemented the checksum computation in Python:\n\n```\ndef calculate_checksum(command, key, nonce):\n\ndata_to_hash = command.encode('utf-8') + key.encode('utf-8') + nonce.encode('utf-8')\n\nhash_object = hashlib.md5(data_to_hash)\n\nfull_hash_bytes = hash_object.digest()\n\nreturn full_hash_bytes[:2]\n\nfull_command = COMMAND_UNLOCK + calculate_checksum(COMMAND_UNLOCK, self._encryption_key, self._nonce)\n\nsend_encrypted_bluetooth_command(full_command)\n```\n\nSo the system now calculates an MD5 hash of the command, secret key and nonce.\nThe first **two bytes** of this hash then serve as verification tag.\nThis construction is sometimes referred to as [YOLO hash](https://blog.trailofbits.com/2024/08/21/yolo-is-not-a-valid-hash-construction/) and rarely a good idea.\nHere in particular, the truncation to two bytes allows us to, in principle, brute force all 65,536 possible verification tags.\nHowever, this is not necessary.\n\nBecause, to our surprise, just the communication between the key pad and actuator got updated.\nThe smartphone app still does not use a verification tag.\nWhich means that our attack still works 1:1, we just need to compute (once!) the difference between a key pad’s encrypted LOCK command and a smartphone issued UNLOCK command.\nWe can then mount our attack using this difference vector, as the actuator then thinks the UNLOCK command comes from a smartphone and does not check the verification tag.\nWe have verified that this variant of our attack works.\n\nWhen we reported this bypass, SwitchBot provided the following context:\n\n> The test firmware pushed to you only includes updates for the Keypad and Lock. The APP has not yet been updated with the new encryption method. We are currently working on implementing encryption upgrades for both the APP and the backend, and the Lock will no longer be compatible with the old encryption method. We need to ensure that this update does not affect other products bound to the APP […].\n\nBackward compatibility is always challenging, especially when it comes to security and IoT devices out in the field.\n\n## Further Attack Surface\n\nAs we were happy with our full compromise, we did not look too much into other avenues of attack.\nNoteworthy, however, was that the key pad uses MIFARE Classic 1K key fobs.\nThese are long broken and can be trivially cloned, e.g., using a [Flipper Zero](https://flipper.net/).\nIn order to mount this cloning attack, you’d have to get close to a key fob first.\n\nAdditionally, while testing the Bluetooth attack, we noticed that the key pad has a tamper detection.\nIf it is removed from the wall, it will play a loud alarm sound and inform the owners via their smartphone.\nThis is implemented using a Hall effect sensor on top of the key pad and can therefore be defeated using a strong magnet.\nWe recommend Neodymium magnets for such purposes ;).\n\n![Switchbot Keypad Components](https://neodyme.io/blog/switchbot/keypad_tamper.png)\n\nSwitchbot Keypad Components\n\n## Disclosure timeline\n\n| Date | Action |\n| --- | --- |\n| **15.07.2025** | Initial Report is sent |\n| **15.07.2025** | SwitchBot replies with additional questions |\n| **15.07.2025** | More context is provided |\n| **17.07.2025** | SwitchBot offers us to beta-test their patch |\n| **06.08.2025** | SwitchBot pushes the update to our account |\n| **13.08.2025** | We report our patch circumvention |\n| **18.08.2025** | We report multiple more patch circumventions |\n| **27.08.2025** | SwitchBot informs us, that it will take 6 months for them to update the rest of their ecosystem |\n| **12.09.2025** | SwitchBot sends us an Amazon voucher 🎉 |\n| **March 2026** | SwitchBot makes an updated version available |\n| **02.04.2026** | SwitchBot shares an updated version with us; we confirm that the described vulnerability does not work anymore |\n| **09.10.2026** | CVE published |\n\n## Fixed Versions\n\nAccording to SwitchBot, the following versions should have the relevant fixes installed.\n\n**Lock:**\n\n- SwitchBot Lock: V7.7 and later\n- SwitchBot Lock Pro: V3.7 and later\n- SwitchBot Lock WiFi: V15.21 and later\n- SwitchBot Lock Ultra: V2.8 and later\n- SwitchBot Lock Lite: V7.7 and later\n\n**Keypad:**\n\n- SwitchBot Keypad: V2.9 and later\n- SwitchBot Keypad Touch: V2.9 and later\n- SwitchBot Keypad Vision: V2.5 and later\n- SwitchBot Keypad Vision Pro: V1.0 and later\n\n**App:**\nSwitchBot App: V9.18 and later\n\n## Conclusion\n\nSecurity is hard and IoT devices often times lack good protections.\nWe have to give credit to SwitchBot for even trying to secure their system.\nMany IoT manufacturers don’t even do that.\nHacking this smart lock was a good reminder about the threats IoT devices can pose.\nEven the more expensive, highly sought after products, are not necessarily immune to attack.\n\nVulnerabilities like these arise from developers’ mistaken assumptions.\nIn fact, misusing crypto primitives like AES-CTR, aka. cryptographic failure, is one of the most common software security vulnerabilities according [OWASP](https://owasp.org/Top10/2025/).\nAs it turns out, we [offer a cutting-edge Black Hat training on crypto vulnerabilities](https://blackhat.com/europe/training/schedule/index.html?track%5B%5D=crypto#black-hat-cryptography-attacks-tools-amp-techniques-54313) and [audits](https://neodyme.io/en/reports/) and [testing](https://neodyme.io/en/pentests/) to help with exactly that!\n\n---\n\n*Originally published at [Neodyme](https://neodyme.io/en/blog/switchbot).*\n","body_html":"<h1 id=\"keyless-entry-hacking-switchbot-smart-locks\">Keyless Entry: Hacking SwitchBot Smart Locks</h1>\n<p><em>Tobias, Aaron, Justin and Ruben · Neodyme · October 26, 2026</em></p>\n<h2 id=\"tl-dr\">TL;DR</h2>\n<p>We’ve identified multiple vulnerabilities in devices of the popular <a href=\"https://eu.switch-bot.com/\" rel=\"nofollow ugc noopener\">SwitchBot</a> Lock Pro smart lock series.\nThe most critical, a cryptographic flaw in their bluetooth communication, allows everyone to silently open smart locks in a software-only attack.\nNo physical tampering is required.\nBelow is a video of the attack in action.</p>\n<h2 id=\"introduction\">Introduction</h2>\n<p>Smart locks have become very popular in recent years.\nEspecially when it comes to AirBnB-style apartment sharing, but also in corporate environments and private accommodation, people enjoy having locks that don’t require physical keys.\nSo when it came to selecting targets for our regular IoT hacking team event, smart locks were a natural choice.</p>\n<p>After some research we cam across the highly praised <a href=\"https://www.amazon.de/Lock-Pro-Touch-Fingerprint-Matter/dp/B0CR67GWML/?\" rel=\"nofollow ugc noopener\">Switchbot Lock Pro Combo</a>, including a key actuator, pin pad and smartphone app.\nIt is one of the best-rated and most-sold smart locks on Amazon.\nFor roughly 240€ (at the time of writing) it comes with a lot of features - and the Amazon reviewers are happy to share that it works as intended.</p>\n<p>Features aside, our main interest was, of course, the device’s security.\nSo we ordered one and had a look.\nHere is what we found out.</p>\n<h2 id=\"reversing-the-lock\">Reversing the Lock</h2>\n<p>As usual when inspecting IoT devices, we wanted to get our hand on the firmware.\nBut before we dive into that, let’s first look into the target’s features and architecture.</p>\n<h3 id=\"the-switchbot-pro-lock\">The Switchbot Pro Lock</h3>\n<p>The bundle comes with two hardware devices, an actuator and a key pad. The lock can further be controlled and configured via a smartphone app.</p>\n<figure><img src=\"https://neodyme.io/blog/switchbot/switchbot_amazon.png\" alt=\"Switchbot Pro Lock Bundle on Amazon\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Switchbot Pro Lock Bundle on Amazon</p>\n<p>The actuator is mounted onto the inside of the door and encloses the door’s key.\nWhen the door is supposed to open, the actuator simply turns the key in the lock.</p>\n<figure><img src=\"https://neodyme.io/blog/switchbot/actuator.jpg\" alt=\"Switchbot Pro Lock Actuator Promotional Material\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Switchbot Pro Lock Actuator Promotional Material</p>\n<p>The key pad is kept outside the door and communicates with the actuator over <a href=\"https://de.wikipedia.org/wiki/Bluetooth_Low_Energy\" rel=\"nofollow ugc noopener\">Bluetooth Low Energy</a> (BLE).\nA person can authenticate itself to the system either using a smart card/key fob, using a fingerprint, or - most commonly - by supplying a PIN.\nThe whole system can also be added to a WiFi network, making it possible to control the lock over the Internet.</p>\n<p>Now that we have an idea of the feature set, we can start digging.</p>\n<h3 id=\"firmware-reversing\">Firmware Reversing</h3>\n<p>When hacking a device, it is usually a good idea to first get your hands on its firmware.\nThere are various techniques for accomplishing this, <a href=\"https://neodyme.io/en/blog/drone_hacking_part_1/\" rel=\"nofollow ugc noopener\">FLASH Dumping</a> for example.\nBefore starting to desolder chips, however, it makes sense to scrape the web for firmware artifacts.</p>\n<p>With SwitchBot we got lucky, as the Android app contained the URL for a public S3 bucket containing firmware files.\nDownloading and analysing these files we found two surprising architectural choices.\nFirst, the key pad on the <strong>outside</strong> of the door actually controls the actuator on the <strong>inside</strong>, not the other way around.\nMeaning that the key pad decides if a PIN, fingerprint or key fob is valid and then issues an “UNLOCK” command to the actuator.\nSecondly, the communication between the key pad and actuator relies on an unprotected, clear-text BLE connection.\nAuthentication between key pad and actuator is done solely on the application level using a home-brewed mechanism.</p>\n<p>While the first point already yields a significant attack surface (i.e. let’s dump the key pad and open the door), the second offers a code smell too good to pass up.\nSo we focussed our main energy on exploiting the BLE communication between key pad and actuator.</p>\n<h3 id=\"key-pad-communications\">Key Pad Communications</h3>\n<p>Once the key pad and actuator are paired, they communicate using unprotected BLE.\nMeaning that all security of the system depends on application-level protections.\nSo let’s find out how these protections work.</p>\n<p>Upon pairing, the key pad and actuator agree on a <em>secret key</em>.\nThen, everytime the key pad becomes active, it requests a so-called “<a href=\"https://en.wikipedia.org/wiki/Cryptographic_nonce\" rel=\"nofollow ugc noopener\">nonce</a>” value from the actuator.\nFor our attack this does not matter.\nIt is noteworthy however, that the nonce is supposed to provide “freshness” between invocations of the protocol but that this implementation uses the same nonce for an entire “session” which can last for multiple commands.\nAfter the nonce is received, the key pad encrypts a command, using the secret key and nonce, and sends said command over the BLE connection.\nSuch a command could, for example, be “lock the door”.</p>\n<p>The following diagram illustrates how the BLE communication works.</p>\n<figure><img src=\"https://neodyme.io/blog/switchbot/Comms_Switchbot.png\" alt=\"Communication between key pad and actuator (simplified)\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Communication between key pad and actuator (simplified)</p>\n<p>Simply by looking at the communication diagram we can see a potential problem: We might be able to simply replay previous “unlock” commands that we have captured.\nHowever, that would require us to be within Bluetooth range, sniff the command, and then somehow replay it before the session ends.\nSince we aren’t writing an academic paper but do actual research: This is boring.</p>\n<p><strong>We want to be able to open the lock, first shot, without any physical tampering and without leaving traces.</strong></p>\n<p>And, as it turns out, we can accomplish this. But first need some more background on the implementation.</p>\n<h3 id=\"communication-protection\">Communication Protection</h3>\n<p>So the key pad/actuator communication is protected using secret-key encryption and a nonce.\nDigging further into the implementation, and with the help of <a href=\"https://github.com/jonghwanhyeon/python-switchbot\" rel=\"nofollow ugc noopener\">community-developed libraries</a>, we found out how the encryption is done.</p>\n<p>The commands are encrypted using the <a href=\"https://de.wikipedia.org/wiki/Advanced_Encryption_Standard\" rel=\"nofollow ugc noopener\">AES</a> block cipher in counter (CTR) mode.\nNow, counter mode is an interesting choice, because it doesn’t actually offer any integrity protection.\nFurthermore, because of its design, turning a block cipher into a stream cipher, bit flips propagate 1:1 from ciphertext to plaintext.</p>\n<figure><img src=\"https://neodyme.io/blog/switchbot/CTR.png\" alt=\"Counter mode encryption\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Counter mode encryption</p>\n<p>Meaning that: If we change a bit in a ciphertext, upon decryption by the actuator, this exact bit will also be changed in the decrypted plaintext.\nThis is a little-known, but often encountered vulnerability class.\nSo, let’s exploit this fact and open some doors!</p>\n<h2 id=\"exploiting-the-lock\">Exploiting the Lock</h2>\n<p>A key observation helps us to mount our attack.\nThe key pad’s lock button always sends an encrypted LOCK command, even if the door is already locked.\nExploiting the fact that AES CTR is used, we only need to compute the difference between an encrypted LOCK and UNLOCK command.\nWhen we XOR this difference (flipping all corresponding bits) into an encrypted LOCK command, the result will be a validly encrypted UNLOCK command.\nIt’s important to note here that this difference has to be computed only once, as it is identical across sessions and devices!\nWe therefore split the attack into a setup phase, run once, and an attack phase that opens a specific lock.</p>\n<p>After the one-time setup, the attack works as follows:</p>\n<ul><li>Press the lock button</li><li>Sniff an encrypted LOCK command send via BLE</li><li>Bit-flip the encrypted LOCK command into an encrypted UNLOCK command</li><li>Send the bit-flipped command to the actuator</li><li>The door opens</li></ul>\n<p>As we suspect a lot of vulnerable devices out there, we won’t publish our full exploit here.\nBut using an individual example, you can see why our attack works.\nSo, let’s work through it.</p>\n<h3 id=\"setup-phase\">Setup Phase</h3>\n<p>Using one pair of encrypted LOCK and UNLOCK commands, intercepted via BLE, we can compute their XOR difference.\nThis difference is identical across all sessions and all locks using the same firmware.\nTherefore, we can use this difference as a sort of “master key” to open all SwitchBot Pro locks.</p>\n<p>Sniffing an encrypted LOCK and UNLOCK command is done easily using our acquired lock.\nThen, we simply compute:</p>\n<pre><code>diff = ENCRYPTED_LOCK_COMMAND ^ ENCRYPTED_UNLOCK_COMMAND</code></pre>\n<h3 id=\"attack-phase\">Attack Phase</h3>\n<p>Applying (XORing) this difference <code>diff</code> to the encryption of any LOCK command, independent of secret key and nonce, will yield an encrypted unlock command, which we can then send to the actuator.</p>\n<pre><code>CRAFTED_ENCRYPTED_UNLOCK = ENCRYPTED_LOCK ^ diff</code></pre>\n<p>So, simply by applying our pre-computed, lock-independent, difference vector, we can turn <em>every</em> SwitchBot Pro LOCK command into an UNLOCK command.\nAnd we can always capture encrypted LOCK commands on any key pad, simply by pressing the lock button.\nNeat!</p>\n<h3 id=\"proof-of-concept-exploit\">Proof of Concept Exploit</h3>\n<p>We’ve recorded our attack in action.\nThe video shows the components and our Bluetooth antenna used for sniffing the encrypted LOCK command.\nOn the left you can see the Python script applying the difference to the encrypted LOCK command and sending the crafted encrypted UNLOCK command.\nThe right side of the screen shows that the attack worked:\nFirst, a LOCK command is issued by pressing the lock button.\nThen, the crafted UNLOCK command is send and the actuator turns the key, opening the door <code>\\o/</code>.</p>\n<p>It all happens very fast, so maybe you have to re-watch a couple of times to grasp everything.</p>\n<h3 id=\"responsible-disclosure-and-insufficient-fix\">Responsible Disclosure and Insufficient Fix</h3>\n<p>In accordance with our responsible disclosure guidelines, we notified the SwitchBot team of our findings.\nThey were very responsive (kudos!) and seemed to take the vulnerability seriously.\nThey awarded us a 100€ Amazon voucher for our work.</p>\n<p>Before they rolled out a firmware patch, they allowed us to have a look at the updated firmware files.</p>\n<p>After we reversed the new firmware, we discovered that they now append a “checksum” to every command.\nWe reimplemented the checksum computation in Python:</p>\n<pre><code>def calculate_checksum(command, key, nonce):\n\ndata_to_hash = command.encode(&#39;utf-8&#39;) + key.encode(&#39;utf-8&#39;) + nonce.encode(&#39;utf-8&#39;)\n\nhash_object = hashlib.md5(data_to_hash)\n\nfull_hash_bytes = hash_object.digest()\n\nreturn full_hash_bytes[:2]\n\nfull_command = COMMAND_UNLOCK + calculate_checksum(COMMAND_UNLOCK, self._encryption_key, self._nonce)\n\nsend_encrypted_bluetooth_command(full_command)</code></pre>\n<p>So the system now calculates an MD5 hash of the command, secret key and nonce.\nThe first <strong>two bytes</strong> of this hash then serve as verification tag.\nThis construction is sometimes referred to as <a href=\"https://blog.trailofbits.com/2024/08/21/yolo-is-not-a-valid-hash-construction/\" rel=\"nofollow ugc noopener\">YOLO hash</a> and rarely a good idea.\nHere in particular, the truncation to two bytes allows us to, in principle, brute force all 65,536 possible verification tags.\nHowever, this is not necessary.</p>\n<p>Because, to our surprise, just the communication between the key pad and actuator got updated.\nThe smartphone app still does not use a verification tag.\nWhich means that our attack still works 1:1, we just need to compute (once!) the difference between a key pad’s encrypted LOCK command and a smartphone issued UNLOCK command.\nWe can then mount our attack using this difference vector, as the actuator then thinks the UNLOCK command comes from a smartphone and does not check the verification tag.\nWe have verified that this variant of our attack works.</p>\n<p>When we reported this bypass, SwitchBot provided the following context:</p>\n<blockquote><p>The test firmware pushed to you only includes updates for the Keypad and Lock. The APP has not yet been updated with the new encryption method. We are currently working on implementing encryption upgrades for both the APP and the backend, and the Lock will no longer be compatible with the old encryption method. We need to ensure that this update does not affect other products bound to the APP […].</p></blockquote>\n<p>Backward compatibility is always challenging, especially when it comes to security and IoT devices out in the field.</p>\n<h2 id=\"further-attack-surface\">Further Attack Surface</h2>\n<p>As we were happy with our full compromise, we did not look too much into other avenues of attack.\nNoteworthy, however, was that the key pad uses MIFARE Classic 1K key fobs.\nThese are long broken and can be trivially cloned, e.g., using a <a href=\"https://flipper.net/\" rel=\"nofollow ugc noopener\">Flipper Zero</a>.\nIn order to mount this cloning attack, you’d have to get close to a key fob first.</p>\n<p>Additionally, while testing the Bluetooth attack, we noticed that the key pad has a tamper detection.\nIf it is removed from the wall, it will play a loud alarm sound and inform the owners via their smartphone.\nThis is implemented using a Hall effect sensor on top of the key pad and can therefore be defeated using a strong magnet.\nWe recommend Neodymium magnets for such purposes ;).</p>\n<figure><img src=\"https://neodyme.io/blog/switchbot/keypad_tamper.png\" alt=\"Switchbot Keypad Components\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Switchbot Keypad Components</p>\n<h2 id=\"disclosure-timeline\">Disclosure timeline</h2>\n<div class=\"table-wrap\"><table><thead><tr><th>Date</th><th>Action</th></tr></thead><tbody><tr><td><strong>15.07.2025</strong></td><td>Initial Report is sent</td></tr><tr><td><strong>15.07.2025</strong></td><td>SwitchBot replies with additional questions</td></tr><tr><td><strong>15.07.2025</strong></td><td>More context is provided</td></tr><tr><td><strong>17.07.2025</strong></td><td>SwitchBot offers us to beta-test their patch</td></tr><tr><td><strong>06.08.2025</strong></td><td>SwitchBot pushes the update to our account</td></tr><tr><td><strong>13.08.2025</strong></td><td>We report our patch circumvention</td></tr><tr><td><strong>18.08.2025</strong></td><td>We report multiple more patch circumventions</td></tr><tr><td><strong>27.08.2025</strong></td><td>SwitchBot informs us, that it will take 6 months for them to update the rest of their ecosystem</td></tr><tr><td><strong>12.09.2025</strong></td><td>SwitchBot sends us an Amazon voucher 🎉</td></tr><tr><td><strong>March 2026</strong></td><td>SwitchBot makes an updated version available</td></tr><tr><td><strong>02.04.2026</strong></td><td>SwitchBot shares an updated version with us; we confirm that the described vulnerability does not work anymore</td></tr><tr><td><strong>09.10.2026</strong></td><td>CVE published</td></tr></tbody></table></div>\n<h2 id=\"fixed-versions\">Fixed Versions</h2>\n<p>According to SwitchBot, the following versions should have the relevant fixes installed.</p>\n<p><strong>Lock:</strong></p>\n<ul><li>SwitchBot Lock: V7.7 and later</li><li>SwitchBot Lock Pro: V3.7 and later</li><li>SwitchBot Lock WiFi: V15.21 and later</li><li>SwitchBot Lock Ultra: V2.8 and later</li><li>SwitchBot Lock Lite: V7.7 and later</li></ul>\n<p><strong>Keypad:</strong></p>\n<ul><li>SwitchBot Keypad: V2.9 and later</li><li>SwitchBot Keypad Touch: V2.9 and later</li><li>SwitchBot Keypad Vision: V2.5 and later</li><li>SwitchBot Keypad Vision Pro: V1.0 and later</li></ul>\n<p><strong>App:</strong>\nSwitchBot App: V9.18 and later</p>\n<h2 id=\"conclusion\">Conclusion</h2>\n<p>Security is hard and IoT devices often times lack good protections.\nWe have to give credit to SwitchBot for even trying to secure their system.\nMany IoT manufacturers don’t even do that.\nHacking this smart lock was a good reminder about the threats IoT devices can pose.\nEven the more expensive, highly sought after products, are not necessarily immune to attack.</p>\n<p>Vulnerabilities like these arise from developers’ mistaken assumptions.\nIn fact, misusing crypto primitives like AES-CTR, aka. cryptographic failure, is one of the most common software security vulnerabilities according <a href=\"https://owasp.org/Top10/2025/\" rel=\"nofollow ugc noopener\">OWASP</a>.\nAs it turns out, we <a href=\"https://blackhat.com/europe/training/schedule/index.html?track%5B%5D=crypto#black-hat-cryptography-attacks-tools-amp-techniques-54313\" rel=\"nofollow ugc noopener\">offer a cutting-edge Black Hat training on crypto vulnerabilities</a> and <a href=\"https://neodyme.io/en/reports/\" rel=\"nofollow ugc noopener\">audits</a> and <a href=\"https://neodyme.io/en/pentests/\" rel=\"nofollow ugc noopener\">testing</a> to help with exactly that!</p>\n<hr />\n<p><em>Originally published at <a href=\"https://neodyme.io/en/blog/switchbot\" rel=\"nofollow ugc noopener\">Neodyme</a>.</em></p>","headings":[{"level":1,"text":"Keyless Entry: Hacking SwitchBot Smart Locks","id":"keyless-entry-hacking-switchbot-smart-locks"},{"level":2,"text":"TL;DR","id":"tl-dr"},{"level":2,"text":"Introduction","id":"introduction"},{"level":2,"text":"Reversing the Lock","id":"reversing-the-lock"},{"level":3,"text":"The Switchbot Pro Lock","id":"the-switchbot-pro-lock"},{"level":3,"text":"Firmware Reversing","id":"firmware-reversing"},{"level":3,"text":"Key Pad Communications","id":"key-pad-communications"},{"level":3,"text":"Communication Protection","id":"communication-protection"},{"level":2,"text":"Exploiting the Lock","id":"exploiting-the-lock"},{"level":3,"text":"Setup Phase","id":"setup-phase"},{"level":3,"text":"Attack Phase","id":"attack-phase"},{"level":3,"text":"Proof of Concept Exploit","id":"proof-of-concept-exploit"},{"level":3,"text":"Responsible Disclosure and Insufficient Fix","id":"responsible-disclosure-and-insufficient-fix"},{"level":2,"text":"Further Attack Surface","id":"further-attack-surface"},{"level":2,"text":"Disclosure timeline","id":"disclosure-timeline"},{"level":2,"text":"Fixed Versions","id":"fixed-versions"},{"level":2,"text":"Conclusion","id":"conclusion"}]}}