IBM TechXchange Korean CyberSecurity User Group (한국 사이버보안 사용자 그룹)

 View Only

코드 중복과 유사성을 통해 본 램닛 멀웨어

By Gwibin Im posted Fri August 26, 2022 03:38 AM

  


램닛에서부터 범블비까지 (네버퀘스트를 거쳐): 코드 중복과 유사성을 통해 멀웨어 개발자들 간의 관계를 조명한다. 
From Ramnit To Bumblebee (via NeverQuest): Similarities and Code Overlap Shed Light On Relationships Between Malware Developers


  IBM 보안 X-Force 팀은 작년에 처음 나타났던 범블리 멀웨어가 램닛 뱅킹트로잔과 소스코드를 기반으로 개발되었을 것이라는 비교분석의 증거를 제시하였습니다. 최근에 공격캠페인 활동에서 지금까지와 전혀 관련성을 찾지 못하었던 ITG23 위협그룹의 관계자들과 범블비와 관련되는 연결고리가 있다는 점이 가장 놀랄만 한 것 입니다.

  올해 ITG23 그룹은 격동의 한 해를 보내고 있습니다. 이 그룹은 콘티유출과 트릭유출이라고 불리는 유명한 유출공격으로, 그룹의 많은 구성원들의 정보가 유출되고 수천개의 메시지가 공개 되는 어려움을 겪었기 때문 입니다. 더욱이 이 그룹은 그들의 가장 유명한 멀웨어 집단 2곳인 트릭봇과 바자르의 문을 닫고 나서도, 콘티 랜섬웨어 공격그룹도 운영을 하지 못하게 되었습니다. 


 A comparative analysis performed by IBM Security X-Force uncovered evidence that suggests Bumblebee malware, which first appeared in the wild last year, was likely developed directly from source code associated with the Ramnit banking trojan. This newly discovered connection is particularly interesting as campaign activity has so far linked Bumblebee to affiliates of the threat group ITG23 (aka the Trickbot/Conti group), who are not known to have had a previous connection with Ramnit.
  This year has so far proven tumultuous for ITG23 – the group suffered a series of high profile leaks, referred to as the ContiLeaks and TrickLeaks, which resulted in the publication of thousands of chat messages and the doxxing of numerous group members. In addition, the group have seemingly retired two of their most high-profile malware families, Trickbot and Bazar, and shutdown their Conti ransomware operation.



  다양한 보안 보고서들로 알 수 있는 것은,  ITG23이 여러 개 파벌로 나뉘고, 일부 조직원들 전체가 다른 곳으로 이동하는 대규모의 인사이동이 있었다는 것 입니다. 범블비 안에 들어있는 램닛코드는 이러한 조직원의 이동흐름을 보여주며,  새로 시작되는 공격 캠페인을 수행할지 모르는 새 공격자를 추측할 수 있게 도와줍니다. 

  이 보고서는 이전에는 보고되지 않은 범블비와 램닛 멀웨어 간의 중복소스와 유사성에 대해 주목 하여 더욱이 2개의 범블비와 램닛 멀웨어의 관계에 대해 조사하였으며, 더불어 트릭못 멀웨어, 이제는 존재하지 않는 네버퀘스트 뱅킹 트로잔과의 관계도 함께 분석하였습니다.


  Various reports have suggested that a significant reshuffling of personnel may be occurring, with ITG23 splitting into several factions and some members moving on entirely. The appearance of Ramnit code within Bumblebee may be indicative of this flux and a sign that new alliances are being formed, which could be a prelude to new types of attack campaigns.
  This research highlights previously unreported similarities and code overlaps between the Bumblebee and Ramnit malware families. It also examines the links between these two malware families, ITG23’s Trickbot malware, and the retired NeverQuest banking trojan.




발견사항은 아래 내용을 포함하고 있습니다.

  • 범블비와 램닛간의 중요한 중복코드가 있으며, 이 코드가 같은 개발자에 의해서 공유되었지 모른다는 가능성
  • 범블비/래밋 멀웨어와 기존의 트릭봇 트러잔과 모두 에서 사용된 커스터마이징 된 코드 라이브러리를 통해, 이전부터 일어난 코드 공유 가능성에 대한 지표
  • 초기의 트릭봇 개발을 할 때, 네벌퀘스트와 트릭봇 개발자 간에 있을지 모르는 잠재적인 협업의 증거

아래 분석은 범블리와 램닛사이에 관찰된 눈에 띄는 점을 더 포괄적이면서도 세부적으로 다루고 있습니다. 구체적으로 이 이들이 트릭봇 뒤에 어떻게 연결이 되어서, 이제 더 이상 존재하지 않는 네버퀘스트 뱅킹 트로잔의 계보를 이어갈 수 있었는지에 대한 내용을 포함하고 있습니다. 

The findings include:
  • Significant code overlap between Bumblebee and Ramnit, suggesting they may share the same developer
  • A custom code library used in both the Bumblebee/Ramnit malware and Trickbot trojan, indicating possible historical code sharing
  • Evidence of potential collaboration between the developers of NeverQuest and Trickbot in the early days of Trickbot’s development

The analysis below provides further detail and explanations on the unique aspects observed between Bumblebee and Ramnit, and how they can be connected back to Trickbot and finally traced to their suspected origins within the retired NeverQuest banking trojan.






램닛에서 부터  / From "Ramnit" 


램닛은 2010년 부터 웜바이러스로 부터 시작된 오래된 멀웨어로, 모듈러 백도어와 뱅킹 트로잔으로 재빠르게 진화해 왔습니다.  램닛은 이후 몇 년간 널리 퍼져서 세계적으로 수백만 감영된 봇넷 시스템으로 커졌으며, 2015년도 초에는 유로폴이 폐쇠시킨 해커그룹의 대상이 되었습니다. 이 폐쇄로 인한 영향은 오래 지속되지 못하고, 2015년 말에 결국 램닛은 다시 돌아와서, 실제로 활동할 하기 시작하였습니다. 이렇게 이전 명성을 다시 얻기위한 노력을 하였으나, 다음해 다시 조용한 시간을 보내며, 공격 캠패인 활동을 하며 지내 왔습니다. 

Ramnit is an older malware that originated in 2010 as a worm and swiftly evolved into a modular backdoor and banking trojan. Ramnit spread prolifically over the next few years, growing into a botnet with several million systems infected worldwide until it was subject to a takedown by Europol in early 2015. The impact of the takedown did not last long and by the end of 2015 Ramnit returned and was once again in active development. The malware struggled to regain its previous momentum, however, and the following years were characterised by campaigns of activity followed by periods of quiet.



램닛은 2018년도 중반에 눈에띄게 발전을 하였는데, 이 때 중요 소스코드가 업데이트 된 것을 보여주면서, 2개월 안에 100,000 기기들을 감염시켰습니다. 새로 커스터마이징 된 후킹 라이브러리를 새로운 로드모듈에 광범위하게 추가한 이 소스코드는  AV회피와 페이로드 실행 2가지에 사용되었습니다. 또한 제우스에서부터 루아 스타일까지의 업데이트된 웹 인젝션은 새 이름이 카멜리아로 나타나서, 기존의 데메트라의 명칭을 대체하였습니다. 이러한 새로운 코드정비의 이유에 대해 알려진 바는 없지만 몇몇 연구자들은 아마 새로운 개발자가 들어와서 코드 스타일이 바뀌었다고 추측을 하고 있습니다.


A notable development occurred in mid-2018, when Ramnit relaunched, infecting 100,000 devices in two months, and demonstrating significant code updates. This included the addition of new loader modules which made extensive use of a custom hooking library for both payload execution and AV evasion; web injects were updated from Zeus-style to Lua-style; and a new name ‘Camellia’ appeared, replacing the original ‘Demetra’ designation. The reason for this overhaul is unknown, but some researchers noted that the code style had changed and speculated that it may have new developers.


램닛은 뚜렷하게 보여지는 변화없이 2019년에서 2020년에 조용하게 지냈으나, 2021년 초 새로운 램닛 샘을 보여주었습니다. 이는 내부아에서 사용되는 이름은  'hooker2.dill' 으로, 이것은  2018년도 8월 래밋이 다시 나타났을 때 발견되었던 여러 샘플중에 일부와 동일한 것 이었습니다. 이 샘플 코드는 2018년도의 코드와 유사하나 여러 업데이트가 있었으며, 그 업데이트 중에 일부에는 추가적인 OpenSSL 라이브러리가 포함되어 있었습니다. 

Ramnit went through another quieter period during 2019 and 2020, with no significant developments observed. Then in early 2021, new Ramnit samples were observed using the internal name ‘hooker2.dll’, which matched several of the samples observed during Ramnit’s resurgence in August 2018. The sample code was similar to its 2018 counterparts but had gone through several updates, which included the addition of the OpenSSL library.



-------------------------- Details ----------------------

Analysis Details

A number of samples were analysed for the purpose of this research, the full details of which are presented in the Sample Hashes table at the end of this report. This includes sets of Ramnit samples dating back to 2018 and 2021, Bumblebee Beta samples from 2021, and Bumblebee samples from 2022. In addition, samples including NeverQuest, Karius, and Trickbot’s inject modules, were analysed for the purposes of comparison and provenance tracking.

Ramnit’s Revamp

In 2018, after a brief hiatus, Ramnit relaunched with great potency, infecting 100,000 devices in two months and boasting new loaders and an upgraded code base. Campaigns involving the sLoad dropper were widely reported on and attributed to TA554. At this point, Ramnit was demonstrating a complex multi-component loading mechanism, including a dropper/installer utilising VBS and Powershell scripts.

This research focuses on the unpacked components of Ramnit outlined in the diagram below, specifically the Camellia Loaders, Hook Loaders, and Hooker2 module. The functionality of the Ramnit Core binary, rmnsoft.dll, did not change significantly and is not covered in this report.

Figure 1 — Diagram showing the relationship between different Ramnit components including the Hook Loaders, Ramnit Core, Hooker2 module, and WebInject module.

The Hook Loaders

Ramnit’s Hook Loaders are small binaries with the primary function to load a payload by hooking the Windows API functions ZwOpenFile, ZwCreateSection, ZwOpenSection and ZwMapViewOfFile. The process of function hooking, as used in this example, involves accessing the target library module in memory and overwriting the code at the start of the target function such that the flow of execution is redirected to a function supplied by the malware.

In this instance, the functions ZwOpenFile, ZwCreateSection, and ZwOpenSection are hooked and redirected to functions within the loader which check the parameters being passed for a file named ‘wups.dll‘, before directing execution back to the original API function.

In the hook function for ZwMapViewOfSection, if the call is determined to be related to the loading of file ‘wups.dll’, then the payload data is retrieved, and a new memory section is created and the payload binary mapped into it. The address of this new section is then copied to the BaseAddress variable which is an output parameter for ZwMapViewOfSection. The result of this is that when ZwMapViewOfSection is called in relation to file ‘wups.dll’, the address of the loaded payload will be returned instead of that of wups.dll.

Once these hooks have been set, the loader calls the Windows API function LdrLoadDll with ‘wups.dll’ as the parameter. The function LdrLoadDll is used for loading DLLs, and it makes use of the APIs ZwOpenFile, ZwCreateSection, ZwOpenSection and ZwMapViewOfFile as part of its loading process. So, when the loader calls LdrLoadDll, this triggers the hooked functions and results in the loading of the payload in place of wups.dll, as described above. As part of the standard DLL loading process LdrLoadDll will also call the loaded DLL’s entrypoint which in this case results in the execution of the payload.

Different versions of the Hook Loader may use DLL names other than wups.dll, and samples using names such as sbe.dll, dimsroam.dll and dimsjob.dll have also been observed.

The main function for the Hook Loader showing the installation of the hooks and execution of LdrLoadDll can be seen in the image below.

Figure 2 — Main function for the Ramnit Hook Loader showing the installation of the hooks and execution of LdrLoadDll

Two variations of the Hook Loader appear to be in use. One is used as a standalone loader and has its payload stored within its data section. The second type we have referred to in this report as an intermediary loader, which is used by a parent loader during the loading process, and require the payload details to be supplied as parameters during execution. The parent executes the intermediary loader and passes the memory address of the payload to it using the DllEntrypoint function’s ‘Reserved’ parameter, and the intermediary loader, in turn, loads the given payload.

Upgraded versions of the intermediary Hook Loaders were observed in the 2021 Ramnit sample set, which could receive an RC4 encrypted payload that the loader decrypted just prior to loading into the allocated memory section. A 4-byte RC4 key would be passed to the intermediary loader by the parent along with the payload address.

This updated variant of the Hook Loader was also observed in Bumblebee samples.

The Hooking Library

Many of the samples analysed throughout this report all make use of the same custom hooking library for the process of setting hooks and storing information about set hooks. We have not been able to trace this hooking code back to any public source and the code does not match the hooking functions found in the leaked source code for trojans such as Gozi, Carberp, and Zeus. Our analysis indicates that this hooking library was likely developed by NeverQuest, aka Vawtrak in 2013, and since then it has shown up in Trickbot inject modules starting in 2016, Ramnit binaries from 2018, and Bumblebee from 2021.

The hooking library is easily recognisable. It makes use of a hook store that contains information about installed hooks including function addresses and the original code so the function can be restored once the hook is no longer needed. An initialization function, usually run during the start of the malware’s execution, will allocate space for the hook store using VirtualAlloc. The size of each hook store object is 71 bytes in most 32-bit implementations and this constant can be useful in identifying the hook library code. The size of the hook store object in 64-bit implementations appears to be 60 bytes.

Figure 3 — Hook library initialization function, referencing notable 32-bit hook object size of 71 bytes.

Figure 4 — The hook creation function within a 2021 Ramnit sample. At this point several of the library’s other functions have been updated to use control flow flattening code obfuscation, which was not present in the 2018 samples.

Ramnit’s Unhooking Code

Hooking is not just confined to malware – it has many different applications and is often used by security software to examine the behaviour of processes and look for malicious activity. One piece of code which is seen repeatedly throughout the Ramnit binaries checks a hardcoded list of API functions for any hooks that might already be set, for instance by security applications, and removes them by restoring the code at the start of the function with the original code as found in the corresponding DLL file stored on disk. Note, this functionality does not seem to make use of hooking library referenced above.

Similar code can also be seen within the Hook Loaders used within the Bumblebee samples.

Figure 5 — Ramnit’s API unhooking function

The Camellia Loader

The Camellia Loader is usually found as a second or third stage loader in the Ramnit loading process and is generally loaded by the standalone version of the Hook Loader such as that described above. The purpose of the Camellia Loader is to load and execute its payload via process injection. A significant amount of the code base of the Camellia Loader can be traced back to source code from the leaked Gozi malware, specifically Gozi’s ‘activdll’ module which contains process injection functions.

Upon execution, the Camellia loader creates a new thread to run its main functionality and uses the same unhooking function described above to check a hardcoded list of APIs for hooks and restore them to their original states. The loader then selects a random process from the following hardcoded list, which will be used as the process injection target. It should be noted that this process list does not appear within the Gozi source and so seems to originate from Ramnit.

%PROGRAMFILES%\Windows Photo Viewer\ImagingDevices.exe

%PROGRAMFILES%\Windows Mail\wab.exe

%PROGRAMFILES%\Windows Mail\wabmig.exe

%PROGRAMFILES%\Windows Media Player\wmplayer.exe

%PROGRAMFILES%\Windows NT\Accessories\wordpad.exe

The loader uses the Windows Management Instrumentation (WMI) interface to create a new instance of the selected process in suspended mode. It then gets a handle on the newly created process and parses it to identify the address of the process entrypoint or first TLS callback function, if applicable, which will be the address of the first function executed by the process. The loader then patches the code at this address, replacing it with the following code, which calls the Sleep API in an infinite loop.

31 c0                   xor    eax,eax

31 db                   xor    ebx,ebx

31 c9                   xor    ecx,ecx

68 e8 03 00 00          push   0x3e8

b8 ?? ?? ?? ??          mov    eax,<Sleep_Address>

ff d0                   call   eax

eb ec                   jmp    0x0

At this point the loader enters code that closely matches Gozi’s ProcessInjectDll function. The comments in the code for this function also provide a concise explanation for why the process needed to be patched to enter an infinite loop prior to injection:

//    Injects current DLL into the process described by lpProcessInformation structure.
//    We cannot just inject a DLL into the newly-creted process with main thread suspended. This is because the main thread
//     suspends BEFORE the process initializes. Injecting a DLL will fail within LoadLibrary function.
//    So we have to make sure the process is completely initialized. To do that we put an infinitive loop into the processes OEP.
//    Then we resume the main thread and wait until it reaches OEP. There we inject a DLL, restore the OEP and resume the main thread.

The code resumes the created process and waits until it is fully initialized, before suspending it again. It then creates a new memory section and maps a view of the memory section in both the current process and the target process. This makes the memory section available to both the loader process and the newly created target process. The loader then takes its payload, which is a DLL file stored within its data section and loads it into the new memory section.

It also copies into the memory section a structure containing information about the payload, as well as a ‘LoaderStub’ function which is responsible for performing the rest of the steps to properly load the payload DLL in the target process. The loader then gets the context for the target thread and updates it to execute an InjectStub function, which in turn executes the copied LoaderStub function. The target process is resumed and the LoaderStub function executes within the target process. The LoadStub function finishes loading the payload DLL within the target process, and finally executes the payload at its entry point.

The payload for the Camellia Loader is often the Ramnit Core module, rmnsoft.dll.

Figure 6 — The main function for the Camellia Loader

Hooker2

Hooker2 is the controller module for Ramnit’s web injection modules. These modules are injected into web browser processes where they can monitor and intercept web requests made through the browser. They may be configured to steal information such as credentials and banking and payment information.

Hooker2 acts as the controller and loader for the web injection binaries, and it is primarily designed to target the web browsers Internet Explorer, Microsoft Edge, Firefox, and Google Chrome. It has two binaries stored within its resources which are the 32 and 64 bit web injection modules. It also contains 32 and 64 bit binaries within its data section, which are intermediary hook loaders, as described earlier in this report.

Hooker2 starts by checking and adjusting the settings for the above listed browsers in order to weaken their security; this includes modifying registry settings and updating command line arguments in shortcut files. It then monitors running processes on the system for any instances of the target web browsers – if found, it proceeds to inject its payloads into the browser process.

Similar to the Camellia Loader, Hooker2 also makes use of code based on the Gozi ProcessInjectDll and AdInjectImage functions in order to accomplish the injection of its payloads into the target browser process. In this case, however, it is injecting two binaries into the target process – the intermediary hook loader and the web inject module (either the 32-bit or 64-bit versions depending on the target process architecture).

Hooker2 goes through the same steps as the Camellia Loader, creating a new memory section, mapping a view of the memory section in both the current process and the target process, and then building the Hook Loader binary within the created memory section. It then repeats this process for the webinject payload.

This procedure is illustrated in the screenshot below.

Figure 7 — Image showing the creation of memory sections and views in current and target processes, and copying payloads into the sections

Hooker2 then creates a ‘Loader Context’ structure which is stored directly after the hook loader in memory and contains information about the web inject payload, as well as a copied Loader Stub function. Finally, a function is called which executes the Loader Stub function within the target process, which in turn loads and executes the Hook Loader binary. The Hook Loader binary then uses its hooking technique, described earlier in this report, to load and execute the final Web Inject module payload.

Figure 8 — Population of Loader Context structure and execution of code within target process.

Ramnit’s 2021 Updates

In addition to the 2018 samples, we analysed two sets of Ramnit binaries compiled in early 2021. Overall the structure and functionality of these newer samples hadn’t changed significantly, but we noted the following updates:

  • Hooker2 module updated to target the Thunderbird email application in addition to web browsers, and includes code targeting email clients. The web browser targeting code is also updated.
  • Addition of the OpenSSL library, which was not included in the 2018 samples.
  • Inclusion of string Z:\hooker2\Common\md5.cpp in the Hooker2 binary.
  • The LoaderStub function is updated with control-flow flattening obfuscation.
  • Several of the functions within the hooking library are also updated to use control-flow flattening obfuscation.
  • The Intermediary Hook Loaders are updated with the ability to decrypt the supplied payload using RC4, and now have the internal name RapportGP.dll.
  • The list of process injection targets in the Camellia Loader is reduced to the following:
    • %PROGRAMFILES%\Windows Photo Viewer\ImagingDevices.exe
    • %PROGRAMFILES%\Windows Mail\wab.exe
    • %PROGRAMFILES%\Windows Mail\wabmig.exe

At this point, it starts to become noticeable how the state of the malware is shifting closer towards Bumblebee, which contains all the above listed features, except the first.





(램닛 이외의 범블비와 네버퀘스트의 정보까지 확인하고 싶다면, 아래 URL 을 통해 원본을 보실 수 있습니다)

https://securityintelligence.com/posts/from-ramnit-to-bumblebee-via-neverquest/
0 comments
35 views

Permalink