Please note that all submissions to the site are subject to the wiki's licence, CC 4.0 BY-SA, as found here
Reverse Engineering Bambu Connect: Difference between revisions
Adding category |
and challenge |
||
(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
<noinclude><div style="padding-left:1.6rem;margin-bottom:0.5rem;">''This is part of the [[Bambu Lab Authorization Control System]] article.''</div></noinclude> | <noinclude><div style="padding-left:1.6rem;margin-bottom:0.5rem;">''This is part of the [[Bambu Lab Authorization Control System]] article.''</div></noinclude> | ||
Bambu Connect is an Electron App with Security | Bambu Connect is an [[Help:Electron|Electron]] App with [[Security Through Obscurity]] principles, hence it is inherently insecure.<noinclude> | ||
{{GuideNotice}} | |||
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. | |||
To read the main.js for further analysis or extracting the private key stored by Bambu in the app: | To read the main.js for further analysis or extracting the private key stored by Bambu in the app: | ||
# Use the | # 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''<ref>https://public-cdn.bblmw.com/upgrade/bambu-connect/bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg</ref>, in there you can find the files of the underlying Electron app in | # Extract ''bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg''<ref>https://public-cdn.bblmw.com/upgrade/bambu-connect/bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg</ref>, in there you can find the files of the underlying Electron app in <code>Bambu Connect (Beta).app/Contents/Resources</code> folder. | ||
# The app uses asarmor to prevent easy reading, the key is stored in ./app.asar.unpacked/.vite/build/main.node and can be extracted. Unpacking app.asar without fixing it first will result in an encrypted main.js file and 100 GB of decoy files generated, don't try it. | # The app uses asarmor to prevent easy reading, the key is stored in <code>./app.asar.unpacked/.vite/build/main.node</code> and can be extracted. Unpacking app.asar without fixing it first will result in an encrypted main.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 to 0000b67e<ref>https://www.reddit.com/r/OrcaSlicer/comments/1i2t6l8/comment/m7tuf2i/</ref> | # Load main.node in Ghidra and Auto-Analyze it. Then search for the GetKey function, or press G and go to <code>0000b67e</code><ref>https://www.reddit.com/r/OrcaSlicer/comments/1i2t6l8/comment/m7tuf2i/</ref> | ||
# Write down the hex key, | # Write down the hex key, and as of 19 January 2025, it is <code>B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2</code>. You will need to follow the previous steps to get the current key if the provided one does not work. | ||
# Install the npm package asarfix and use it to fix the archive: <code>npx asarfix app.asar -k B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2 -o fixed.asar</code> | # Install the npm package asarfix and use it to fix the archive: <code>npx asarfix app.asar -k B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2 -o fixed.asar</code> | ||
# Now you can extract it in cleartext with <code>npx asar extract fixed.asar src</code> | # Now you can extract it in cleartext with <code>npx asar extract fixed.asar src</code> | ||
# ./src/.vite/build/main.js is minified, use any JavaScript beautifier to make it better readable. Interesting user code including the private key is at the end of the file. | # <code>./src/.vite/build/main.js</code> is minified, use any JavaScript beautifier to make it better readable. Interesting user code including the private key is at the end of the file. | ||
=== Extracting certs and private key === | === Extracting certs and private key === | ||
Line 73: | Line 75: | ||
extract_certs_and_key() | extract_certs_and_key() | ||
</pre> | </pre> | ||
== References == | |||
{{reflist}} | |||
[[Category:Bambu Lab]] | [[Category:Bambu Lab]] | ||
</noinclude> |
Latest revision as of 20:44, 20 January 2025
Bambu Connect is an Electron App with Security Through Obscurity principles, hence it is 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 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 currently under consideration for this wiki.
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: Mission statement
If you believe this notice has been placed in error, or once you have made the required improvements, 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.
To read the 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[1], in there you can find the files of the underlying Electron app in
Bambu Connect (Beta).app/Contents/Resources
folder. - The app uses asarmor to prevent easy reading, the key is stored in
./app.asar.unpacked/.vite/build/main.node
and can be extracted. Unpacking app.asar without fixing it first will result in an encrypted main.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 to
0000b67e
[2] - Write down the hex key, and as of 19 January 2025, it is
B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2
. You will need to follow the previous steps to get the current key if the provided one does not work. - Install the npm package asarfix and use it to fix the archive:
npx asarfix app.asar -k B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2 -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 to make it better readable. Interesting user code including the private key is at the end of the file.
Extracting certs and private key[edit | edit source]
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()