The Emotet family could not do what it does without receiving a constant stream of instructions from its owners, or in the absence of the detailed level of feedback about its operating environment each bot sends home from an infected host machine. It also uses huge numbers of compromised websites that belong to other people or businesses to host copies of its main executable. These files get taken down quickly, so the network is in a constant state of flux.
In many ways, the entire operation of Emotet hinges on the bot being able to send and receive regular installments of data and feedback, instructions and results, payloads and signals about task completion. If the bot cannot connect, it cannot do its job.
Each Emotet binary communicates with its command-and-control (C2) server in unusual ways, in some cases by using conventional network protocols in ways they were never intended. Emotet has a tendency to rely on the use of compromised, legitimate websites for hosting the malware itself, but it uses servers under the direct control of the botnet operators to receive messages from, and send instructions to, each node on the botnet.
Emotet typically uses the HTTP protocol to exfiltrate stolen data or receive instructions, but it does not strictly follow the conventions of that protocol, nor does it transmit that information in the clear.
The malware encrypts all the data it will transmit using a two-stage process, which it then transmits over unencrypted HTTP. It performs these communications with its C2 servers by performing an HTTP GET request that includes the passing of the data in the guise of a browser cookie. The header The server may respond with a simple acknowledgment or with a longer set of instructions or commands.
Here is an insider’s look into how Emotet communicates with its C2 servers.
Emotet phone home
Emotet periodically queries the list of running Windows processes and sends it to the C2 server. This routine serves as a good example of how the malware encrypts the data, transmits it, and interprets the results.
Emotet gathers some information about the infected system, and then serializes that data using protobuf.
The malware uses certain constants (highlighted in red) to “sign” the formatted package of data it will exfiltrate (circled in blue). The data masked by a grey bar contains the computer name and the volume serial number of the infected system, hidden here to make it more difficult for the Emotet operators to identify our test system.
Here’s what those highlighted constants indicate:
after 0x08: The byte after 0x08 is set to 0x00 when the initial API loading (crypt32.dll, urlmond.dll, user32.dll, userenv.dll, wininet.dll, wtsapi32.dll) is successful. After the first network communication, the bot increments this value, like an odometer, with every successive communication.
after 0x12: The number that immediately follows the 0x12 (the first blue highlighted byte) is the length, in bytes, of a concatenation of the computer name and volume serial number information (derived from the GetVolumeInformationW function, lpVolumeSerialNumber) separated with an underscore, eg., computername_volumeserialnumber. The actual concatenation follows the length.
after 0x18: The three bytes here is calculated from the native system information (RtlGetVersion, GetNativeSystemInfo)
after 0x20: The session ID from the Process Environment Block (PEB)
after 0x2D: CRC value (generated by RtlComputeCrc32) of the Emotet executable
after 0x32: the comma-separated list of processes. (generated by Process32FirstW, Process32NextW) This section is terminated in the highlighted byte 0x3A at the end of the screenshot.
Encrypting the message
Once the above data structure is complete, Emotet serializes the data using protobuf, before compressing with zlib (and serializing again). Then it encrypts the message. The Emotet binary contains an RSA public key, which it uses with the CryptGenKey function call to generate an AES 128 symmetric encryption key pair.
Emotet encrypts the data block using this key, then encodes the encrypted data in base64, and finally transmits it by performing an HTTP GET request to the root directory of the C2 server. The malware actually transmits the data by attaching it as a “cookie” to the HTTP request headers (shown below), thereby making the “content” of the HTTP request empty.
The C2 servers can receive these communications on port 80, which is the default port for HTTP, but may also receive them on port 443, which is the default for HTTPS traffic, or on a number of other nonstandard ports, including but not limited to 7080, 8080, 8090, 50000, or several others. The table above shows the frequency breakdown of ports used by Emotet for command and control, taken from a sample set of about 3000 Emotet executables.
User tips for detecting Emotet network traffic
Unencrypted HTTP traffic requests, with empty content and no exchange of SSL certificates, to ports normally used by HTTPS may indicate the presence of Emotet in your network.
HTTP traffic to other ports normally used by standard services, such as DNS (53) or SMTPS (465) is another red flag.
Empty (no content) HTTP GET requests with the unusually long cookie header, sent directly to internet IP addresses (as opposed to domain names), may be another.
The response from the C2 server contains an encrypted blob of feedback, which the malware needs to decrypt and verify before it will act upon the instructions. The response to the transmission shown above contained an updated version of the Emotet malware application, itself, which the malware decrypted and then launched. The updated build of Emotet then supplants the prior build, and deletes the older version of the malware.
SophosLabs researchers Anand Ajjan, Krisztián Diriczi, Anton Kalinin, and Luca Nagy contributed to this section of the report.