[RE023] Quick analysis and removal tool of a series of new malware variant of Panda group that has recently targeted to Vietnam VGCA


Through continuous cyber security monitoring and hunting malware samples that were used in the attack on Vietnam Government Certification Authority, and they also have attacked a large corporation in Vietnam since 2019, we have discovered a series of new variants of the malware related to this group. Readers can re-read and compare the information below with the previously analyzed article: [RE018-2]Analyzing new malware of China Panda hacker group used to attack supply chain against Vietnam Government Certification Authority - Part 2

I.   Analysing loaders

Sample 2b15479eb7ec43f7a554dce40fe6a4263a889ba58673b7490a991e7d66703bc8 was discovered by us on VirusTotal on 11/06/2021, and was submitted from Vietnam:

The remarkable point in this file is the .NLS (National Language Support) extension, but it’s exactly a DLL PE64. We conduct an in-depth analysis of this sample and determined it seems to be crafted by the same hacker who wrote and built smanager_ssl.dll, msiscsi.dll, verifierpr.dll, wercplsupport.dll.

  • Hash: 2B15479EB7EC43F7A554DCE40FE6A4263A889BA58673B7490A991E7D66703BC8
  • Compiled time: Tuesday, 04.08.2020 06:48:49 UTC
  • Original DLL: DllSvchDtchX64.bin
  • Malicious file: C_20253.NLS, in \Windows\System32
  • Visual Studio version: 2015, linker 14.0, update 3
  • Coding language: C

RichID Information:

You can compare with the RichID information in Figure 3 of this article. Attackers used impersonating NLS in the Windows\System32 and Windows\SysWow64 folders, which contain config and C&C info during the attack on a large Vietnam corporation (Figure4). After that, attackers upgraded in April 2020 to real PE(s) to perform other tasks.

DllSvchDtchX64.bin is written as a service Dll, the code and style is exactly like the code of smanager_ssl.dll and wercplsupport.dll. The ServiceMain, SvcCtrlHandler, and SetSvcStatus functions are all the same.

ServiceMain function (compare with Figure5):

Another small difference is that in addition to the global variable g_dwServiceState, the hacker has added another global variable, g_dwSvcStopped to Sleep continuously until this service of DllSvchDtchX64.bin was stopped by Windows. With this sample, the main task of executing malware code is not included in the ServiceMain function, but directly in the DllMain function.

The SetSvcStatus function (compare with Figure 7 and 8):

In the DllMain function, the malware decrypts the SID and Mutex name, creating a thread to execute another task. This SID and Mutex name are used in the MainThreadProc of the created thread.

The encrypt and decrypt encryption algorithm used by the hacker in this sample is Salsa/Chacha20. It can be detected by FindCrypt3 or Capa of FireEye.

Source code C implementing Salsa and Chacha algorithms is abundant in Lib Crypto libraries, for example Cryptlib, libtomcrypt, libcrypto… But the C source we decompiled is more similar to the source here: http://cr.yp.to/snuffle/ecrypt.c. We are not 100% sure if the hacker changed the algorithm or because of the optimization mechanism of the VC compiler. Readers can refer to it for self comparison.

For decrypting the mutex name and SID, the hacker converts two hardcoded hex strings into a byte buffer using the Hex2Bytes function at address 0x7FFCD3492220, and then feeds this buffer to the Salsa/Chacha20 function at address 0x7FFCD34914F0.

After decrypt, we get:

  1. SID = S-1-5-18
  2. Mutex Name = Global\24yQoCWKY3kbZexjzTR6hc7pHU1lI0EV

SID = “S-1-5-18” is known as Local System, Dll Services run under this account. Readers can refer here: Well-known security identifiers in Windows operating systems. Hackers declared and used a struct like the one below to save the config that regulate the operation of this malware family. This struct has sizeof = 0x248 (584 decimal), and has been encrypted using the Salsa/Chach20 algorithm used above.

The meaning of these fields in this struct:

  • dwSizeData: The actual size of the real data area from the fExecuteShellcode field
  • dwHash: ROL 0xB hash of the whole data range from rgbIv
  • rgbIv: 12-byte array, used as value for parameter Iv for salsa_decrypt_bytes function
  • fExecuteShellcode: flag specifies whether the data area in the rgbShellcode array has shellcode data, and whether the malware will execute this shellcode or not
  • fCreateMutex: flag determines whether or not to create a mutex with the above decoded name
  • fCheckSID: check if the malware is being executed correctly in the above decrypted SID group
  • fCheckExePath: check whether the executing malware has the correct Exe name or the correct Parent Exe name with the szExePath field
  • szExePath: Name of Exe or Parent Exe that needed to be checked
  • dwShellcodeSize: The actual size of the rgbShellcode area (rgb = Range of Bytes) or length (in bytes) of the shellcode file's path
  • rbgShellcode: Shellcode or path of another dll or shellcode that needs to be loaded and executed

Source decompiler of MainThreadProc, address = 0x7FFCD3491FD0.

Note: g_config is a global variable of the above struct CConfig. 0x14 (20) is the total size of the 3 fields: DWORD dwSizeData, DWORD dwHash and BYTE rgbIv[12].

After checking the correct size, the Decrypt function will decrypt the hardcoded config, encrypted with the decrypt Salsa/Chacha20 functions.

The value of the local hash variable in the Decrypt function is calculated from the address of rgbIv, the loop size is the value of the field dwSizeData + 0xC (12 = sizeof(rgbIv)). If the hash value matches the dwHash field, the data region will be decoded.

The decryption key is the hardcoded string "u0FBSP2dDyTLhIQ9MXsEexmH7JbiN3k", the Iv value is rgbIv, the output decoding starts at the address of the fExecuteShellcode field (offset 0x14). After decoding the hardcoded config, in the MainThreadProc image above, the malware starts checking flags, flags that are set to 1 will call the corresponding check function.

The function checks the user’s SID that the malware is running:

The variable g_pwszSID is WCHAR * type, decrypted from the begining (“S-1-5-18”). If the SID is equal (stricmp return 0) then the function will return TRUE.

Function to check current Exe name or Parent Exe name (when malware runs as a service Dll). The function also returns TRUE when the Exe Name matches the szExePath field:

Function creates mutex is the same as the regular CreateMutex functions:

The value of g_pwszMutexName variable has been decoded from the begining: “Global\24yQoCWKY3kbZexjzTR6hc7pHU1lI0EV”. The created Mutex will be saved to the g_hMutex global variable.

As shown in the figure of MainThreadProc, if the fExecuteShellcode field is set to 1, the shellcode will be executed as usual (VirtualAlloc, copy and execute). When it is 0, the shellcode file will be read from rgbShellcode.

g_hInstDLL is the HINSTANCE of the malware, running as a service DLL, assigned value at the Entrypoint DllMain function. Readers notice three functions PathRemoteFileSpec, PathAddBackslash and PathAppend. These three functions will regenerate the path for the Shellcode file that is from a subdirectory of the same level as the Malware. In this case, malware has an impersonation name of C:\Windows\System32\ C_20253.NLS, that subfolder will also be located in C:\Windows\System32.

After getting the path of the shellcode file, the shellcode will be read, decrypted, and return a pointer to the decrypted shellcode.

The memory containing this decrypted shellcode is executed by MainThreadProc. With this sample, after the Decrypt function, we only have the following config information:

  • All flags are 0
  • File shellcode is “ErrorSvc.dll”, field dwShellcodeSize = 0x1A (26)

II.   Hunting the same loader

Based on the special hardcoded string “u0FBSP2dDyTLhIQ9MXsEexmH7JbiN3k”, is used as IV for the Salsa/Chacha20 encrypt/decrypt function, we did a search on VirusTotal and Hybrid Analysis, there are many similar loaders, most of which are uploaded by users recently, from Vietnam, Korea, Japan, Hong Kong... and lastest is a sample from China.

Until yesterday, we have found and analyzed 7 more loader samples like this. The source code is completely the same, only the final build format are different (EXE or DLL). And it's all PE64, include the following samples:

  1. 4578b3bf586658c47c8db1d497a8994d7637d28f16a11af9f6af64836085d4ed
    • Build Exe
    • Flags = 0
    • Shellcode path: stuffe.dll
  2. 8061df4d29ea57a420491f0db4bf37964070cc695f4b1b45af40e46194cc8c36
    • Build Exe
    • Flags = 0
    • Shellcode path: tmp01.dat
  3. 4b1928dbaf68e427db2f3971ea2ff5604d210ef0dee876d57281d7e395da8c37
    • The impersonated file name is C_892.NLS
    • Build as Dll, original Dll name: DllSvchDtchX64.bin
    • Flags = 0
    • Shellcode path: winsec.dll
  4. d2beff6d7f5be68cdda36182d010e8103d86053fcc63f1166fec42727c26558d
    • Build as Dll, original Dll name: DllSvchDtchX64.bin
    • Flags = 0
    • Shellcode path: access.sys
  5. d28984576620aebfa929767ad9453fe7549c969716d41ba49cbe6ca7fae72789
    • Build as Exe
    • Flag fExcuteShellcode = 1
    • Shellcode size = 0x107A2 (67490)
  6. 3714568d8c8b7359259e968664de3a6c13d6d7c16559dfb0a25f9aa8194e8de4
    • Build as Dll, original Dll name: DllHijkDtchX64.bin
    • fCreateMutex, fCheckSID, fCheckExePath set 1
    • Exe Parent Name to check: WmiApSrv.exe
    • Shellcode path: AxLnst.bin
      Notice the file name Exe Parent. This exe is the original Windows file, located in the \Windows\System32\Wbem folder. So this malware and AxLnst.bin will also be in this directory (according to the GetShellcodePath function). This could be an attack using WMI Exploitation that the Winnti/Derusbi Group has been using. Read more here.
  7. b69d9ed06cba8eea081df01bad146abb004a4cf5fb6b296017d82ebb18975386
    • Build as Exe
    • Flags = 0
    • Shellcode path: koreanflass.bin

III.   Hunting the updated malware of this group

Continuing to hunt for signs of old malware samples that this group has used in campaigns targeted Vietnam over the years, we found that this group still uses old samples, has updated code and rebuilt with Visual Studio 2019, v16.4 or later. Completely build in x64 mode.

This group continues to use files that impersonate Windows' NLS files as config containers or as shellcode files. The identification point is that this group has a coder who specializes in CryptoPP library and coding in C++ style, using std::string.

The samples we collected were released recently, in May and June, also from the countries mentioned above. We collected and analyzed the following samples:

  1. 5afc41060cf62d1613219caa108eb9714074479a413f4a26797c0358fc95a4db
    • Built with Visual Studio 2019 v16.9
    • PDB Path: C:\Users\VS\Desktop\Auto_Firefox\x64\Release\8.1.pdb
    • Using CryptoPP, C++ style
    • Xor value: 0x28
    • Build time: 08/06/2021 - 1:24:48 AM (UTC)
    • Export function: ServiceMain, run as a service Dll
    • Read and execute MSIscSI.Dll in the same directory and load vsmapi.dll in SysWow64, calling the netEntryApi export function.
  2. 8dd13f34d1734d3c844474ce98a4f39244e511bafbefd59b18bb7fb0b52ce895
    • Built with Visual Studio 2019 v16.9
    • PDB Path: C:\Users\Machine\Desktop\Work\20200913\Auto_Firefox\x64\Release\8.pdb
    • Using CryptoPP, C++ style
    • Build time: 19/09/2020 - 8:58:34 AM (UTC)
    • Export function: NetworkChecker
    • Decrypt, read two configs from two fake NLS files, C_4868.NLS and C_4869.NLS

  3. 9abf047566c6e9bd77120e8eb6c3503eef7c05dd4fd0abac9046d495291e5c8d
    • Built with Visual Studio 2008, code C style
    • Export two functions Run and main. Two different functions but the code is exactly the same
    • PDB path: C:\Dev\16\3\x64\Release\F71.pdb
    • Build time: 01/06/2016 - 4:38:32 PM (UTC)
    • Impersonate as Windows VfWWDM.dll in Resource Version Info
    • C2 hardcoded, xor with 0x27, is “www.newshcm.com”
    • Read two files is NLS fake are C_436.NLS and C_20130.NLS. The xor value to decode the contents of 2 files is 0x26 and 0x27
  4. 60fe689bafb1ce4def3fab1c91e69e46b223869314e4364fa8efb12e6a0bafba
    • Built with Visual Studio 2019 v16.9, C style
    • PDB path: C:\Users\VS\Desktop\Auto_Firefox\x64\Release\8.1.pdb
    • Export function: ServiceMain
    • Xor value: 0x2B, load dll pubiapi.dll in Windows\SysWow64, calling export function netEntryApi of this Dll.
  5. 68e871190f405131635ccaa851339c9ca3f61c3b6a9d84dbd7afc99b65edd588
    • Built with Visual Studio 2019 v16.9
    • Using CryptoPP, C++ style
    • Build time: 12/04/2021 - 9:18:26 PM (UTC)
    • Export function: netEntryApi
    • Load 2 fake NLS files are C_4868.NLS and C_4869.NLS like (2)
  6. 918ad6c918b26de1e112281393f6ced9141712484bb0da5f8250fb36fc0d476b
    • Built with Visual Studio 2012, C style
    • PDB Path: C:\Dev\17D\Release\7.pdb
    • Build time: 30/04/2017 - 12:29:05 AM (UTC)
    • Export two functions are Run and main like (3)
    • CC hardcoded, xor with 0x1B, is “www.sexphm.com” and IP hardcoded
    • Read two fake NLS files are C_20831.NLS and C_20832.NLS in Windows\System32
  7. c092546e9db9424d454cc21047d847ad93424440e7a4d339fe58fa9a4d8f6913
    • Is vsmapi.dll of (1)
    • Built with Visual Studio 2019 v16.9
    • Using CryptoPP, C++ style
    • PDB path: C:\Users\VS\Desktop\Auto_Firefox\x64\Release\8.pdb
    • Build time: 08/06/2021 - 1:24:51 AM (UTC)
    • Export function: netEntryApi
    • Load two fake NLS files are C_4868.NLS and C_4869.NLS like (2) and (5)

Thus, we can see that the samples that this group used in this campaign are mostly rebuilt, besides some old samples in their inventory that have not been detected. Maybe they have been used, installed and infected in many companies and organizations of many countries, including Vietnam since 2016. Until now, we have discoverd a number of fake NLS files that this group used throughout, including:

  • C_201263a.NLS
  • C_20130.NLS
  • C_20253.NLS
  • C_20831.NLS
  • C_20832.NLS
  • C_20834.NLS
  • C_20835.NLS
  • C_21871.NLS
  • C_21872.NLS
  • C_436.NLS
  • C_4868.NLS
  • C_4869.NLS
  • C_877.NLS
  • C_878.NLS
  • C_892.NLS

And probably many more impersonated NLS files out there that we may not discovered.

IV.   Analysing Windows C_xxxx.NLS files

The value xxxx is a number, which is a codepage identifier. For example, Vietnam has a codepage of 1258, the file C_1258.nls on Windows is for Vietnam.

For more codepage definition, readers can read it here. Values ​​of Codepages that international and Windows have a convention can refer here. The current maximum value of Codepage is 65501, Unicode UTF-8. Between 1 and 65535 (0xFFFF), you will see a lot of space, more than 65,000 numbers. This group used numbers not on the above Codepage identifiers to name the impersonated C_XXXX.NLS files.

The original Windows C_xxxx.NLS files are used for mapping and converting from MultiByte to Unicode characters. Two common API functions commonly used in Windows, MultiByteToWideChar and WideCharToMultiByte, are based on these C_xxxx.nls files corresponding to the current Windows Codepage on the user's machine.

On Windows 2000, XP operating systems, these .nls files are not included in the list of Windows Protection Files files, only .exe, .dll, .sys, .ocx files. From Windows Vista onwards, the list of Windows Protection Files file types is expanded and the .nls file is added. Readers can refer to protected files here.

The C_xxx.nls are installed when the user installs Windows, located in the Windows\System32 and Windows\WinSXS\ folders in several subfolders named xxx.codepage-core.xxx and xxx.codepage-additional-xxx.

These C_xxxx.nls files all have Owner Trust Installer, users with System and Administrators rights can only Read, no change rights. When trying to switch Owner and change these files, Windows Resource Protection will notify and recover immediately.

When the user installs Windows, the list of C_xxxx.nls files were created by Windows is located at KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage. The name value is the codepage number and the Data value is the codepage file name.

The image above is part of the list of Windows 10. In addition to .nls files, Windows also uses C_xxxx.dll files to serve for mapping, converting between that codepage back and forth Unicode. These dlls only export a single function is NlsDllCodePageTranslation. Prototype of this function: DWORD __stdcall NlsDllCodePageTranslation(DWORD CodePage, DWORD dwFlags, LPSTR lpMultiByteStr, int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar, LPCPINFO lpCPInfo)

On Windows XP and 2000, the number of codepages in the above registry is less, although there are many .nls files copied by the Windows installer to System32\dllcache, they are not considered to have been installed and updated in the above registry.

The number of codepages that are considered installed and supported on each version of Windows is also different. From Windows Vista onwards, all .nls files that are installed are turned on as installed. Codepage installed and supported on Windows XP:

Codepage installed and supported on Windows 7

Codepage installed and supported on Windows 10

Since Microsoft does not disclose the structure of the .nls file, we searched the Internet and relied on the WinNLS.h file in the Windows SDK to create the NLS.bt file. This file is used as a template parser for 010 Editor, a HexEditor program that supports scripts and parse templates very strongly, widely used by the RE community, forensics ....  When using 010Editor to open an NLS file and select the template file as NLS.bt, 010Editor will show us the internal structure of an NLS file. We uploaded NLS.bt here.

V.   Tools to check the number of codepages and scan fake NLS files file

After analyzing the structure of an official, original Windows C_xxxx.NLS file, VinCSS has developed two tools to check and scan fake NLS files of this group. These two tools are written in Delphi (Object Pascal) and built with Free Embarcadero Delphi Community Edition.

We provide both the built exe and the source code for your reference, which can be easily tested, rebuilt by yourself, also in the above repo. According to this report by Positive Technologies, hackers have now updated to new fake NLS.

  1. CheckCP:
    Based on the EnumSystemCodePages API function with two parameters CP_INSTALLED and CP_SUPPORTED, CheckCP will display a list of installed and supported codepages on the current Windows. If you detect a suspicious C_xxxx.NLS file, you can enter that number into the CheckCP program to check if the codepage number is fake or belong to Windows. XXXX is a number, for example: file C_20130.NSL, the number to check is 20130.

    With the list of fake NLS files above, we immediately see that all the codepage numbers are fake (1258 and 1252 are valid, we added):

    CheckCP.exe source code you download at the above repo, in the subdirectory .\src, file CheckCP.dpr

  2. NLSScan.exe:
    NLSScan is the main program to scan all C_xxxx.NLS files in Windows\SysWow64 and Windows\System32 folders, deep into all subfolders. This file is built with 32bit mode, running on old Windows such as XP, 2000 because there is a high possibility that many computers in organizations still use these operating systems.

    This group always put fake NLS files in the above two folders. NLSScan checks many factors to ensure that a C_xxxx.NLS file must meet all of those conditions to not be considered fake or malware. When running NLSScan with no parameters, NLSScan will request Admin privileges to read only a small portion of the files C_xxxx.NLS finds. If you choose Yes, NLSScan will automatically run again in Admin privilege.

    For example, a requirement that the codepage number be consistent in the file name and in the file content. We found two cases where the content of the .NLS file was valid when parsed in NLS.bt, but the codepage number in the file name was invalid, and the codepage number in the content was inconsistent. Hackers copied the original Windows file C_037.NLS into two new files C_21871.NLS and C_21872.NLS, overwriting the config of the content of ​​the file.

    Compare these two files with the C_037.NLS file and you will see the overwritten area:

When NLSScan detects fake NLS files, the tool will ask the user for permission to copy those files to the %TEMP% folder and delete them. If the tool fails to remove it, NLSScan will prompt you to reboot to delete it at the next reboot. When you receive the NLSScan message as above, there is a fake NLS file, you should allow copying and deleting, then reboot Windows immediately, run the tool again. If the tool still cannot be deleted, please restart Windows in Safe Mode, run the tool again or find and delete those fake NLS files manually.

When NLSScan has detected a fake NLS file, it is almost certain that your computer has been infected with some malware of this group. You should disconnect from the Internet, rescan your system with AV programs, change the passwords, review all security factors.

You can send us the fake NLS files that have been copied to the %Temp% folder, and if you need helping with finding, review, etc. please contact us at the email address: malware.report@vincss.net

This is a test result by using NLSScan on our Windows 10 machine. Especially, you can see the file C_878.NLS that we mentioned in part II, which is a PE x64 dll file, which Windows Defender has not detected at the time of this article.

NLSScan can also scan each or multiple NLS files (user can enter the path of those NLS files). Currently, NLSScan only supports scanning C_XXXX.NLS files. On Windows there are a number of other NLS files such as: l_intl.nls, locale.nls, normidna.nls, normnfc.nls, normnfd.nls, normnfkc.nls, normnfkd.nls, SortXXX.nls. But because the format of these files is not announced by Microsoft, we cannot check. When you encounter files with such names, you use the Windows tool sfc.exe (System File Checker).

The file C_20253.NLS is invalid, so sfc will say “WRP could not perform….”, C_037.NLS is a valid file, located in Windows Protection Files, not compromised, so sfc says “WRP did not find …

We also upload a small bat file sfcnls.cmd in the above repo for you to periodically run and check with NLSScan all .nls files in the Windows directory. We hope you will share these tools to scan all Windows-based computers in Vietnamese companies, agencies, organizations and economic groups. In our opinion, this group is very dangerous, may has been able to penetrate and lies deep inside with undetected for a long time, causing great harm to Vietnam.

We wish you good health, peace, … and together overcome this pandemic.

Click here for Vietnamese version.


Author: Truong Quoc Ngan (HTC), Dang Dinh Phuong

VinCSS (a member of Vingroup)

No comments:

Post a Comment