Reverse engineering Bambu Connect
Bambu Connect is an Electron app with security through obscurity, which makes it inherently insecure.
🔔This is a user-submitted guide
What is presented here is not objective information about a company's relation to consumer rights and does not follow the Consumer Action Taskforce Wiki's usual content guidelines.
This is a guide intended to give you more rights over your purchase. Inclusion of guides such as this one is only permitted in certain circumstances described in the article types page.
This guide may be incomplete and the information in it may have not been validated or updated. For more information see the discussion around it.
- For official mission and guidelines, please see our Mission statement
If you believe this notice has been placed in error, please visit the #appeals
channel on our Discord server: Join Here.
The purpose of this guide is to demonstrate the trivial process of extracting the "private keys" used for communicating with Bambu devices to examine, and challenge, the technical basis for Bambu Lab's security justification of Bambu Connect.
Update (January 26, 2025): Bambu Connect v1.1.3[1] is no longer obfuscated. You can skip all steps related to asarmor, asarfix
, Ghidra, and string deobfuscation.
To read main.js
for further analysis or extracting the private key stored by Bambu in the app:
- Use the MacOS .dmg file, not the .exe (finding the needed decryption code is easier in the .dmg).
- Extract
bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg
.[2] In there you can find the files of the underlying Electron app in theBambu Connect (Beta).app/Contents/Resources
folder. - The app uses asarmor to prevent easy reading. The key is stored in the mach-o binary located here:
/Bambu Connect (Beta).app/Contents/Resources/app.asar.unpacked/.vite/build/main.node
and can be extracted. Unpackingapp.asar
without fixing it first will result in an encryptedmain.js
file and 100 GB of decoy files generated. Don't try it. - Load
main.node
in Ghidra and Auto-Analyze it. Then search for the GetKey function, or press G and go to0000b67e
[3] - Write down the hex key. You will need to follow the previous steps to get the current key if the provided one does not work. As of 19 January 2025, they are:
- macOS:
B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2
- Windows:
D8BCE831F1284E1993D98EE807101F10F27AFF4E30BD4B420E057D02B8E9BD1B
- macOS:
- Install the npm package
asarfix
and use it to fix the archive:npx asarfix app.asar -k <KEY> -o fixed.asar
- Now you can extract it in cleartext with
npx asar extract fixed.asar src
./src/.vite/build/main.js
is minified. Use any JavaScript beautifier (for exampleprettier
) to make it better readable. Interesting user code (including the private key) is at the end of the file.
Extracting certs and private key
The private key and certs are further obfuscated. To get cleartext you need to do: Encrypted string from cy() -> ure(string, key) -> RC4 decryption -> decodeURIComponent() -> final string.
Example Python reimplementation to extract the secrets, easy to run. Copy the content of t from function cy() in main.js
and paste it here. After running, you have a private key from Bambu Lab.
import urllib.parse def cy(): t = [ # copy from main.js ] return t def ure(t, e): # RC4 implementation r = list(range(256)) n = 0 s = "" # Key-scheduling algorithm (KSA) for o in range(256): n = (n + r[o] + ord(e[o % len(e)])) % 256 r[o], r[n] = r[n], r[o] # Pseudo-random generation algorithm (PRGA) o = n = 0 for byte in t: o = (o + 1) % 256 n = (n + r[o]) % 256 r[o], r[n] = r[n], r[o] k = r[(r[o] + r[n]) % 256] s += chr(byte ^ k) return s def lt(t, e): r = cy() n = t - 106 s = r[n] s = ure(s, e) return urllib.parse.unquote(s) def extract_certs_and_key(): try: result = {} result["Are"] = lt(106, "1o9B") result["fre"] = lt(107, "FT2A") result["private_key"] = lt(108, "Tlj0") result["cert"] = lt(109, "NPub") result["crl"] = lt(110, "x077") except Exception as e: print(f"Error extracting certs/key: {e}") for key, value in result.items(): print(f"{key}:\n{value}\n") if __name__ == "__main__": extract_certs_and_key()
Purpose of the private key
The private key is used to digitally sign critical operations, such as print jobs and G-code commands. The printer can validate whether received MQTT commands are signed by Bambu Connect using the app's public key, rejecting any unsigned or improperly signed commands.
Bambu Lab's authorization control system that is meant to increase security is entirely built on the assumption that others do not have access to the private key and thus cannot create valid signatures.
Since the private key has already been leaked, however, third-party software can now regain access to the lost functionality, and it is clear that the overall security characteristics have neither improved nor worsened compared to previous updates.
What the key cannot be used for, contrary to many false claims on the internet:
- Decrypting HTTPS traffic to the cloud
- Decrypting any MQTTS or FTPS or video feed traffic
- Bypassing cloud user authentication
- Bypassing local authentication (LAN access code)
- Getting access to other printers
- Signing custom firmware
- Signing custom filament NFC tags
- Jailbreaking
Purpose of the certificates
The private key corresponds to the public key contained in the app's certificate. This certificate is sent to the printer, allowing it to verify the authenticity of the digital signature using the public key.
Bambu Connect continues to work after these certificates expire. Because of how these certificates are used, it is also unlikely that expiry causes the printer to get "bricked", but this needs to be proven through experiments or firmware analysis.
Additional security measures
Bambu Connect also encrypts G-code commands and file paths of print operations using the printer's public key. This ensures that only the intended printer can decrypt the data, rather than all authenticated MQTT clients and the cloud. This adds another layer of security.
The potential security benefits are diminished, however, because both the encrypted and plain-text strings are sent at the same time, likely because of negligence or the need for backwards compatibility.
Note that network traffic is encrypted by TLS regardless of this, ensuring that no middleman can decrypt it.
References
- ↑ https://public-cdn.bblmw.com/upgrade/bambu-connect/v1.1.3/bambu-connect-beta-darwin-arm64-v1.1.3_2c73d82.dmg - public-cdn.bblmw.com - accessed 2025-01-29
- ↑ https://public-cdn.bblmw.com/upgrade/bambu-connect/bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg - public-cdn.bblmw.com - accessed 2025-01-28
- ↑ "Bambu Firmware to impact use of OrchaSlicer" - archive.is - archived 2025-01-21