How to Bypass WhatsApp Web's Locked Chat Feature
I discovered that WhatsApp's feature to lock/hide chats is quite secure -> the key or secret code is not easily recoverable as it is encrypted. But, **the chats are actually not encrypted with the secret code**. That means, the secret code feature is just a front-end security control mechanism that can easily be bypassed. This may sound like bruteforcing Netflix's profile PIN which may be useless, but it actually serves an interesting use case. Let's say that the locked chat contains a very important information, but you forgot your secret code and you don't have access to your phone. Unfortunately, without the secret key, or a normal way to unlock the chats, WhatsApp will erase those chats. So, your options may be: (1) try to bypass the lock mechanism, or (2) find the secret code hash and crack it. ### Discovery I went to the Developer Tools' Sources tab, and search for interesting strings like "secretCode", "validateSecretCode", etc. Then, set a breakpoint on some interesting lines. This way, I can dissect the variable contents at runtime via the debugger, including the hashed secret code. ### Location of Secret Code Hash Aside from using the debugger, the hashed secret code is also stored in the `localStorage`. Look for something with the following value: ``` {\"transformer\":1,\"encoding\":0,\"iterations\":10000,\"salt\":\"bnUhR7dM70MxxxxxB0u4PA==\",\"data\":\"uO3dHQYxxxxxxxxcGBxb21dEQ1jjCcPOJcSrBO+31TQP/p/SjNWU4t5P6WIQXCIH8MdirWsutoUhLIxOWN2tA==\"}" ``` It's hashed using PBKDF2 ([this may be interesting](https://github.com/wppconnect-team/wa-proto/blob/48d0c1bf8f8c7c2a8c6eca903d3b6ed7e8793899/WAProto.proto#L3649)). ``` import json from passlib.hash import pbkdf2_sha512 # from localStorage p = '{"transformer":1,"encoding":0,"iterations":10000,"salt":"bnUhR7dM70MF8tNfB0u4PA==","data":"uO3dHQYZ1RiQwbaNcGBxb21dEQ1jjCcPOJcSrBO+31TQP/p/SjNWU4t5P6WIQXCIH8MdirWsutoUhLIxOWN2tA=="}' p = json.loads(p) # $pbkdf2-digest$rounds$salt$checksum h = f'$pbkdf2-sha512${p["iterations"]}${p["salt"].strip("=")}${p["data"].strip("=")}' assert pbkdf2_sha512.verify("hehe", h) is True ``` ### Bypassing Secret Code Check In the Sources tab, find a file with the following content: ``` d("WAWebCmd").Cmd.trigger("chatlock:unlock")); ``` It should be inside the body of an `if` statement. Set a breakpoint on the `if` statement. The `if` statement should look like `if (yield o(a)) {`. Now, try to enter a wrong secret in the secret code pop-up form, it should hit the breakpoint. In the console, modify `o` to return `Promise.resolve(1)`. ```o = () => Promise.resolve(1)``` Then, let the debugger continue. And.. voila! Your locked chats are now unlocked. <small>Sorry for the bad English. English is not my first language + I am too sleepy to think much about grammatical correctness</small>Created: 2024-12-06 19:04:12, Updated: 2024-12-06 19:29:07, ID: 3cf8e1b9-e5e3-4a6d-af27-12720c5b2d54