Conficker’s virtual machine detection

Image (1) conficker-other-vm-detection.png for post 20008

The Internet Storm Centre blogged back in February about how the startup code of Conficker would do a quick check, using the SLDT instruction, to see if it was running in a virtual machine. If so, it would Sleep() forever and take no further action. The most recent variant of Conficker, detected by Sophos as Mal/Conficker-B, also does this check — but that isn’t quite the full story. Deeper within the obfuscated code in Mal/Conficker-B is an extra set of virtual machine detection tests.

Conficker's other VM detection tests

One interesting thing here is that Conficker doesn’t bail out if any of these detect that it’s running inside a virtual machine. Instead, for each test Conficker will set a bit in a bitfield to specify whether the test “passed” or not. This bitfield is within a data structure to which Conficker also saves information about the operating system version and the language ID of kernel32.dll on the Windows drive. This set of data seems to be used when Conficker initialises its peer-to-peer communications — the most obvious explanation would be that the owners of the Conficker botnet are harvesting that data to get a better idea of the computers they have available.

Still more interesting is another VM detection test that Conficker does in the same function. This is a variant of what’s sometimes known as the Red Pill detection method using the SIDT instruction. Trawling through our database of malicious code I managed to find almost exactly the same implementation in an old Trojan from 2006 which we detected as Troj/Agent-DJQ. This is actually part of the malware family known to different vendors as either LinkOptimizer, Stresid or Gromozon. The family is detected generically by Sophos as Mal/LinkOpt-A.

Take a look at this code from Conficker:

Conficker's SIDT detection loop
Mal/Conficker-B SIDT detection loop

And compare with this code from the LinkOptimizer variant:

Troj/Agent-DJQ SIDT detection loop
Troj/Agent-DJQ SIDT detection loop

The only practical difference between these two implementations is that the LinkOptimizer version will wait for an extra third of a second before deciding that it isn’t in a VM. That isn’t the only similarity, however.

Both of these samples share almost exactly the same “spaghetti code” obfuscation method, where functions and basic blocks are split up with direct and indirect jmp instructions — though in Conficker the system seems to have been toned down a little so that, on average, there are a few more instructions per “slice” between jmps (possibly an attempt to make the technique harder to detect generically). This trick is commonly used in malware, but the implementation of it is almost identical between LinkOptimizer and Conficker.

There have also been reports of the earliest variants of Conficker being mislabelled as LinkOptimizer by some vendors’ anti-virus products — though it’s not clear whether this was due to generic detection code designed to spot this kind of obfuscation or simply a misclassification by the vendors when analysing samples. In any case, I don’t think it would be a stretch to suggest that Conficker and LinkOptimizer might have been written by the same people.

Sophos is continuing to analyse Mal/Conficker-B and we intend to publish more information soon. People looking for details on this threat can read our virus description and Mike Wood’s blog post regarding the worm’s new call-home functionality. There is also a detailed analysis of the latest variant available from the SRI Malware Threat Centre.

For anyone looking to remove a Conficker infection, the Sophos Conficker clean-up tool is available to do just that!