# [RE018-1] Analyzing new malware of China Panda hacker group used to attack supply chain against Vietnam Government Certification Authority - Part 1 **blog.vincss.net/2020/12/re018-1-analyzing-new-malware-of-china-panda-hacker-group-used-to-attack-supply-chain-against-** vietnam-government-certification-authority.html **I. Introduction** In process of monitoring and analyzing malware samples, we discovered an interesting blog post [of NTT here. Following the sample hash in this report, we noticed a hash on VirusTotal:](https://insight-jp.nttsecurity.com/post/102glv5/pandas-new-arsenal-part-3-smanager) _Figure 1. Hash’s information in the NTT blog_ On the event that a hacker group believed to be from Russia attacked and exploited the software supply chain to target a series of major US agencies, along with discovery that the keyword **eToken.exe belongs to the software that is quite popularly used in agencies, organizations and** businesses in Vietnam, we have used eToken.exe and SafeNet as keywords for searching on VirusTotal and Google. As a result, we uncovered information about two remarkable installation [files (1, 2) that have been uploaded to VirusTotal since August 2020:](https://www.virustotal.com/gui/file/6be34df727fcb79123e4e8f472ad24b698d83395fb17d4db019e9976f485cd83/detection) ----- _Figure 2. Information look up on VirusTotal_ The name of the installation files are quite familiar: gca01-client-v2-x32-8.3.msi and gca01**client-v2-x64-8.3.msi, We have tried to download these two files from the website and they** have the same hash value. However, at the present time, all files on the VGCA homepage have been removed and replaced with the official clean version. According to the initial assessment, we consider this could be an attack campaign aimed at the software supply chain that can be leveraged to target important agencies, organizations and businesses in Vietnam. On December 17, ESET announced a discovery of an attack on APT they called "th Operation SignSight" against the Vietnam Government Certification Authority (VGCA). In that report, ESET said they have also notified VNCERT and VGCA and VGCA has confirmed that they were aware of the attack before and notified the users who downloaded the trojanized software. At the time of analysis, we have obtained two setup files that have been tampered by hackers. This blog post series will focus on analyzing the signatures and techniques that hackers have applied to malicious samples in these two installation files. **II. Analyze installation file** This application is named as " **SafeNet Authentication Clients" from SafeNet .Inc company.** Portable Executable (PE) files are mostly signed with SafeNet certificates. ----- _Figure 3. PE files signed with SafeNet certificate_ By using UniExtract tool, we extracted the entire file from an installer (x64 setup file). The total number of files is 218 files, 68 subfolders, the total size is 75.1 MB (78,778,368 bytes). To find out which file has been implanted by hackers, we only focus on analyzing and identifying unsigned PE files. With the help of sigcheck tool in Micorsoft's SysInternals Suite, with the test parameters is signed, hash, scan all PE files, scan the hash on VirusTotal, the output is csv file. Then sorting by unsigned file, resulting from VirusTotal, we discovered that eToken.exe is the file was implanted by the hacker. _Figure 4. Discovered file was implanted by hacker_ The hash of this eToken.exe matches with the one in NTTSecurity's report. Another strange point is that it’s a 32bit PE but located in the x64 directory, the version information such as “Company, Description, Product…” are not valid for such a large company application. Here is [the scan result of the eToken file on VirusTotal.](https://www.virustotal.com/gui/file/97a5fe1d2174e9d34cee8c1d6751bf01f99d8f40b1ae0bce205b8f2f0483225c/detection) Since this application is built with Visual C ++ of Visual Studio 2005 which is old version, and uses the Qt4 library, some of the dll files of this installer are also unsigned. We checked each file and determined that the files were clean, leaving only three suspicious files: **RegistereToken.exe, eTOKCSP.dll and eTOKCSP64.dll.** So eToken.exe file is a malware that hackers have added to the installation of the software suite. To find out how eToken.exe is executed, we analyze the installation file: msi file ( Microsoft _Windows Installer file): gca01-client-v2-x64-8.3.msi_ Extracting the msi file to raw format before installing, we obtained two **.cab files (Microsoft** _Cabinet file): Data1.cab and Cabs.w1.cab. This is anomaly because a normal msi file has only_ one main .cab file. Check the Data1.cab file and the MSI log text file, **eToken.exe and** **RegistereToken.exe are in Data1.cab file. And both .exe files have no GUID ID info:** ----- _Figure 5. Exe files do not have a GUID ID info_ Continue checking the features: DriverFeature, and two files eToken.exe and **RegistereToken.exe msi file with Microsoft's Orca tool (a specialized tool for analyze and** _modify msi files). Through a search, the hacker has added a custom action: RegisterToken_ (without "e" before Token) to the msi file and added that **CustomAction at the end of** **InstallExecuteSequence. RegistereToken.exe will be called with the parameter is** **eToken.exe:** _Figure 6. Hacker implanted a custom action_ Analyzing the RegistereToken.exe file, we see that this file was built on "Wednesday, **22.07.2020 07:40:31 UTC", ie 07/22/2020, 2h40m31s PM GMT +7, PE64, using VC ++** **2013:** _Figure 7. Information of the RegistereToken.exe file_ **RegistereToken.exe's pseudo code only calls the WinExec API to execute the passed in** argument: ----- _Figure 8. Tasks of RegistereToken.exe_ With all the information above and based on the timestamp in the **Data1.cab and** **RegistereToken.exe files, we can conclude:** Hacker has created and modified the .msi file and created the Data1.cab file at timestamp: 07/20/2020 - 15:15 UTC time, added the eToken.exe file at this time. Build RegistereToken.exe file at timestamp: 22/07/2020 - 07:40 UTC Add RegistereToken.exe file to Data1.cab at timestamp: 22/07/2020 - 08:40 UTC Note: According to Cab file format, the two Date and Time fields of a file in the cab file are DOS **Datetime format, each of which is a Word 2 bytes which reflect the time when the file was** added according to DOS time. Cab file processing programs will convert and display in UTC time. [That is, the above UTC times are the current time on the hacker machine. See more here.](https://docs.microsoft.com/en-us/windows/win32/sysinfo/ms-dos-date-and-time) _Figure 9. MS DOS Datetime Information_ **III. Analyze eToken.exe** ----- **1. Analyze PE Structure** File eToken.exe: Size: 192 KB (196,608 bytes) MD5: 830DD354A31EF40856978616F35BD6B7 SHA256: 97A5FE1D2174E9D34CEE8C1D6751BF01F99D8F40B1AE0BCE205B8F2F0483225C Information about compiler, RichID and build timestamp: Build with VC ++ 6 of Microsoft Visual Studio, Service Pack 6. Build at: 26/04/2020 - 15:12:58 UTC Checksum is correct, file has not been modified PE Header. Linking with MFC42.dll library, Microsoft Foundation Class v4.2 library of Microsoft, is a library supporting GUI programming on Windows, always included in Visual Studio suite. Link with a special library: dbghelp.dll. Use the MakeSureDirectoryPathExist API [function. See more here.](https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-makesuredirectorypathexists) Checking the resource section of the file, we determined that this is a Dialog application, created by MFC Wizard of Visual Studio 6. The project name is VVSup, which means the .exe file when built out would be VVSup.exe. _Figure 10. File's resource information_ ----- **2. Static code analysis** **eToken.exe (VVSup.exe) is built with dynamic link DLL mode with MFC42.dll, so the .exe** file will be small and the functions of the MFC42 libirary will be easily identified via the name import of the DLL. The name mangling rule of Microsoft VC ++ compiler reflects the class name, function name, parameter name, call type... of functions. IDA helps us to define the functions import by ordinal of MFC42.dll using the file mfc42.ids and mfc42.idt included with IDA. However, VVSup is built with the RTTI (Runtime Type Information) option is disabled, so there is no information about the RTTI and Virtual Method Table of all classes in the file. We only have RTTI of class type_info, the root class of RTTI. _Figure 11. RTTI Info of type_info class_ The analysis will show how to define classes, recreate the code of this malware, and share experience in applying when analyzing malwares/files using MFC. Plugins used: Simabus’s ClassInformer Matrosov’s HexRaysCodeXplorer **MFC_Helper** The MFC C++ source code can be found in the src\mfc directory of the Visual Studio installer. [Since MFC4.2 (MFC of VS6) is very old, it can be found on Github. We refer here. About the](https://github.com/dblock/msiext/tree/master/externals/WinDDK/7600.16385.1/inc/mfc42) [relationship chart of the classes of MFC (Hierarchy Chart), you can see at this link.](https://docs.microsoft.com/en-us/cpp/mfc/hierarchy-chart?view=msvc-160) Three important dlls file to diffing/compare with MFC malware, for example in this sample **eToken, are mfc42.dll, mfc42d.dll, mfco42d.dll. You can find and download the correct** debug symbol file (.pdb) of the dlls you have. The most important one is **mfc42d.dll (debug** _build), since its .pdb will contain full information about the types, enumes, classes, and vtables_ of the MFC classes. We export local types from mfc42d.dll to .h file, then import into our idb database. IDA's Parse C ++ has an error, unable to parse the "<>" template syntax, so we find and replace pairs of "<" and ">" to "_" in .h files. Parallel opening mfc42d.dll in new IDA together with IDA is parsing malware, copy names, types of classes, functions from mfc42d.dll. As mentioned, this malware is an MFC Dialog application, so we will definitely have the following classes in the malware: CObject, **CCmdTarget, CWinThread, CWnd, CDialog. According to the MFC Wizard's auto-naming** rule, we have classes with the following names: CVVSupApp (inherited from CWinApp), **CAboutDlg (dialog About, resID = 100), CVVSupDlg (main dialog, resID = 102).** Scan results of vtables, classes of two plugins ClassInformer and HexRaysCodeXplorer. ----- _Figure 12. Scanning vtables, classes result_ Use MFC_Helper scan CRuntimeClass, as expected, CVVSupDlg has CRuntimeClass and add another class: CVVSupDlgAutoProxy. It shows that the hacker when running the MFC Wizard, clicked to select support OLE Control. _Figure 13. Detect classe after run MFC_Helper_ Based on the import function CWinApp::GetRuntimeClass, we can determine CVVSupApp vtable, and based on CDialog::GetRuntimeClass we can define two vtables of the other two dialogs. But which dialog is About, which dialog is a malware dialog? Identify all the internal structures of MFX such as AFX_MSGMAP, AFX_DISPMAP, AFX_INTERFACEMAP... Using the Xref to feature call the CDialog constructor: void __thiscall CDialog::CDialog **(CDialog *this, unsigned int nIDTemplate, CWnd *pParentWnd), nIDTemplate is the** **resID of the dialog, we define the vtable of** **CAboutDlg and CMalwareDlg. Because** **CMalwareDlg does not have CRuntimeClass and RTTI, so it is temporarily named like that.** The hacker deleted the DECLARE_DYNAMIC_CREATE line of these two classes and the **CVVSupApp class when build.** ----- _Figure 14. Identify vtable of CAboutDlg and CMalwareDlg_ Relational Classes table of this malware: ----- _Figure 15. Relational classes table of this malware_ Copy the names of functions, types, function types, parameters ... from the respective parent classes of the above classes, in the correct order in the vtable, identify the generated MFC Wizard functions and the functions the hacker wrote. _Figure 16. Result after copy name of functions, types, function types, parameters_ Every MFC application has a global variable called theApp, belonging to the main class **CXXXApp inheriting from CWinApp. In the case of this malware are: CVVSupApp theApp;** This global variable is initialized by C RTL in the start function, called before main/WinMain, in table __xc_a. The functions in this table call after the C RTL constructors in __xi_a. These tables are the parameters passed to the internal _initterm function of C RTL. ----- _Figure 17. TheApp global variable in the MFC application_ The flowchart of creating and executing an MFC application is as follows: _Figure 18. Flowchart of creating and executing an MFC application_ The CVVSupApp :: InitInstance function is also a common code generated by MFC wizard ----- _Figure 19. CVVSupApp::InitInstance function_ Constructor of CVVSupDlg: void CVVSupDlg::CVVSupDlg() is also common code generated by MFC Wizard. But in CVVSupDlg::OnInitDialog, which is called from **CVVSupDlg::DoModal(), we can see immediately, at the end of the code that the MFC Wizard** generated, CMalwareDlg is initialized and shown, then the malware exits forcibly **exit (0).** ----- _Figure 20. CMalwareDlg was created and shown_ The value 129 is the resID of the CMalwareDlg dialog, and sizeof(CMalwareDlg) = **0x290, which is larger than the size of the parent CDialog. It proves that** **CMalwareDlg was** added by hackers to some data members. Through analysis, we recreated the data members of **CMalwareDlg:** _Figure 21. Recreate data members of CMalwareDlg_ The CMalwareDlg::CMalwareDlg Constructor does the following initialization jobs. Note the copy string "192.168" into the field m szMask: ----- _Figure 22. Copy "192.168" string to m_szMask field_ When shown, CMalwareDlg::OnInitDialog will be called, and the main function that is important for doing the malware's task is called here: _Figure 23. The Infect main function will do the malware's job_ The Infect (we named) function is relatively long, so it should be presented via the flowchart below: _Figure 24. Infect function flowchart_ ----- We ll go into detail each of the important child functions called by the **Infect function of the** **CMalwareDlg class. The UserIsAdmin function, using the IsUserAdmin() API of** **shell32.dll:** _Figure 25. UserIsAdmin fuction_ **GetSomeAPIAddrs function is a redundant function, function pointers are taken but** completely unused. We guess this could be an old code. _Figure 26. GetSomeAPIAddrs function_ ----- The Base64Decode function is like other Base64 decode functions, except that the Base64 code table is copied by the hacker to a char arrary m_szBase64Table and accessed from here. After being decoded Base64, the original ServiceName "TmV0QmlvcyBNZXNzYWdlciBSZWdpc3Rlcg==" will be " **NetBios Messager** **Register". The original ServiceDescription** "TmV0QmlvcyBjb21tdW5pY2F0aW9uIGJldHdlZW4gc3lzdGVtIGNvbXBvbmVudHMu" would be "NetBios communication between system components." The ExtractCabFile function is a global function, not part of the **CMalwareDlg class. Note** that the file is created with the attribute hidden. _Figure 27. ExtractCabFile function_ The .cab file is completely embedded in the .data section, **size = 94874 (0x1729A). Hackers** declared the following equivalent: "static BYTE g_abCabFile[] = {0xXXXX, 0xYYYY};" (no const, so it will be located in .data section). Extracting that area, we have a **.cab file** containing a file, named smanager_ssl.dll, the date added to the cab is **04/26/2020 - 23:11** **UTC, build date 26.04.2020 15:11:24 UTC.** _Figure 28. The embedded .cab file contains the file smanager_ssl.dll_ The smanager_ssl.dll file (netapi32.dll) will be analyzed in the next post because it is relatively complex. ----- _Figure 29. RunExtrac32Exe function_ The ExecuteAndWait function is also a global function, using the ShellExecuteExA API to call and wait until the execution completes. _Figure 30. ExecuteAndWait function_ The Config of the Proxy on the victim machine is defined by the hacker through a struct as shown, **PROXY_TYPE is an enum:** _Figure 31. struct PROXY_CONFIG_ ----- The ReadProxyConfig function will read from the victim s registry first, otherwise it will read from the Firefox pref.js file. We are still not clear why hackers tried to read from Firefox, maybe they did a reconnaisance to learn about the commonly used web browsers at the target. _Figure 32. ReadProxyConfig function_ The ReadProxyConfigFromRegistry function is a bit long so there are only important parts: _Figure 33. The main job of the ReadProxyConfigFromRegistry function_ ----- The ReadProxyConfigFromFireFox function is very long so we won t cover it in detail here. The UpdateFile function uses the memsearh equivalent function to find a string in the file's content, and C&C Info will be written at the found location. In the case of this malware, the mask string is "192.168". _Figure 34: The UpdateFile function uses the memsearh equivalent function to find a string_ We recreated the C&C Info struct as follows: _Figure 35. struct of C&C info_ And C&C info has been hardcoded by hackers in the code: ----- _Figure 36. C&C information is hardcoded in the malicious code_ The content of smanager_ssl.dll* (netapi32.dll**) is original and after being updated from **g_CCInfo structure via:** _Figure 37. Contents of smanager_ssl.dll file (netapi32.dll) before and after being updated_ The function to load the extracted file and create the Scheduler Task: ----- _Figure 38. Function LoadDllAndCreateSchedulerTask to load the extracted file and create a Scheduler Task_ Then, if the malware is run with admin, it will register as a **ServiceDll, with the name** mentioned above, the Service registry key chosen at random from a table of ten elements, and appended "Ex". These series include: "Winmads", "Winrs", "Vsssvr", "PlugSvr", "WaRpc", "GuiSvr", "WlanSvr", "DisSvr", "MediaSvr", "NvdiaSvr". After appending Ex by the sprintf function, the registry key on the victim machine is created under the branch HKLM\SOFTWARE\Microsoft\Windows **NT\CurrentVersion\Svchost will be one of the following strings: “WinmadsEx”,** “WinrsEx”, “VsssvrEx”, “PlugSvrEx”, “WaRpcEx”, “GuiSvrEx”, “WlanSvrEx”, “DisSvrEx”, “MediaSvrEx”, “NvdiaSvrEx”. Since the function is also a bit long, only the main points are covered here: _Figure 39. Create a registry key on a victim machine_ ----- _Figure 40. Create service on victim machine_ The RegistryCall function is a self-written function by hacker, it is a global function, also only doing tasks with the Registry. From our point of view, hackers' programming styles are extremely messy and inconsistent (maybe this is how they intentionally confusing), which made it difficult for us to analyze. After registering as a Dll service, the Infect function completes and returns. Malware will exit because of the above call to exit(0) on OnInitDialog We will provide .xml file containing analysis information on IDA so anyone interested in this malware can use it to re-import IDA and Ghidra using Ghidra's plugin xml_importer.py. ----- The IOCs of the malicious code have been noted in the article. You can write your own **.bat file or** script using PowerShell, VBS ... to find and remove this malware on the victim's computers. **Note:** Original smanager_ssl.dll MD5: C11E25278417F985CC968C1E361A0FB0 SHA256: F659B269FBE4128588F7A2FA4D6022CC74E508D28EEE05C5AFF26CC23B7BD1A5 **netapi32.dll (ie smanager_ssl.dll has updated CCInfo):** MD5: 43CE409C21CAD2EF41C9E1725CA12CEA SHA256: 6C1DB6C3D32C921858A4272E8CC7D78280B46BAD20A1DE23833CBE2956EEBF75 [Click here for Vietnamese version: Part 1, Part 2](https://blog.vincss.net/2020/12/phan-tich-ky-thuat-dong-ma-doc-moi-co-nhieu-dau-hieu-lien-quan-toi-nhom-tin-tac-Panda.html) **Trương Quốc Ngân (aka HTC)** **Malware Analysis - VinCSS (a member of Vingroup)** -----