Man-in-the-Browser in Google Chrome: Part 1 – Locating the SSL VMT

The financial services sector has become one of the main targets of cyber-attacks worldwide with the advent of e-banking. One of the most sophisticated and effective method used to conduct fraud is the man-in-the-browser attack, which infects the web-browser and is able to change the content of web pages and tamper network traffic without the victim noticing, even with security controls in place such as SSL/TLS.

To conduct such type of attacks, malware authors target specific internal browser functions which are responsible of handling network traffic and redirect the execution flow by applying a technique called “hooking“. Those internal functions, namely “attack points“, may or not be specifically exported by web browsers, making them straightforward to locate or very hard. The latter is the case of Google Chrome and, more generally, Chromium-based browsers which does not export functions responsible of handling SSL/TLS data thus making difficult for attackers to locate and hook those functions.

This series of articles will be divided in multiple parts with different approaches on how to locate the attack points used by financial malwares to grab submitted form data and/or to perform Webinjects.

MITB Attacks in Chromium

In modern browsers, attackers prefer to disable additional browser functions such as HTTP/2 and SPDY protocol which allows the compression of HTTP data. These two features, while they’re not security measures, might cause extra work for attackers which want to eavesdrop or alter HTTP communications. This is achieved by starting Chromium with specific flags such as –use-spdy=off and –disable-http2.

After disabling such protocols, financial malwares inject malicious code inside the virtual address space of the targeted browser to intercept and/or manipulate the secure communication between the user and the remote server(s). This is a two-step process which includes the following operations:

  • Locate internal Chromium functions responsible of handling the SSL/TLS data in plaintext
  • Redirect the execution flow to the attacker’s malicious code which can then either intercept sensitive data (form-grabbing) and/or manipulate the data by showing the user a modified version of the page (Webinject).

The variable nature of Chromium updates make malware author’s life hard as the internal Chromium functions are not exported directly thus different approaches have been employed which are more or less robust. A common attack point to Chromium-based browsers is to locate the SSL virtual method table (kTLSProtocolMethod 1) (which contains fundamental functions which, if hooked, could allow malwares to manipulate HTTPS data before it gets encrypted (i.e. outgoing data) and after it has been decrypted (i.e. incoming data).

However, since version 64 few fundamental methods used by attackers have been dropped from this internal table, namely ssl3_read_app_data and ssl_read_close_notify which denied attackers to easily locate the routines responsible of handling incoming HTTPS data.

Figure 1: Attack points in Chromium since version 64 2

ESET team also noted how the switch from Microsoft Visual C++ compilter to Clang in March 2018 changed the way methods appeared in the binary. In particular, because of different optimizations, SSL_Read was no longer inlined in DoPayloadRead with the compiler switch.

After all these changes, malware authors shifted their interest from SSL VMT to higher level functions such as SSL_Write and SSL_Read with different degrees of reliability and success. This article will look into locating the virtual table in memory.

SSL VMT Memory Hunting

This approach involves searching for a specific string in memory which resides just after the location of kTLSProtocolMethod. The procedure is the following:

  • Obtain the memory location of .rdata section of chrome.dll and its size
  • Perform a memory string search for until a match is found, starting from the base address of .rdata section
  • Looping backwards, attempt to find a memory structure similar to the one shown in Figure 2
  • After the kTLSProtocolMethod structure instance is found in memory, it is possible to access to its methods by index
Figure 2: Memory dump of kTLSProtocolMethod instance

The algorithm works by looping backwards until a false boolean value (in x64, a zeroed out QWORD) is found followed by n pointers to sub routines contained in the .text section of chrome.dll. Having found the SSL VMT memory location, it is possible to apply hooks on the table itself by modifying its method entries by changing the memory protection from read only (default in .rdata section) to read/write. It is also possible to apply an inline hook directly to the subroutine. Alternatively, it could be possible to obtain both SSL_Read and SSL_Write method locations by redirecting the SSL VMT entries related to write and read operations to a custom handler which, when called, checks the call stack to detect the higher-level calling routines.

DWORD64 GetTLSTableAddr(int& outMembersCount) {
    DWORD rdataSize, textSize;
    DWORD64 cur, match, vtable_method, rdataAddress, textStart, textEnd;
    HMODULE hModule;
    int k;
    // Get address where chrome.dll resides in memory
    hModule = GetModuleHandleA("chrome.dll");
    if (!hModule)
        return 0;
    // Get informations  about chrome.dll PE sections (.rdata and .text)
    rdataAddress = GetSectionAddress(hModule, ".rdata", &rdataSize);
    textStart = GetSectionAddress(hModule, ".rdata", &textSize);
    textEnd = textStart + textSize;
    for (int i = 0; i < rdataSize; i++) {
        cur = *(DWORD64 *)(rdataAddress + i);
        if (!memcmp(cur, "", 13)) {
            match = rdataAddress + i;
            // go backwards 300 bytes
            for (int j = 1; j < 300; j++) {
                k = 1;
                // is_dtls is zero for kTlsProtocolMethod instance
                if (*(DWORD64 *)(match - j) != 0)
                while (true) {
                    vtable_method = *(DWORD64 *)(match - j + k * sizeof(DWORD64));
                    // VMT methods are within .text section of chrome.dll
                    if (vtable_method < textStart || vtable_method > textEnd) {
                // SSL VMT table needs to have at least 15 methods
                // this limit is arbitrary, based on the evolution
                // of the SSL VMT structure
                if (k > 15) {
                    outMembersCount = match - j;
                    return match - j;
    outMembersCount = 0;
    return 0;

This approach was successful in finding VMT table address from the memory. By choosing an algorithm which does not not check for fixed amount of members in the VMT, it is possible to find arbitrary the SSL VMT in a more robust way. In fact, the algorithm proved its robustness even after an update to the kTLSProtocolMethod members count, which shifted from 18 to 19 from major version 81 to 83.

Chromium VersionTarget VMT FoundVMT Members Detected


As key methods such as ssl3_read_app_data and ssl_read_close_notify were removed from the SSL VMT, malware authors shifted their focus to higher-level functions. This was a necessary move as the SSL VMT has an history of being edited or reordered quite often. Consequently, even though the VMT lookup method results were positive, further work is needed to obtain higher-level wrappers addresses especially for read operation. Next part of this series will show possible approaches to obtain those internal wrappers, namely SSL_Read and SSL_Write and will evaluate how robust those approaches are.


  1. in Chromium source code repository
  2. VB2017 paper and update: Browser attack points still abused by banking trojans

Leave a Comment