You will need to run some code before the page code runs, which can be done with either Chrome Local Overrides or a userscript.
It depends on how the page listens to messages. If it assigns to the onmessage
property of the socket instance, you can overwrite the setter with your own setter that traces the caller - you could use console.trace
, or throw new Error
.
Object.defineProperty(WebSocket.prototype, 'onmessage', {
set(newVal) {
throw new Error();
}
});
Then just open the console, look at the stack trace of the thrown error, and you'll be in the general location of where the message gets parsed - perhaps the decryption is done there, or perhaps the payload gets passed to another function that does the decryption. If the page's script is large, it'll help to use a good IDE that allows you to jump to function definitions by their references. (eg, in VSCode - right click an identifier, then select Go to definition).
If the message listener gets attached with addEventListener
instead, you can monkeypatch WebSocket.prototype.addEventListener
and use the same technique.
WebSocket.prototype.addEventListener = function(eventName, callback) {
if (eventName === 'message') {
throw new Error();
}
};
One of the above approaches will show you where the message enters the page's script. Since you already know how to get to where the message exits the page script (and gets put into the DOM), you now have a starting point and an ending point, and can work backwards and forwards until they meet.
That's for the general approach. For this particular situation, it looks like it's encoded with some variation on Base64, because I can see that the payload in your question contains the words currentPayout
, code
, currentGameTime
, and currentMultiplier
.