Backdoor.Prioxer!inf: “Accidentally” the Stealthiest File Infector Ever!
Following the Trojan.Koredos incident, we stumbled upon a very interesting back door Trojan—Backdoor.Prioxer. We received this Trojan from a source that was also infected by Trojan.Koredos, and although we cannot prove a direct link between the two, we believe it is likely that both threats derive from the same source.
You can read more details about Trojan.Koredos in our previous blog entry. Briefly, Koredos is a threat that was used in a targeted attack against several Korean websites. The Trojan shows a modular architecture and a level of sophistication that suggests the attack is coming from a well-established malware source.
Why is Prioxer interesting? Well, at first glance it looks like a normal back door Trojan, which, in fact, it is. The installer drops a .dll file that is the botnet component. The bot operates via IRC in order to exchange commands and data with the command-and-control (C&C) server. The threat files are not even encrypted or obfuscated. Furthermore, in order to survive a reboot of the computer, it infects a Windows system .dll file. The .dll file is then loaded whenever Windows starts and the payload of the threat loads the botnet .dll file again. Nothing new there, save one thing of particular note—the infected files are completely invisible!
Very invisible infection—an accident?
Prioxer does not use rootkit functionality, nor does it use any code in kernel mode. How is it possible to achieve such invisibility from a simple application? It succeeds in evading a number of security tools, with the exception of one anti-rootkit tool that is able to extract the infected .dll file by using its own file browser utility.
A closer look at the infector code solves the mystery:
Figure 1: The code determines whether the disk volume is FAT32 or NTFS and runs its own custom file system interpreter.
The main dropper has its own built-in parser for the FAT32 and NTFS file systems. The code opens the C volume in raw mode, performs a manual read of disk sectors, and then manually parses the disk data in order to understand the file system structure and find where in the disk the infection target .dll file is located (and perform a raw write operation to infect it). This whole functionality normally resides in the file system layer in the kernel. An application specifies a file path and the file system driver (NTFS on most Windows computers) locates the file data on the disk. Prioxer is able to do all of this by itself, bypassing the file system layer completely and accessing the disk directly.
By infecting the .dll file in raw mode, the Trojan is able to bypass filters or restrictions on the file itself. This is not really new or ground breaking because threats possessing raw access to hardware resources are quite common.
Nonetheless, there is another interesting thing that comes into play: caching. The NTFS file system driver maintains a cache of the most frequently read files (and a Windows .dll file is likely to belong in this category) in order to speed up performance. Whenever you modify a file that is cached, NTFS should update the memory cache to reflect the file changes. Instead, Prioxer writes to disk, directly bypassing the file system layer completely. In this way, NTFS does not know that a system .dll file present in the cache has been modified and will not update the cached version of the file.
Figure 2: The infected .dll is on the disk, but the NTFS cache is providing the clean .dll instead, rendering the infection invisible.
This leads to an inconsistent situation. The cached .dll file is the clean one, but the infected one is actually on the disk. This means that if you try to access the infected file from any application, or even from Kernelmode drivers, you will access it through the NTFS layer and NTFS will return the data of the clean version of the .dll file. Therefore, the real infected .dll file is on the disk and invisible!
Notice that this behaviour is not a bug, nor is it a flaw in the NTFS design. The cache is simply working the way it is supposed to. The infected file can of course be accessed by any utility that can operate at a lower level than the NTFS file system. Also, the cache is not permanent, so the system may eventually end up refreshing the cached infected file, rendering it back to visible (for example after a memory stress condition, or simply after reboot).
Figure 3: The infection code in the targeted DLL.
Given that Prioxer does not really try to actively hide itself, it is possible that this invisibility feature was not intended by the malware authors. It is just a handy side effect of misusing the system’s functionality. However, this example shows that this technique could be very effective if abused, and it can be run from Usermode without requiring the use of kernel drivers (which rootkits normally need).
The payload is a simple bot that operates via IRC protocol. The bot can exchange data with the C&C server in the form of chat messages, like any other standard IRC backdoor. I joined the C&C server and got some interesting information:
PASS [removed] NICK [nick] USER nobody unknown unknown :noname :MyWebServer 375 [nick] :- MyWebServer Message of the Day - :MyWebServer 372 [nick] :- This is ircd-hybrid MOTD replace it with something better :MyWebServer 376 [nick] :End of /MOTD command. VERSION :MyWebServer 351 [nick] hybrid-7.2.3(SVN). MyWebServer :egIKMZ6 TS6ow USERS :MyWebServer 265 [nick] :Current local users: 46 Max: 53 :MyWebServer 266 [nick] :Current global users: 46 Max: 53 LIST :MyWebServer 321 [nick] Channel :Users Name :MyWebServer 322 [nick] #mail01 5 : :MyWebServer 322 [nick] #god8 1 : :MyWebServer 322 [nick] #god2 8 : :MyWebServer 322 [nick] #god3 1 : :MyWebServer 322 [nick] #god1 2 : :MyWebServer 322 [nick] #god4 1 : :MyWebServer 322 [nick] #kkk3 4 : :MyWebServer 322 [nick] #kkk2 19 : :MyWebServer 322 [nick] #kkk1 8 : :MyWebServer 323 [nick] :End of /LIST LUSERS :MyWebServer 251 [nick] :There are 0 users and 47 invisible on 1 servers :MyWebServer 254 [nick] 9 :channels formed :MyWebServer 255 [nick] :I have 47 clients and 0 servers :MyWebServer 265 [nick] :Current local users: 47 Max: 53 :MyWebServer 266 [nick] :Current global users: 47 Max: 53 :MyWebServer 250 [nick] :Highest connection count: 48 (48 clients) (265 connections recei ved) STATS :MyWebServer :MyWebServer 212 [nick] JOIN 313 1589 :0 :MyWebServer 212 [nick] NICK 270 4658 :0 :MyWebServer 212 [nick] PASS 271 3794 :0 :MyWebServer 212 [nick] PRIVMSG 4238 2345746 :0 :MyWebServer 212 [nick] USER 269 8070 :0 :MyWebServer 212 [nick] WHOIS 234 8520 :0
Figure 4: Some snippets of the data log from the IRC C&C server. The USERS command shows the number of users over a period of time. LIST shows the available channels and how many users are on them. STATS shows how many times commands have been used in the server.
I issued standard IRC commands to obtain lists of statistics and the number of users. From the STATS command we can see some global counters of how many times the commands have been executed (the second number after the command name). We can see that JOIN, NICK, PASS, and USER commands (normally used by bots to authenticate themselves and join a channel) are more-or-less consistent, and are in the order of several thousand. Of course, this is the total number including non-bots, so it is reasonable to estimate that the total size of this botnet could be roughly 100, which makes it relatively small. This doesn’t come as a surprise, since we mentioned a possible link with the Koredos threat. Knowing that it was a targeted attack, it is unlikely to be widespread.
Although we are focusing on its invisibility, the threat does not seem to do this intentionally, as mentioned above, nor does it take any action to actively hide itself. Therefore, the cache trick only works for a limited amount of time. As a defence, a computer can be simply rebooted and then the malicious infection will be visible and detected by security products. If the computer has been running long enough after infection, there are also good chances that the infection will be visible due to a refreshed cache.
It’s a clever, though likely unintentional, ruse. Regardless, customers that update to the latest virus definitions will be protected from this threat.