W32.Sality is a family of file infectors that’s been around for a long time. It seems the virus first appeared back in 2003, originating in Russia. At that time, Sality was a file infector that prepended its viral code to a host, and had back door and keylogging facilities.
Nowadays, Sality’s “signature” remains the same—virus and Trojan capabilities—but it includes more features to facilitate propagation, assure its survival, and performs the dirty jobs. Among these capabilities is the decentralized peer-to-peer network (P2P) that Sality-infected computers create and populate, which I’ll introduce later on.
Sality is an entry-point obscuring file infector. Infected files will have their original, initial instructions overwritten with complex code, with an end-goal of reaching the viral body code and executing it. This body code is located in the last section and is encrypted. Once decrypted and executed, a separate thread is created to carry the virus payload memory mapping and execution. This payload is Sality itself. Let’s review its features.
The payload runs five distinct components in separate threads. The first component is a process injector. All processes—except those belonging to the users “local service”, “network service”, or “system”—will be injected with a copy of Sality to make sure the malware stays running.
The second component is responsible for lowering or disabling the general security of the system. Security-related processes and services are stopped, including many antivirus and personal firewall products. The registry is modified and SafeBoot key entries are deleted. Components such as registry editing with the Windows regedit.exe tool or Task Manager creation are disabled. Firewall rules are added to let Sality access the network and the Security Center, among other things, is disabled.
Sality also drops a kernel driver to a dynamically generated location in %System%\drivers and creates a service named “amsint32”. This driver is a rootkit in charge of two things. First, it ends processes should a regular call to TerminateProcess() fail, as instructed by the user-mode part of Sality. In fact, the rootkit is able to run dynamic code on to a target process, but so far this code only concerns process termination.
The second feature is more interesting: the driver sets up an IpFilter callback function to process network packets. Ipfltdrv.sys is a standard Windows driver that can be loaded by starting the IpFilterDriver service. Kernel drivers can set a callback function to be called by IpFilter every time an IP packet goes in or out. The callback can decide to drop the packet. In a few words, IpFilter is a very straightforward way to build a simple Windows firewall. Sality uses the IpFilter to drop every IP packet containing words that belong to an encrypted list of strings that make up security vendor’s URLs. The user-mode process can also instruct the driver to drop SMTP packets, blocking traditional email exchange.
The third component is the infector itself. Sality is able to infect files on local drives as well as Windows shares. It also infects files referenced in the HKEY_CURRENT_USER\Software\Microsoft\Windows\ShellNoRoam\MUICache registry key, which references the most often-used executables on the system, as well as .exe files located in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run and HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run. Note that the infection routine is careful enough to check that a file is not protected by the Windows file protection mechanism (SFC) before trying to infect it.
Let’s move on to the fourth component: the downloader. Downloading and executing other malware or security risks is the end goal of Sality. A compromised host carries with it a list of HTTP URLs that point to resources to be downloaded, decrypted, and executed. These URLs can also point to more URLs. The encryption used is RC4 with static keys embedded in the compromised host. The question is, how are the URLs updated in case some of them get blocked, or more simply, if the malware gang decide to have Sality download other components?
The answer is given by the fifth and final component: its peer-to-peer client and server code. Sality-infected hosts thus become bots of a P2P botnet.
The protocol used is fairly simple and likely built in-house. Packets are encrypted—RC4 again, dynamic key this time, comprising the packet payload data hash and size—and transported over UDP.
A host first picks a semi-random port above 2200, which will be used by the server to listen for incoming client queries. The initial peers contacted by a host are found in a bootstrap list embedded in the virus. This list contains at most 1000 entries, to maximize the chances to find at least one valid peer.
The goal of the P2P network is to exchange list of URLs to feed to the downloader. The P2P protocol offers only a few commands, the most important being:
- Ask a peer for its list of URLs (‘URL package’)
- Give a peer its own URL package
- Ask a peer to send the IP address and port of another peer in the botnet, in order to keep the list of peers up-to-date
We can imagine that, hidden among the peers, are Sality servers that regularly inject new URL packages. A URL package contains metadata, including a sequence ID—only packages with an ID greater than what the host currently has will be “installed”. Also, the packages are digitally signed with RSA 1024 bits in order to prevent hostile URL package injection in the botnet or a botnet take-over by other malware gangs or security researchers.
Upon initial connection to a peer, a client will send a “hello” packet, indicating it would like to receive a URL package. A P2P packet includes a field that indicates which URL package ID the bot is using. The queried peer will check that field and only serve its URL package if it’s newer than the client’s ID. Likewise, the client sends its own package to the server if it detects that the server’s package is older than its own.
The client then sends its information: the port number it’s listening to. In response, the server will generate a client ID, whose validity depends on the client’s response to a “send me your URL package” query. If the client served a malformed packet (not compliant with the protocol format), the ID it will get and be assigned will be considered bad. Other peers the client will communicate with will see this ID, and eventually not store it in the peer list. This mechanism is a simple, yet efficient way to clean the initial bootstrap list. There is another mechanism, less aggressive this time, to slowly discard unresponsive peers from the list.
As mentioned above, the last functionality offered by the protocol is a request for peers. The peer list contains at most 1000 entries. As long as the client has less than 980 valid peers, it will regularly ask for extra peers. This mechanism allows Sality to have a constantly updated list of peers, which is essential for efficient propagation of URL packages.
Because the P2P botnet uses the UDP protocol and listens directly on to a network interface, having an infected host hidden behind a NAT or firewall (such as in corporate environments or even at home), it will effectively disable the server part of Sality, which means it won’t be able to serve its URL package. However, it will not prevent Sality from querying the botnet and asking for URL packages.
Finally, the file infector component mentioned earlier will always embed the updated list of peers in files it infects. The updated list is also encrypted and stored in the registry.
Sality is a complex and complete threat. It has it all: advanced file infector, efficient security products disabler, and flexible and decentralized P2P capabilities to propagate URLs and avoid static DNS or IP lockdown by authorities. Altogether, these three factors make Sality a very dangerous threat, likely to remain around for a while.