To read the main.js for further analysis or extracting the private key stored by Bambu in the app:
bambu-connect-beta-darwin-arm64-v1.0.4_4bb9cf0.dmg. Inside, you can find the files of the underlying Electron app in Bambu Connect (Beta).app/Contents/Resources folder./Bambu Connect (Beta).app/Contents/Resources/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.main.node in Ghidra and Auto-Analyze it. Then search for the GetKey function, or press G and go to 0000b67e.B0AE6995063C191D2B404637FBC193AE10DAB86A6BC1B1DE67B5AEE6E03018A2D8BCE831F1284E1993D98EE807101F10F27AFF4E30BD4B420E057D02B8E9BD1Basarfix and use it to fix the archive: npx asarfix app.asar -k <KEY> -o fixed.asarnpx asar extract fixed.asar src./src/.vite/build/main.js is minified. Use any JavaScript beautifier (for example prettier) to make it better readable. Interesting user code including the private key is at the end of the file.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()