top title background image

Google Phishing Kit: When Phishing Becomes a Real-Time Remote Browser

Published on: 11.08.2026



Introduction


Most of the phishing pages are mere static clones of the login form, whereas sophisticated phishing kits implement adversary-in-the-middle techniques that perform authentication in real-time. In particular, the design being analyzed below fits into the Browser-in-the-Middle (BitM) scheme where the victim-facing page becomes the client for the browser session running at the backend of the phishing operation.

The captured network traffic and the extracted client-side artifacts demonstrate the functioning of the BitM session. The backend streams complete Google authentication views and subsequent DOM updates to the victim over Socket.IO, while the browser sends complete field state and user interactions in the opposite direction. This bidirectional relay allows the backend to drive a multi-step authentication flow while the victim remains on the malicious origin.

As can be seen from the analysis conducted with Joe Sandbox, the phishing kit perfectly duplicates the Google sign-in UI.




Furthermore, the architecture reconstructed in the Joe Reverser analysis and summarized in the diagram below goes well beyond a static credential-harvesting page. The kit combines a Google sign-in imitation with a bidirectional, real-time communication channel between the victim's browser and the phishing backend.



Thus, the server gets the opportunity to update and control the page as the authentication flow progresses, while the browser relays entered data and user interactions. In practice, the phishing webpage serves as a front end for an interactive remote session.

The client-side code already suggests that the phishing page is only one half of a much larger system. However, static analysis alone cannot answer an important question: how does this architecture behave during an actual phishing session? To answer that, the next section correlates the recovered JavaScript with the TLS-inspected network traffic captured during dynamic analysis.


How the Kit Mirrors and Controls the Victim's Browser


The TLS-inspected traffic captured during the Joe Sandbox analysis exposes the kit's delivery sequence. The initial request to the malicious URL returns a Cloudflare Turnstile gate. Once the challenge is successfully completed, the server redirects the browser back to the same route and sets three cookies with a three-minute lifetime, including viewer_session_id. When the browser follows the redirect with those cookies, it receives the encrypted application loader instead of the Turnstile gate:

GET https://salemilaw[.]com/?510c6ea8

As documented in the JoeReverser Expert Mode analysis report, the loader contains all the material required to decrypt itself inside the browser. Once decrypted in the browser, the page loads three JavaScript components from the phishing origin:

GET https://salemilaw[.]com/socket.io-client.js
GET https://salemilaw[.]com/domdiffer.js
GET https://salemilaw[.]com/index.js

The first script provides the Socket.IO transport. The second is a reformatted browser build derived from fiduswriter/diffDOM. The third, index.js, implements the custom relay and control logic that connects the victim-facing page to the phishing backend.

As shown in the figure below, taken from the same report, in the client-to-server direction, the most significant event is inputchange. Rather than sending only the most recently pressed key, it transmits the complete current value of any input or textarea, along with its CSS path, selectionStart and selectionEnd positions, and HTML element metadata. The same structure is emitted for normal input, paste, IME composition, and change events. This way, the backend gets both the captured value and enough context to determine which field produced it.




Since every user interaction is forwarded to the backend, the next question is how the phishing page prevents the browser from handling those interactions locally. In order to do that the click and submit handlers call preventDefault() and stopPropagation(). As a result, the browser does not perform the usual local navigation or form submission. Instead, the interaction is forwarded to the backend, which can respond with the next DOM state.

Forwarding user input alone would not be sufficient for a Browser-in-the-Middle attack. The backend must also be able to continuously reshape the interface shown to the victim. This is exactly what happens in the opposite direction, the backend controls the interface presented to the victim. As illustrated below, it uses domchanges to send diff arrays that index.js applies to the document head, body, and nested iframes. A server-to-client inputchange can update a specific field, restore its selection range or caret position, and dispatch a synthetic input event so that the page's event handlers can react to the change.

Before dispatching the event, the client records the server-supplied value in inputTracker; when the local input handler encounters the same value, it suppresses the corresponding outbound event, preventing a client-server feedback loop.



Beyond DOM rendering and field synchronization, the remaining events let the backend control the flow itself: it can prepare a document reset, pause further updates, rewrite the displayed path while preserving the malicious origin, and finish with a server-selected redirect that also sets a completion cookie.

The recovered code therefore defines both halves of the relay: complete field state and selected interactions travel towards the backend, while DOM patches, field synchronization, navigation updates, and flow-control commands travel back to the browser.


Revealing the real-time phishing kit behavior


At this point we have reconstructed the protocol from the client implementation, but the recovered code only describes the capabilities of the relay. The next step is to verify that these mechanisms are actually exercised during a live phishing session. Fortunately, the TLS-inspected capture produced by Joe Sandbox exposes the underlying Socket.IO traffic in plaintext, allowing the implementation to be matched against observed protocol events.

On the wire, this Socket.IO communication is protected by TLS: first over HTTPS polling and then, once the transport is upgraded, over WSS. The Joe Sandbox capture was produced through TLS inspection, exposing the plaintext application payloads. By decoding the remaining Engine.IO and Socket.IO framing, we can move from the capabilities identified in the client code to the event-by-event behavior observed during the sandbox session.

The extraction script used to reconstruct the timeline below is provided in Appendix A.

Rather than inspecting isolated packets, reconstructing the complete Socket.IO conversation makes it possible to follow the phishing workflow from the victim's perspective. The sequence below shows how user actions and server responses alternate throughout the authentication flow, revealing which side drives each step.

The reconstructed session contains 90 protocol records, including 74 application events. Most application activity occurred after the connection upgraded from HTTP polling to WebSocket. The direction markers reveal a genuinely bidirectional flow: the browser transmitted field changes, selections, and clicks, while the backend returned DOM patches, field updates, page resets, and URL changes.




The client did not wait for form submission before sending the entered email address to the backend. As it was typed, successive inputchange events transmitted the complete current value, together with the caret position and field metadata. Separate selectionchange events tracked cursor movement, while small domchanges messages arrived from the backend during the same interaction.

The completed address was sent again (frame 2695) immediately before the Next button was relayed as a structured click event (frame 2697).



Capturing the email address is only one half of the interaction. More interesting is what happens immediately afterwards, because the server uses the received input to advance the authentication flow and update the page presented to the victim.

The response to that click illustrates the other half of the protocol. The backend returned successive domchanges messages, synchronized the identifierId field with the complete email address through a server-to-client inputchange, and completed the updated interface with a final DOM patch carrying loadingFinished=true. That patch also contained field references including hiddenPassword, showing that the DOM delivered to the client already included elements for subsequent authentication states.




This is therefore not a conventional form submission followed by a new page load. The authentication interface evolves through a continuous exchange: the client streams its current state and user actions, while the backend determines what the browser displays next.


Conclusion


Taken together, the static analysis of the client-side code and the reconstructed Socket.IO session provide two complementary views of the same architecture. The recovered JavaScript reveals how the relay mechanism is implemented, while the network trace confirms how those mechanisms behave in practice during an actual authentication attempt.


The analysis confirms that this phishing kit operates as a real-time Browser-in-the-Middle system rather than a static credential harvester. By combining Joe Sandbox's dynamic analysis with the AI-assisted static analysis provided by Joe Reverser, it was possible to quickly identify and enumerate the kit's behavior, at least from the client-side perspective.


Indicators of Compromise (IOCs)

  • salemilaw[.]com

Appendix A.  

Here's the Pastebin link to the code: https://pastebin.com/MRYaTCvp.