BokBot: Proxy Module
This article is a continuation of CrowdStrike’s recent blog, “Digging Into BokBot’s Core Module,” and provides a detailed analysis of the inner workings of the BokBot proxy module — a complex piece of code written to trick victims into sending sensitive information to a command and control (C2) server.
Overview
The BokBot banking Trojan —also known as IcedID — was first observed in April 2017 and CrowdStrike has been tracking this threat ever since. BokBot has been used against financial institutions worldwide and is able to augment its capabilities by retrieving several modules, including one that runs a local proxy server. This proxy module is able to intercept and potentially manipulate web traffic with the goal of facilitating financial fraud. The BokBot core module downloads the proxy module, injects it into a spawned svchost child process, and the proxy module initializes itself in the target process. The following is a step-by-step analysis of how this process unfolds.
Module Initialization
Prior to standing up the proxy server thread, this module goes through an initialization process. Most of it is similar to the other BokBot modules — covered in the previous blog — and includes making errors less noisy, building a list of C2s, and setting up named events for communicating with the parent process. The following steps are taken prior to intercepting any traffic from a victim’s browser.Webinject Updates
User-mode asynchronous procedure call (APC) objects are used to trigger update events for the webinject data that exists in process memory. During initialization, separate user APC objects are sent to the APC queue, one for each of the webinject DAT files (see previous blog). Each DAT file is decoded and stored in process memory, and will be passed as a parameter to the APC callback function. Once the APC queue is processed, the web configs will be parsed and loaded into process memory.C2 Communication Thread
The communication thread is signaled whenever there is collected data to be sent back to the C2. A signal event occurs when the injected malicious javascript sends a specific type of request to the proxy server (see: Browser Perspective section) . The data that is sent back can consist of harvested personal information, snapshots or proxy-related errors.Proxy Server Initialization
The proxy server is bound to 127.0.0.1 on TCP port 57391. After the listener is set, a Windows Socket API (WSA) event handler is registered using this socket to handle all connect/send/receive network requests.SSL Certificates
In order to perform a man-in-the-middle (MITM) attack on SSL connections, the proxy server needs to generate an SSL certificate, and insert it into the cert store. The certificate is created by calling CertCreateSelfSignCertificate, using the following hard-coded distinguished name (DN) values:
- C:\Users\jules\AppData\Local\Temp\D38D667F.tmp

Proxy Connections
Now, whenever the browser attempts to connect to a website, that request is hijacked and first processed by the proxy server. This section covers how the connection states are managed, how SSL MITM works, and what actions are taken by the proxy server.Managing Connection State
All connections are managed by a series of data structures tied to WSA callback events that keep track of internal communication with the client, external communication with the target website, and to ensure the integrity of all the requests handled by the proxy server.
SSL Man in the Middle
Any SSL request, where the URL matches a URL from the list of webinject targets, is hijacked by the proxy inserting itself into the communication using its own SSL certificate. The proxy server receives the request from the victim and establishes an SSL connection using the proxy server’s SSL certificate. After that, the proxy server sends the request to the target website, and establishes an SSL connection between the proxy and the target website. The response from the target is decrypted, and then encrypted using the proxy’s certificate. This response is sent to the victim, where the traffic will be decrypted using the proxy’s certificate.An SSL context data-structure, similar to Figure 1, is used to maintain the state of the SSL traffic. See the “Ensuring Valid Certificates” section to understand how the browser is hooked to ensure that it sees these certificates as valid.
Proxy Action
If the requested URL hostname does not match one of the webinjects, then the proxy server passes the HTTP requests/responses between the infected host and the web server. However, if a URL matches one of the many websites targeted by the webinjects, then additional action is taken (see “Traffic Manipulation Proxy Perspective”).Redirecting Browsers to the Proxy
After the proxy server has been initialized, any currently executing browser process will have to be configured to use the proxy. To do this, BokBot injects code into the browser process. The injected code adds hooks into key functions, allowing it to hijack browser traffic.Browser Process Selection
A looping thread is spawned to iterate over all of the currently executing process names. To get a list of current processes, a list ofBASIC_PROCESS_INFORMATION
structures is generated using ZwQuerySystemInformation
.
Process Identification
Once the list is generated, the module will attempt to identify browser processes. A hash of the process name is used to identify whether the process is one of the specific browser processes listed in Table 1.
Proxy Configured Check
Once the browser has been identified an additional check is made to determine if this browser process has already had the proxy configured by BokBot. To keep track of every browser process that has been injected into, a linked list data structure is created (Figure 2). The entire list is walked, checking to see if both the process ID and the process creation time exist in the list. If the browser is not in the list, then a new list item is created that contains the target process ID and target process creation time.
OpenEvent and if the returned error code is
ERROR_FILE_NOT_FOUND
, the injection code continues.
Opening the Process and Additional Checks
OpenProcess
is called to open a handle to the browser process. BokBot checks to see if the process is WOW64, and if so, different procedures are used that will yield the same result.
To be thorough, another check is made to determine if the process has already been configured:
ZwQueryInformationProcess
andReadProcessMemory
are used to get the process environment strings.- Each string is checked to see if this exists:
v313235373937=true
- The
3132353739
is an ascii representation of the BotID.
- The
- No injection occurs if this environment string exists.
Browser Process Injection and Code Execution
The proxy configuration code is injected in the same manner as BokBot’s child process injection method (see the blog on BokBot’s main module), except for two things:OpenProcess
is called to connect to the process, and a hook is added for ZwWaitForSingleObject
. This means that as soon as the browser executes ZwWaitForSingleObject
, the injected code executes: The hook is removed, the proxy is configured and the
ZwWaitForSingleObject
call is completed to maintain process execution.
Context Structure
The context data structure is injected into the browser process and provides the proxy configuration code with the necessary information to properly configure the proxy.Browser Proxy Configuration Code
The “configuration code” is actually a series of procedure hooks that are used to insert the proxy module into the communication channel:CertVerifyCertificateChainPolicy
CertGetCertificateChain
connect
- Browser specific functions:
- Internet Explorer:
MSAFD_ConnectEx
- Firefox:
SSL_AuthCertificateHook
- Chrome:
ws2_32.WSAEventSelect
- Internet Explorer:
Inserting the Hooks
Most of the hooks are inserted by walking the export table of the target module, hashing the procedure name, and then comparing that hash against a static value. If these hashes match, then the hook can be placed.
MSAFD_ConnectEx
, a different method is used and is discussed in the “Internet Explorer: MSAEFD_ConnectEx” section.
Winsock2 Connect Hook
The Winsock2 hook intercepts allAF_INET
network traffic that uses the connect
API to send network traffic (Firefox and IE). The socket is set to non-blocking mode, using
ioctlsocket
and a new connect
call is sent to the proxy server. Once a connection is established, a 12-byte packet containing the following data is sent to the proxy server:

PROXY_SESSION_CONTEXT
data structure (Figure 1). The result of the hooked call is a network file descriptor. Any network call that uses this file descriptor will be sent to the proxy server. Whichever browser made the call will be unaware of the proxy intercepting the traffic.
Hooking Browser-Specific Functions
The next set of hooks are dependent on the target browser. Essentially, whether or not it is a browser-specific library or a MS shared module, each browser handles requests in a different manner.Internet Explorer: MSAFD_ConnectEx
Similar to the previousconnect
hook, this function swaps out the original socket with a socket that contains the connection data for the proxy server. The procedure address is not located in the export table of mswsock.dll, so the address is acquired by calling WSAIoctl
socket with the IO Control Code of SIO_GET_EXTENSION_FUNCTION_POINTER (0xC8000006).
FireFox: SSL_AuthCertificateHook
Firefox uses theSSL_AuthCertificateHook
callback function to authenticate a certificate. SECSuccess
(null) is returned if the certificate is authenticated. BokBot attempts to hook this function in the “nss3.dll” module and if that fails, it will patch the same function in “ssl3.dll.” The hook always returns
SECSuccess
.
Google Chrome: WSAEventSelect
In addition to thews2_32.connect
procedure being hooked, BokBot adds an additional hook in the ws_32.dll module in WSAEventSelect
. The hook grabs the socket and the event object for every connection event (FD_CONNECT
). This data will be processed by the call to the hooked connect procedure.
Google Chrome: connect
Essentially, this hook does the same thing as what is covered in the previous section on the connect hook for IE and Firefox. The main difference is that all connection events collected by theWSAEventSelect
hook are processed by this hook.
Ensuring Valid Certificates
Once browser traffic is redirected to the proxy, the malware must prevent browser certificate errors from informing the user that requests are being intercepted. To ensure that the certificates are both verified and trusted, two procedures are hooked:CertVerifyCertificateChainPolicy
and GetCertificateChain
.
Certificate Chain Verification
Certificate chains are verified by callingCertVerifyCertificateChainPolicy
. This procedure returns a Boolean function to signify whether or not a specific chain is valid. BokBot hooks this function to ensure that all attempts to verify SSL certificate chains (CERT_CHAIN_POLICY_SSL
) will always return TRUE
.
Certificate Chain Context Trust
In order to ensure that the browser sees that the certificates are trusted, BokBot hooks theGetCertificateChain
procedure. GetCertificateChain
will construct a CERT_CHAIN_CONTEXT
structure that contains an array of CERT_SIMPLE_CHAIN
structures. Each one of these
CERT_SIMPLE_CHAIN
structures contains an array of CERT_CHAIN_ELEMNT
data structures.
These data structures all contain a field, TrustStatus
, used to convey potential issues with the certificate chain. To ensure success, the TrustStatus
field needs to be modified to ensure all certificates in the chain are trusted.
TrustStatus
is a structure comprised of a field that identifies errors with the certificate (ErrorStatus
) and a field that contains an information status for the ticket (InfoStatus
). Patching these two fields within each structure will trick the browser into believing that the certificates are all trusted. First,
ErrorStatus
is set to indicate that there is no error with the certificate or chain:

InfoStatus
fields, however, are different between the CERT_CHAIN_ELEMENT
structure, CERT_CHAIN_CONTEXT
and CERT_SIMPLE_CHAIN
structures:

Proxy C2 Communication
The majority of the communication passed between the proxy server and the C2 will be comprised of either exfiltrated data or error messages for debugging. Table 3 contains the URI(Uniform Resource Identifier) parameters that are passed with every request. The data sent will be covered in the following section.




Traffic Manipulation: Proxy Perspective
BokBot’s proxy module relies on traffic manipulation to steal a victim’s sensitive information. Web traffic generated by a victim’s browser is matched against a list of target URLs (webinjects), and if matched, the proxy takes one of the following actions: redirect to a decoy website (webfake); scrape the page; screenshot the page; or ignore. In addition, the response to the request is matched to determine if either HTML or Javascript is injected into the page and served back to the victim.
Web Injection DAT Files
The DAT files downloaded by the BokBot main module are structured binary files that contain a list of target URLs, target HTML/Javascript code blocks, and the Javascript/HTML code blocks to be injected. During the initialization process, this structured data is broken into multiple lists for each of the webinject categories. The webinject category lists are built out of a series of webinject types. Once parsed, each element has the following structure:
Page Scraping
The page-scraping processing functions perform a match on either the URL or on the HTML body to determine if the webpage’s information should be scraped and sent to the C2. Page scraping targets banking account display pages to grab the target’s account information.Types 33, 34
Either an exact URL string or a regex is used to match the victim’s requested URL. Once a match is made, both the HTML body and the matched URL are sent to the C2. Each of the targeted URLs are related to pages that contain the victim’s account information, for example:- chaseonline.chase.com/gw/secure/ena
- client.schwab.com/Accounts/Summary/Summary.aspx
Type 64
This scans the webpage body looking for text (“Account Balance,” “Current Balance,” etc.) related to account balances, security challenge questions and other personal data. If located, the URL, the HTML body and the matched text are compressed and sent to the C2.Screenshots
Screenshots are generated when a URL matches on a Type 49 inject. Screenshots are taken using the Windows GDI+ API. A bitmap is generated, written to a tmp file, read into a buffer, compressed, and then sent to the C2. Bitmaps are written to the local temp directory under AppData and the filename is a unique string of alpha characters.Code Injection
Code injection works by either matchinga URL, or doing a match and replace on an HTML element.
Types 17 and 19
Types 17 and 19 are used to hide elements within a page, grab form data, inject code, replace code, and to make the webfake experience more believable for the victim. The difference between these two types is that Type 17 doesn’t rely on regex to match and replace HTML and Javascript.
Type 81
Type 81 is a list of URLs that are ignored entirely by the proxy server. The purpose is to avoid complications that could come up when injecting into advertisements and chat or email clients. Rather than deal with handling this code, the requests and responses are forwarded to the victim or the target by the proxy, without modification.
Webfake Phishing Site
BokBot uses the webinjects to create a replica of the original target website. These replica websites are called webfakes. URIs are rewritten to forward the traffic to the webfake site. This section covers each of the injection types used to redirect traffic to a webfake. The web browser is not aware that traffic is being redirected to the webfake.
Type 50
Type 50 requests perform exact matches (no regex) on URIs received from the client. Whenever a match occurs, the URL is rewritten to point toward the webfake site, and the request is sent to the replica page. The response to that request is parsed by the proxy server and sent back to the victim.
Type 51
To match individual icon/gif/bitmap/other names, regex match and replace is leveraged:- Regex to match: ^https:\/\/www\.amazon\.{2,5}\/.*\/style\/images\/(.*)\.(png'|gif)$
- Replacement URI: hxxps://hospirit<.>com/amazon/style/images/$1.$2
- IP Address for hospirit<.>com:
- IP Address for hospirit<.>com:

Type 52
Type 52 requests appear to check a URL for a substring and then extract that data, but the BokBot samples used to build this report did not contain a Type 52 rewrite.URL Rewrite Bypass
It would become an issue if the same webfake process is used every time a victim attempts to log into a targeted website. Once the victim’s information has been collected, there is no longer a need to rewrite URLs to point towards the webfake site. Instead, the request should be sent, unmodified, to the real website. To ensure this happens, BokBot, maintains a list of subkeys located under the HKCU\Software\Classes\CLSID registry key. For this to work, a unique name needs to be generated for each of the target sites. Each of the inject types included in this category contains a Webfake Template field, for example:
If the registry subkey exists, the proxy server sends a request to the C2 to determine if the request should be rewritten. If the response from the C2 is anything other than one of the two bytes — “0x2D” or “0x2B” — the legitimate URL will not be rewritten to point to the webfake site.
Verification Requests
Verification requests are generated by the Bot API javascript (covered further down) and are used to either send data to the C2, or to insert/delete/query a value in the registry. Multiple verification request types are used, each one is processed by the proxy server.
Type 96
In order to either display a “Site Down for Maintenance” message or present the victim with a legitimate website (bypass the URL rewrite request), the Bot API injected javascript code can generate these Type 96banknameS
requests.

Each site is provided a unique ID that is sent to the proxy server via the
banknameS
parameter. This value is used to generate a UUID, which will be the name of the registry key. All of these entries are created under the following registry path: HKCU\Software\Classes\CLSID
.
After the key is created, the value located in the body of the Type 96 request is hashed and written to the (Default
) value field in the registry subkey.
Types 97 and 98
Both Type 97 and 98 verifications will be generated by the Bot API’s injected javascript, and will perform an action on the registry key that was created by the Type 96 request. Type 97 queries the registry to see if the value exists, and Type 98 will delete the key.Type 100
Verification Type 100 is either passed directly to the C2 (Type 2) or the request tells the proxy server to interact with the C2 (Type 1) in some manner.These requests are either HTTP POST or HTTP GET requests that contain the information collected from the malicious javascript code.
Putting it All Together
Let’s take an example using the cashanalyzer website inject: First, the proxy server receives a request from a web browser to access www.cashanalyzer.com. The proxy cycles through the various webinject lists to match the URL. A match is found.
2299737dfa5c070dc29784f1219cd511
value from the first part of the Webfake Template field and uses it to generate a UUID to determine if a “Site Down For Maintenance” page is set (see the “Verification Requests” section). If it exists, a request is sent to the C2 to determine if the block page should be updated with a new time or removed.
Once the block page check has been made, the proxy server takes the rest of the Webfake Template and replaces the front://
string with the web protocol (HTTP/HTTPS) and the replacement URL hospirit.com/cashanalyzer
. The URL path and query, content/main?a=2299737dfa5c070dc29784f1219cd511&b=#gid#&c=#id#
, is appended to the end of the URL. The Project ID and the Bot ID values replace the #gid#
and #id#
parameter value tokens, respectively.

main.js
is loaded from the webfake. The browser requests to download the javascript file from the redirected website and, once again, the proxy server performs the webinject match routines. As a result, a Type 19 match is found.

main.js
code when the redirected website responds to the request. Now all of the necessary components are in place to collect the target’s account information.
Once form data is collected, Validation Type 100 requests are sent and processed by the proxy server. These requests are POST requests with the form data contained within the request body. Once processed by the proxy, the form data will be sent to the C2 by signaling the C2 communication thread.

Traffic Manipulation: Browser Perspective
Due to the multitude of variations for the injected javascript API, and rather than attempting to abstract and present the high-level processes each inject has in common, this section will focus only on continuing the cashanalyzer.com example introduced in the previous section. This analysis can be used to understand how the other injects work. The first couple of sections will cover how the site interacts with the victim, the proxy and the C2. After that is covered, the “Putting it All Together” section will connect the separate pieces.Bot API: Core Javascript Module
As previously mentioned, the
main.js
file contains the Bot API code. This code provides everything necessary to interact with the proxy, the C2 and the webpage HTML elements, to ensure that the victim has a seamless experience while entering the account information.
Token States
A token state is a numerical indicator used to identify what action the Bot API should take next. There are five token states:
Page View Architecture
In order to ensure that the correct information is collected in the proper order, the Bot API relies on a traditional view/controller architecture. In this case, the controller is the attacker-controlled webfake site. The Bot API client notifies the C2 that it is ready to receive a command, the server responds with a command, and this command is used to load the next page view.
- Login page view is loaded
- Victim enters the account information and submits the form
- A wait page is displayed as the login form is processed
- Security token page view is loaded
- Victim enters the security token
- A wait page is displayed as the security token form is processed
- First name/last name/phone number page view is loaded
- Victim enters this information
- Another wait page is displayed as this form is processed
Wait Pages
After the victim attempts to log in to the website, there is an idle period as the proxy forwards the request to the webfake site, and that site forwards the request to the legitimate website.To avoid causing any concern, the Bot API displays a wait page.

Communication: Bot API Requests to the C2
Commands are forwarded to the C2 on behalf of the Bot API by the proxy server using Validation Type 100 requests. Contained within these requests is a base64-encoded string. This string decodes to a series of parameters in JSON format.

Communication: C2 Responses to the Bot API
Responses from the C2 contain commands specifying what actions the Bot API should take, based on the initial request. After each form submission, a command is received from the C2 telling the Bot API which page to load next. These responses are also base64-encoded JSON.

id
field lines up with the view commands table (Table 6) covered in the “Page View Architecture” section.
Site Maintenance Page
Whenever the token state of the Bot API is set to “3” or “4,” an error page stating that there are technical issues is displayed (Figure 6). The token is set to one of those two states whenever there is an issue communicating with the C2, the webfake, the proxy server, or if an error occurs when the webfake communicates with the real website.
Logging
The Bot API is constantly sending logging data back to the C2 as base64-encoded JSON. The following is the decoded JSON object:
key:value
pairs, where the h key contains the log, as a value
. The logs are descriptive and useful for the malicious actor.
Putting it All Together
Initial Browser Request
The victim’s browser sends a request for cashanlyzer.com, and that request is intercepted by the proxy, rewritten, sent to the webfake site, and the response is sent from the proxy to the victim. The page content also contains the following javascript code to load a javascript file from the attacker-controlled site:
main.js
request is forwarded by the proxy and has the following code injected into the response:

String.prototype.init
method that is defined in main.js
. In this case, the init method contains the malicious Bot API javascript module, and will end up calling the main function to initialize and load the webfake site.

id
of the HTML <div> object that contains the login form.

none
to block
and the login page is displayed (Figure 7). Now the victim can enter the login information and click “continue.” All of the data entered is placed into a C2 request structure and sent to the webfake site.



Wrapping Up the Process
Once all of the information has been collected, the Bot API sends a Validation Type 96 request to the proxy server: However, instead of a timestamp, the value being set in the registry is the string “true,” as highlighted below.
HKCU\Software\Classes\CLSID\{7570CC99-D32B-6883-1375-9D2881583EFB)
' registry key with the (Default
)value, set to a four-byte binary value. Once this is set, any further attempt to access bypasses any attempt to rewrite the URL (inject Types 50, 51, 52), and will load the legitimate website. To load the legitimate website, the page is refreshed and now the victim will be able to login to the legitimate cashanalyzer.com website. Of course, if any of the other webinjects match on the site, other actions will be taken (collecting account balance data, etc.).
How CrowdStrike Falcon® Prevent Stops BokBot
CrowdStrike® CrowdStrike Falcon® Prevent™ next-generation antivirus successfully stops BokBot when process blocking is enabled, as explained in the following. BokBot spawns a svchost child process, injects the main module, and that svchost process spawns and injects into multiple child processes. The process tree in Figure 8 is an example of what BokBot looks like when viewed using Falcon Prevent with process blocking is disabled. As shown below, several malicious child processes were launched by BokBot’s main module, located inside of the first svchost process.
Suspicious Process Blocking
Falcon has the capability to prevent the execution of BokBot’s main module and all of the child modules. Turning on process blocking in Falcon Prevent kills the BokBot infection at the parent svchost process. Looking at the process tree in the Falcon UI with process blocking enabled (Figure 9), an analyst sees that the svchost process was prevented. The block message (Figure 10) that occurs with this preventative action explains why this process was terminated.

Indicators
BokBot Hashes
The following hashes were used in creation of this blog post.File Hash | File |
87d37bc073d4d045d29e9c95806c7dcf83677697148e6b901c7a46ea7d5f552e | BokBot Container |
2c331edaadd4105ce5302621b9ebe6808aecb787dd73da0b63882c709b63ce48 | BokBot Container |
7e05d6bf0a28233aa0d0abfa220ef8834a147f341820d6159518c9f46f5671b7 | BokBot Container |
961f7bada0c37c16e5ae7547d9b14b08988942af8d4a155ad28e224ece4fa98e | BokBot Container |
c992229419759be2ecaddcfd2d0ce26ce3cddca823a4c4875564316b459b05eb | BokBot Container |
88e41cc6bd4ec57bcabf67f15566475e1ee3ff7667b73f92ac81946f8564e6d9 | BokBot Proxy DAT |
ec205babdc4422888c3c29daa2f3d477315a2a136a2bd917947cd2184cdce406 | BokBot Proxy DAT |
File Locations
Path | Details |
%PROGRAMDATA%\{UUID}\.exe | Bokbot main binary |
%PROGRAMDATA%\}\.dat | Bokbot DAT File |
Registry
Path | Details |
HKCU\Software\Classes\CLSID\{UUID) | Block Site and Rewrite bypass data |
Network Listeners
Port | Service Name | Details |
TCP 57391 | svchost.exe | Proxy Server Port |
Attacker Controlled Sites
Hostnames |
segregory<.>com |
tybalties<.>com |
waharactic<.>com |
ambusted<.>space |
overein<.>space |
exterine<.>space |
stradition<.>space |
stocracy<.>space |
ugrigo<.>space |
yorubal<.>space |
portened<.>space |
coultra.space |
parchick.space |
exhausines.space |
haractice.space |
acquistic.space |
Additional Resources
- Learn about the collaboration among eCrime groups that may be driving these attacks: "New Evidence Proves Ongoing WIZARD SPIDER / LUNAR SPIDER Collaboration," and
- Download the 2021 CrowdStrike Global Threat Report
- Download the 2018 CrowdStrike Services Cyber Intrusion Casebook and read up on real-world IR investigations, with details on attacks and preventative recommendations.
- Learn more about CrowdStrike’s next-gen endpoint protection by visiting the Falcon platform product page.
- Test CrowdStrike next-gen AV for yourself: Start your free trial of Falcon Prevent™ today.