In mid-2020, researchers detected multiple campaigns, which were later attributed to the Gelsemium group, and tracked down the first version of the malware used by the group, dating back to 2014. The victims of these campaigns are located in East Asia, as well as in the Middle East, and include governments, religious organizations, electronics manufacturers, and universities.
Main points in this research:
The entire Gelsemium chain may seem simple at first glance, but the extensive configurations, implemented at each stage, modify the configuration for the final payload on the fly, making it more difficult to understand. The behaviors discussed below are tied to configuration.
Therefore, filenames and paths may be different in other samples. Most of the campaigns we observe follow what we describe here.
Gelsemium employs three components and a plugin system that offers operators different options for collecting information: the Gelsemine dropper, the Gelsenicine loader, and the Gelsevirine main component.
First, the dropper is written in C++ using the Microsoft Foundation Class (MFC) library and contains multiple binaries from other stages. The size ranges from 400k to 700kb, which is unusual and would be even larger if the eight embedded executables were not compressed.
In this sense, the developers have used the statically linked zlib library to reduce the overall size, hiding behind each executable a complex but flexible mechanism capable of releasing different stages depending on the characteristics of the victim's computer, such as the number of bits or privileges.
Almost all stages are compressed and located in the resource section of the PE and mapped into the same memory address space of the component.
For its part, the second step is the loader (loader), a loader that recovers Gelsevirine and executes it, having two different versions (both are DLLs), which differ in the context in which it is executed, depending on whether it is from an administrator or a user with compromised standard privileges.
Finally, the main plugin is the last stage of the chain, which has the peculiarity that if the defenders manage to get this last stage alone, it will not be executed, since it requires that its arguments have been configured by Gelsenicine. The configuration used contains a field called controller_version is the versioning used by the operators for this main plugin.
Gelsenicine is a loader that retrieves Gelsevirine and runs it. There are two different versions of the loader: both are DLLs; however, they differ in the context in which Gelsemine is run.
For victims with administrator privileges, Gelsemine drops Gelsenicine to C:\Windows\System32\spool\prtprocs\x64\winprint.dll (user-mode DLL for the print processor) which is then automatically loaded by the Windows spoolsv service. To write a file to the %WINDIR%/system32 directory, administrator privileges are required; hence the requirement mentioned above.
In the case of users with standard privileges who are compromised by Gelsemine, Gelsenicine is dropped into a different directory that does not require administrator privileges. The DLL chrome_elf.dll is dropped in CommonAppData/Google/Chrome/Application/Library/.
The Gelsemium biome is very interesting: it shows few casualties (according to our telemetry) with a lot of adaptive components. The plugin system shows that its developers have a deep understanding of C++. Minor similarities to known malware tools shed light on possible relationships with other groups and past activities. We hope that this investigation will prompt other researchers to post about the group and reveal more roots related to this malware biosphere.