Return of the Festi Rootkit
Festi, a once popular rootkit is back in the wild, distributed mainly by the RIG exploit kit.
A long known Windows rootkit, Festi dates back to 2009 where at that time it served as a bot, forming a large and successful botnet utilized both for DDoS and distribution of spam mails. It was previously researched by ESET, which published a thorough analysis of its internal workings back in 2012.
Since then, after the arrest of its author and operator, Igor Artimovich, by the Russian authorities, Festi has been dormant. The arrest occurred following an investigation of a DDoS attack carried out by the botnet against the Aeroflot website in 2010. Igor, who was known by the nickname “Engel” in underground forums, was sentenced to two and a half years in prison, with a release date of August 2016. Since the arrest, the botnet was taken down and there have been no signs of its activity up until now.
The new variants of Festi are accompanied by a tricky new dropper that masquerades as an Adobe Flash Player update in order to elevate privileges. It is also interesting to note that the new rootkit variant contains quite a few changes in the code, suggesting that the current operator has access to Festi’s source code.
Taking all this into account, the sudden re-emergence of Festi raises questions regarding the identity of the operator behind it. Is it possible that the original operator is back to his old tricks after his prison release, or has the source code been sold or stolen?
Figure 1: Our telemetry shows a few thousand infections of Festi,
most of them occurring in Turkey and Brazil.
The dropper is responsible for decoding and installing the rootkit driver that resides encoded inside it. In case the dropper doesn’t have the required privileges to install the driver, it uses a devious social engineering technique in order to elevate its privileges and “bypass” UAC. It displays an authentic looking Abode Flash Player updater window, baiting the user to click ‘Install’ in order to ask for elevated privileges via UAC.
Figure 2: The Festi dropper displays an authentic looking Abode Flash Player updater window, baiting the user.
While this technique is not new, the level of authenticity seen here is quite impressive. The fake installation window contains links such as “See Details…” and “End User License Agreement” which point to the real Adobe website. Additionally, if the user clicks “Remind Me Later,” the dropper exists and deletes itself, implying the operators prefer caution over additional infections.
After gaining privileges, the dropper opens an event named “Global\\irp65289”. It then extracts the rootkit that was embedded in the data section and decrypts it. The rootkit is saved as C:\Windows\system32\drivers\serial<random_number>.sys, and then loaded as a kernel driver, using the WinAPI functions “CreateServiceA” and “StartServiceA” which are resolved at runtime.
Finally, before terminating, the dropper writes a “cleanup” bat file into %TEMP% directory with a random name and executes it. The bat file’s job is to delete the dropper file and then delete itself.
The Festi Rootkit
The rootkit is written in C++ and operates as a kernel mode driver that is launched amongst the standard system drivers during startup. It is fairly sophisticated, especially for its time, employing tricks to evade endpoint security products. It has a modular design; supporting different plugins that allow it to customize functionality. A deep technical analysis for the older variants can be found in ESET’s publication.
The latest observed samples, however, show some changes in code from the ones inspected by ESET. On the surface, a simple code comparison against the older variants shows little matching code, and a lot of differences. Upon closer inspection however, it seems that the core logic is mostly still the same. The discrepancies seen in pieces of code which serve the same purpose in both binaries indicate that it’s likely that the malware code has been recompiled. There are, however, quite a few changes made to the functionality itself. Some of these are outlined below.
First of all, looking at the DriverEntry function of both binaries we can see a very similar flow, whereby the malware does some initializations that are required for its functionality. These include a decryption of an embedded configuration section, assignment of a dispatch routine for all major functions (other than IRP_MJ_POWER and IRP_MJ_SHUTDOWN), attachment to the SystemRoot device so as to intercept any IRP prior to it being passed to subsequent filter drivers and initiation of the malware’s main worker thread.
In spite of this, the differences are evident. For one, the older version contains anti-vm checks (one for VMWare and another for Virtual PC) as well as a check for the presence of the Network Packet Filter driver (npf.sys) used by Wireshark. These are not included in the new version and suggest that they were either omitted on purpose, or an older code base was used during compilation of the recent samples.
Figure 3: Some of the similarities (highlighted in gray) and differences in the old & new Festi DriverEntry functions.
Likewise, both versions contain a check for the presence of an attached debugger. This is done by inspecting the KD_DEBUGGER_ENABLED global variable. However, the older version has an additional check to see if it can access the \Driver\NTICE object, which corresponds to the SoftICE debugger. Once again, this check is absent from the newer version.
Figure 4: Comparison of the anti-debugging
checks in old & new Festi samples.
Another similarity that can be witnessed is in the structure of the DGA function, which is a fallback mechanism if the hardcoded C&C domain is not responding. As can be seen in the diagram below, the overall algorithm is the same. The function takes a struct that represents a date as a seed, and creates a 12 character .com domain based on it. Each seed value is transformed into a character using predefined mappings in the chr_decode_func_X functions. If we look closer though, we can see that while the order of the calls to the mapping functions remains the same, the order of the seed arguments changed in the new version. Also, the mappings themselves changed, as can be seen in the compared chr_decode_func_0 functions. Finally, the newer version incorporates a xor operation of a stack DWORD with the BugCheckParameter2 variable, used in KeBugCheckEx function. This further emphasizes the fact that this particular function was recompiled.
Figure 5: DGA algorithm in both versions of Festi.
Finally, a function that was fully altered is the configuration section decoding function. This section is embedded within the .cdata section in the driver’s image, and is decoded during run-time so as to host the majority of strings used by the malware throughout its execution. An example of such section can be seen below, and contains strings for devices, C&C domains, function names, registry keys etc.
Figure 6: Decoded .cdata section
While the old Festi samples xored the whole section with a hardcoded DWORD, the new variants use an inline implementation of crand() to generate a key stream that gets xored with the encoded data.
Figure 7: different implementations of the .cdata decoding algorithms.
As already mentioned, these changes suggest that someone is in possession of Festi’s original source code.
The return of the Festi rootkit, after being gone for so long, is quite surprising. The operation so far indicates the current operator is cautious and prefers to stay under the radar. Additionally, the technical analysis indicates the current operator probably has possession of the source code, whether he is the original author or not. Still, it is too early to tell if this is just someone playing around with an old malware, or the start of a whole new chapter for Festi.