W32.Virut is a Windows file infector that’s been around since 2006. It usually makes the top 10 in threat charts and therefore deserves regular scrutiny.
Analysis of recent variants show that changes were made to strengthen the communication protocol between the bots and the command and control server to prevent blacklisting, sinkholing, and hijacking of their command and control servers.
Virut connects to one of two IRC servers that act as the command and control servers (C&C) (note that they are currently ilo.brenz.pl and ant.trenz.pl). The IRC commands are usually encrypted and tunneled over TCP ports 80 or 443–used by HTTP and HTTPS respectively. The main commands sent by the C&C instruct bots to download and install additional malware.
Because these domains can be blacklisted or blocked, the first improvement was the addition of a domain name generator used to find new C&C candidates, should the hardcoded domains be unreachable. The technique is not new; several malware used it in the past, including the infamous Downadup and Mebroot.
The domain generator uses two seeds:
- The day’s date, supposedly common across all machines.
- A random integer C in the range [0, 99].
For each C, 100 domains in the form of “[6-alpha-chars].com” are generated. Overall, up to 10,000 domains can be generated daily. This compartmentalization has the inconvenience in that the operators need to register 100 domains (1 for each compartment) in order to migrate all bots. The main advantage for the malware controller is the great number of domains one would need to block in order to stop all bot communication with the C&C.
In case the auto-generated domain happens to already be registered by some unrelated third party, Virut performs an initial verification step to ensure the server is a Virut C&C. The server is queried on TCP port 443, and expected to return a 256-byte long blob of data. This data is the signed SHA-256 hash of the domain itself. The bot decrypts the blob using the 2048-bit RSA public key embedded in its code. Therefore, no one but the holder of the private key can generate the signed blob used to authenticate a domain.
Figure 1: Assembly code showing the RSA public key used by Virut
The following diagram summarizes the exchange taking place between a bot and a C&C candidate in order to authenticate itself:
Figure 2: Domain generation and validation
However, note that this check is mainly used to avoid accidental connections to non-Virut servers. While the check would prevent domain hijacking before the domain was utilized by the Virut controllers, this check does not prevent domain hijacking after the server is already being used as a C&C, since the hijacker can simply replay the signed domain hash.
Thus, the Virut creators needed to implement additional checks to prevent domain hijacking. New variants give the C&C a 30-second window for authentication purposes. If the authentication succeeds, the bot will accept and process commands sent by the server. Otherwise, the connection will be terminated.
- First, the bot expects a PRIVMSG command containing the server’s timestamp and a signed data blob.
- The signed blob contains the encrypted timestamp as well as the encrypted server’s IP address.
- Using the RSA public key, the bot decrypts the blob, and the decrypted timestamp and IP address are expected to match the plaintext timestamp and current server’s IP address.
- If there’s a mismatch, the authentication fails.
- Else, the bot checks the returned timestamp against its own system time. The authentication is considered successful if the server’s timestamp is in the +/- 3 days range.
Whereas a challenge/response mechanism would have been simpler and secure, Virut’s implementation is complicated and flawed.
The signed timestamp was meant to avoid replay attacks on the authentication scheme. However, the 6-day delta gives anybody a great length of time to issue downloadand execute commands, potentially taking over the botnet as commands are only symmetrically encrypted. I can only assume that the authors decided to add the server’s IP address in the blob for extra security. Indeed, taking over the DNS and using the same IP is more challenging, but not bullet-proof. And the 6-day window could then be exploited. (Note: The assembly implementation of the blob validation routine seems patchy. A 4-byte extra check takes place after validation, likely added to accommodate the IP address check. This can be seen in figure 1, on line stating “extra DWORD check”.)
Asymmetric cryptography used in malicious programs is becoming more and more frequent. The usage varies greatly. For instance, it can be used to authenticate hosts, to validate payloads, or to protect symmetric encryption keys (as some ransomware do). It could also be used as a very strong obfuscation mechanism in the case of targeted attacks.
From the perspective of the antivirus industry, asymmetric cryptography can be a plague. However, the protocol and implementation are as critical as the algorithms themselves. In the case of Virut, the end-result may be effective, but the protocol is not. Hopefully, there will always be cases of poor implementation that allow the security industry to break malicious creations.