{
	"id": "6b91bc4d-7a23-43c6-829f-6882ebae48fa",
	"created_at": "2026-04-06T00:18:15.074783Z",
	"updated_at": "2026-04-10T13:12:30.214001Z",
	"deleted_at": null,
	"sha1_hash": "090fd0b5c914d3c45a59a1af8f24b5a31a56af77",
	"title": "Dissecting APT21 samples using a step-by-step approach – CYBER GEEKS",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 9255539,
	"plain_text": "Dissecting APT21 samples using a step-by-step approach – CYBER\r\nGEEKS\r\nPublished: 2020-11-27 · Archived: 2026-04-05 16:14:39 UTC\r\nSummary\r\nIn this blog post we’re presenting a detailed analysis of 2 malicious files (a backdoor known as “Travelnet”) linked to\r\nan APT (Advanced Persistent Threat) actor called APT21.\r\nAPT21 , also known as Zhenbao or Hammer Panda, is a group of suspected state sponsored hackers of Chinese origin.\r\nAccording to multiple online sources, that we have referenced in the article, APT 21 historically targeted the Russian\r\ngovernment and groups which seek greater autonomy or independence from China, such as those from Tibet or\r\nXinjiang.\r\nThe first file is a dropper used to register a malicious DLL (NetTraveler trojan) as a service. The main purpose of the\r\ntrojan is to gather information about the environment such as user name, host name, IP address of the host, Windows\r\nOS version, different configurations of the CPU, information about memory consumption, the list of processes. The\r\nmalicious process is interested in .doc, .docx, .xls, .xlsx, .txt, .rtf, .pdf files on disk and also on USB drives and\r\nnetwork shares in order to exfiltrate them. During the entire infection, multiple .ini configuration files are created and\r\nalso the malware has the capability to download and execute additional files on the infected machine. The data is\r\ncompressed using a custom Lempel-Ziv-based algorithm and encoded with a modified Base64 algorithm before it will\r\nbe exfiltrated to the Command and Control server.\r\nTechnical analysis\r\nSection I\r\nDropper\r\nSHA256: FECA8DB35C0C0A901556EFF447C38614D14A7140496963DF2E613B206527B338\r\nOne of the first steps the malware is performing consists of creating a mutex called ” INSTALL SERVICES NOW!”\r\n(note the space). The mutex is used to avoid reinfection of an already infected machine:\r\nFigure 1\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 1 of 37\n\nThe malicious process creates a configuration file at “C:\\Windows\\System\\config_t.dat” which will be heavily used\r\nduring the entire infection. The API call used to accomplish this task is CreateFileA and it’s presented in figure 2:\r\nFigure 2\r\nThe following bytes found at a precise location in the malicious file are read in order to decrypt them:\r\nFigure 3\r\nThe decryption routine is shown in the next figure and consists of a XOR operation with 0x3E:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 2 of 37\n\nFigure 4\r\nAfter the decryption is over the new string represents a URL which contains the C2 server as we’ll see later on:\r\nFigure 5\r\nThe configuration file is populated using WritePrivateProfileStringA API calls as shown below. Please note that\r\nWebPage is equal to the string decrypted above and the others options will be explained later on in a better context:\r\nFigure 6\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 3 of 37\n\nFigure 7\r\nFigure 8\r\nFigure 9\r\nFigure 10\r\nAfter all of these API calls the configuration file has the following schema:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 4 of 37\n\nFigure 11\r\nNow there is a byte at offset 0x334 in the file which indicates if the malicious process is supposed to use a proxy or\r\nnot (by default this value is 0 and UP=0 means the malware is not using a proxy for network communications). If that\r\nbyte is set to 1, the malware writes UP=1 in the configuration file and also 5 additional values: PS (proxy address), PP\r\n(proxy port), PU (proxy user), PW (proxy password) and PF (unknown). RegQueryValueExA API is used to retrieve\r\nthe type and data for netsvcs (svchost.exe) associated with\r\n“HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Svchost”:\r\nFigure 12\r\nThe malicious file enumerates all the available services on the host and compares them with a hardcoded list presented\r\nin figure 13. The first service which is not found on the system will be used for malicious purposes as we’ll describe\r\nfurther.\r\nFigure 13\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 5 of 37\n\nThe strategy is as follows: it will enumerate the keys corresponding to a service like\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\\u003cServiceName\u003e” in order to see if the service is\r\ninstalled or not. The following services have been present on the analyzing machine: CertPropSvc, SCPolicySvc,\r\nlanmanserver, gpsvc, iphlpsvc, msiscsi, schedule, winmgmt, SessionEnv and the first one which was missing is\r\nFastUserSwitchingCompatibility. RegOpenKeyExA API is utilized to check for the existence of the services, one such\r\nexample is detailed in the figure below:\r\nFigure 14\r\nThe file “C:\\WINDOWS\\system32\\FastUserSwitchingCompatibilityex.dll” associated with\r\nFastUserSwitchingCompatibility service is supposed to be deleted by the running process (it doesn’t exist on the\r\nmachine):\r\nFigure 15\r\nA new service called “FastUserSwitchingCompatibility” is created using CreateServiceA API function which tries to\r\nimpersonate the legitimate service, the binary path of the service being %SystemRoot%\\System32\\svchost.exe -k\r\nnetsvcs (legitimate process):\r\nFigure 16\r\nIf the call is successful we’ll see a registry key like the one displayed in figure 17. (this technique is part of evasion\r\ntechniques). Attackers will try to impersonate/use legitimate system binaries or libraries on the host to hide malicious\r\nactivity. This will allow them to blend with regular activity and remain hidden. (you can find more details about\r\nlolbins at https://lolbas-project.github.io/).\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 6 of 37\n\nFigure 17\r\nIn order to verify that the service was successfully created the malicious process tries to open\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility” (now it exists\r\nbecause it corresponds to the newly created service):\r\nFigure 18\r\nA new key called “Parameters” is created under\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility” using\r\nRegCreateKeyA API. This will be used to register a malicious DLL as a service:\r\nFigure 19\r\nThe process creates an empty file called temp.bat in the same directory as the initial executable (in our case, Desktop).\r\nThe content of the batch file is shown below:\r\nFigure 20\r\nThe purpose of the batch file is to register the DLL found at\r\n“C:\\WINDOWS\\system32\\FastUserSwitchingCompatibilityex.dll” as a service by adding “ServiceDll” entry. File\r\n“C:\\WINDOWS\\system32\\FastUserSwitchingCompatibilityex.dll” doesn’t exist at this time, however it’s created by\r\nthe malware using CreateFileA API as shown below (it will be populated with malicious code as we’ll see in a bit):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 7 of 37\n\nFigure 21\r\n“Timestomping” is a tehnique used by a malicious actor to modify files’ timestamps (for example created/modified\r\ntimestamps) in order not to raise any suspicions about the file. In our case the created and modified timestamps of the\r\nDLL file are set to Tuesday, August 17, 2004, 9:00:00 PM:\r\nFigure 22\r\nNow the DLL file created earlier is filled with malicious code using WriteFile API. Even if the path of the file looks\r\nlegitimate (running from “C:\\Windows\\SysWOW64” directory), it’s just impersonating a legitimate service:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 8 of 37\n\nFigure 23\r\nIt’s worth mentioning that registering a DLL file as a service is a persistence mechanism. The newly created service is\r\nstarted using StartServiceA API and the flow of execution is passed to the DLL export function ServiceMain:\r\nFigure 24\r\nSection II\r\nDLL file\r\nSHA256: ED6AD64DAD85FE11F3CC786C8DE1F5B239115B94E30420860F02E820FFC53924\r\nOne of the first steps the malware is performing is to invoke GetProcessWindowStation API which returns a handle to\r\nthe current window station and then it uses OpenWindowStationA API to open the interactive window station\r\n(“Winsta0”). The process assigns the specified window station (“Winsta0”) which is the only interactive window\r\nstation (the service is supposed to be interactive) to the calling process using the SetProcessWindowStation function:\r\nFigure 25\r\nAs in the first example the process creates a different mutex called “NetTravler Is Running!”. If it exists it will exit\r\nwithout reinfecting the machine:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 9 of 37\n\nFigure 26\r\nNow it retrieves a few elements from the configuration file config_t.dat created by the first process: WebPage,\r\nDownCmdTime, UploadRate, AutoCheck, UP and CheckedSuccess (it doesn’t exist at this time, so the function\r\nreturns 0). All of the values are extracted using GetPrivateProfileString and GetPrivateProfileInt APIs:\r\nFigure 27\r\nFigure 28\r\nFigure 29\r\nFigure 30\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 10 of 37\n\nFigure 31\r\nFigure 32\r\nBecause we’re running the DLL using an executable used by x32dbg to debug the DLL files, the process name is\r\nsimilar to “DLLLoader32_58D1.exe” (in our case). The malicious process creates a .log file which has the same name\r\nas the executable (“DLLLoader32_58D1.log”):\r\nFigure 33\r\nThe file enumerates the directories from “C:\\Program File (x86)” and the output is copied to the newly created file:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 11 of 37\n\nFigure 34\r\nRegOpenKeyExA API is used to open\r\n“HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders” registry key and\r\nthe “History” value is extracted from it using RegQueryValueEx. The content of “History” value is “C:\\Users\\\r\n\u003cUsername\u003e\\AppData\\Local\\Microsoft\\Windows\\History”:\r\nFigure 35\r\nThe malware is looking for a file called “C:\\Users\\\r\n\u003cUsername\u003e\\AppData\\Local\\Microsoft\\Windows\\History\\History.IE5\\index.dat” which contains Internet browsing\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 12 of 37\n\nhistory activity, including Internet based searches and opened files:\r\nFigure 36\r\nThe process extracts “Version” value from\r\n“HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Internet Explorer” using RegQueryValueEx\r\nfunction:\r\nFigure 37\r\nWindow 10’s Internet Explorer is Build 916299, Version 9.11.16299.0 as shown in the figure below:\r\nFigure 38\r\nThe following information is appended to the .log file: IE History is empty because that file is missing on Windows 10\r\nand the IE version (note that “version” word is written in Chinese language “版本”):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 13 of 37\n\nFigure 39\r\nGetVersionExA function is utilized to find the current operating system. The recognized versions are: Microsoft\r\nWindows 7, Microsoft Windows Vista, Microsoft Windows 2003, Microsoft Windows 2000, Microsoft Windows XP\r\nand Microsoft Windows NT:\r\nFigure 40\r\nIt also extracts the “ProductType” value from\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions” registry key. On our system the\r\nvalue is equal to “WinNT”:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 14 of 37\n\nFigure 41\r\nThe following string is appended to the .log file: “操作系统版本” translates to “Operating system version”:\r\nFigure 42\r\nThe user agent used in the network communications is always set to “Mozilla/4.0 (compatible; MSIE 6.0)”. There is\r\nalso an Accept request HTTP header as shown below:\r\nFigure 43\r\nThe process tries to connect to http://www.microsoft.com/info/privacy_security.htm (this URL used to be available in\r\nthe past) in order to verify if there is an internet connection. The HTTP request is shown in figure 44:\r\nFigure 44\r\nIf the connection is successful the following strings will be added at the end of the .log file:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 15 of 37\n\nFigure 45\r\nFurthermore UP (use proxy indicator) is set to 0 and it adds a value called CheckedSuccess (set to 1) to config_t.dat\r\nusing WritePrivateProfileStringA API:\r\nFigure 46\r\nNow, if the connection was unsuccessful , an “Method1 Fail!!!!!” message is written to DLLLoader32_58D1.log.\r\nProcess32First and Process32Next functions are used to find “EXPLORER.exe” process and then the process tries to\r\nopen it using OpenProcess API:\r\nFigure 47\r\nBasically the attacker’s purpose is to steal “explorer.exe” process’ token by calling OpenProcessToken in order to open\r\nthe access token associated with “explorer.exe” and then it uses ImpersonateLoggedOnUser function to impersonate\r\nthe security context of a user. The function calls are displayed in figure 48 and figure 49, respectively.\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 16 of 37\n\nFigure 48\r\nFigure 49\r\nThe process is using RegOpenKeyExA to open\r\n“HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings” registry key and then it\r\nextracts “ProxyEnable” value to see if the computer uses a proxy server:\r\nFigure 50\r\nAlso same function is used to get the “ProxyServer” (hostnames/IPs of the proxy server on the network) and\r\n“ProxyOverride” (hostnames/IPs that bypass the proxy server) values from the same registry key. The extraction of\r\n“ProxyServer” value is shown below:\r\nFigure 51\r\nAs in the first method, the attacker verifies if he’s able to connect to the same URL using the proxy settings he found\r\nin the registry. If the connection is successful it will append the content of that page to the .log file together with some\r\nnew parameters:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 17 of 37\n\nFigure 52\r\nAlso, because the method works, the malicious process modifies the config_t.dat file by setting UP=1, PF=10 and then\r\nPS (proxy server), PP (proxy port), PU (proxy user), PW (proxy password) are set according to the settings found. If\r\nthe connection fails, the message “Method3 Fail!!!!!” is appended to the .log file. Method4 is pretty similar to\r\nMethod3 presented above and will not be explained in details. One of the differences is that the “Method4 Fail!!!!!”\r\nmessage is appended to the .log file if the network connection isn’t successful.\r\nIf all methods fail, the infection will stop and the following operations are performed (self-deleting malware):\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Enum”,\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Parameters”,\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Security” and\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility” registry keys\r\nare deleted using RegDeleteKeyA function. The following files are deleted as well:\r\n“C:\\WINDOWS\\system32\\enumfs.ini”, “C:\\WINDOWS\\system32\\dnlist.ini”, “C:\\WINDOWS\\system32\\udidx.ini”,\r\n“C:\\WINDOWS\\system32\\uenumfs.ini” and “C:\\WINDOWS\\system32\\stat_t.ini” (some of them don’t exist at this\r\ntime).\r\nIf one of the methods enumerated above works, the malicious process sleeps for 60 seconds and then creates another\r\nthread that we’ll call Thread1 , sleeps another 10 seconds, and creates Thread2. The main thread will enter into an\r\ninfinite loop until the variable found at 0x100163E8 (absolute address) is set to 3:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 18 of 37\n\nFigure 53\r\nThread1 activity\r\nFirstly the thread retrieves the volume serial number (“A2C9-AD2F”) associated with “C:\\” directory using\r\nGetVolumeInformationA function. This number will be used as a host id in the communication with the C2 server as\r\nwe will see later on. Also it uses GetComputerNameA API to find the NETBIOS name of the computer,\r\nGetUserNameA API to find the username associated with the current thread, gethostname API to retrieve the host\r\nname for the computer and gethostbyname/inet_ntoa functions to print the IP address of the computer:\r\nFigure 54\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 19 of 37\n\nOne more time the “ProductType” value from\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions” registry key is retrieved as\r\nshown in figure 55:\r\nFigure 55\r\nThe malicious process enumerates the available disks drives and it’s interested in type 3 drives (DRIVE_FIXED) as\r\nshown in the screenshot below:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 20 of 37\n\nFigure 56\r\nRegOpenKeyExA API is utilized to open\r\n“HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0” registry key and then\r\nRegQueryValueEx is used to retrieve “VendorIdentifier”, “Identifier” and “~MHz” values:\r\nFigure 57\r\nThe process uses GlobalMemoryStatus function to get information about system’s usage of physical and virtual\r\nmemory. All the information extracted so far will be stored in a new file called\r\n“C:\\Windows\\SysWOW64\\system_t.dll” in order to exfiltrate it. All translations from chinese to english are provided\r\nto better understand the content of the file: “计算机信息” translates to “computer information”, “计算机” translates to\r\n“computer”, “用户名” translates to username, “Ip地址” translates to “Ip address”, “操作系统” translates to\r\n“operating system”, “磁盘空间” translates to “disk space”, “总磁盘空间为” translates to “The total disk space is”,\r\n“剩余磁盘空间为” translates to “The remaining disk space is”, “占” translates to “take up”, “物理内存” translates to\r\n“physical memory”, “总物理内存” translates to “Total physical memory” and “可用内存” translates to “Available\r\nmemory”:\r\nFigure 58\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 21 of 37\n\nA list of processes is retrieved using Process32First and Process32Next APIs as shown below:\r\nFigure 59\r\nAfter the operation is complete and the malware obtains the list of processes, it will be appended to system_t.dll (“进\r\n程列表” translates to “Process list”):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 22 of 37\n\nFigure 60\r\nThe next step is to create a pipe using CreatePipe API . This will be used as an inter-process communication\r\nmechanism. It will create a new process “ipconfig /all” which displays the full TCP/IP configuration for all adapters\r\nand the output will be transmitted back to the original process through pipes:\r\nFigure 61\r\nThe output of the ipconfig process is saved to system_t.dll as shown in the figure below:\r\nFigure 62\r\nThe malware checks the UP value from config_t.dat using GetPrivateProfileInt function. According to the Kaspersky\r\nreport, the content of system_t.dll file will be compressed using a custom Lempel-Ziv-based algorithm and encoded\r\nwith a modified Base64 algorithm. The function responsible for this operation and the “modified Base64” alphabet is\r\ndisplayed in figure 63:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 23 of 37\n\nFigure 63\r\nThe encoded data is exfiltrated via a GET request to vipmailru[.]com (C2 server). The following parameters are\r\nprovided in the URL: hostid = the serial number of current disk drive, hostname = hostname, hostip = IP of the\r\nmachine, filename = “travlerbackinfo-\u003cyear\u003e-\u003cmonth\u003e-\u003cday\u003e-\u003chour\u003e-\u003cminute\u003e.dll”:\r\nFigure 64\r\nIf the server response contains “Success:”, the exfiltration was successful. The malicious process also deletes\r\nsystem_t.dll using DeleteFileA API . It performs another GET request (to the same C2 server) with the parameters\r\nincluding “action=getcmd” and others which were already explained above:\r\nFigure 65\r\nThe result of the query must contain “[CmdBegin]\\r\\n” at the beginning of the message and “[CmdEnd]\\r\\n” at the end\r\nof it. The message between the “borders” is saved at “C:\\Windows\\System32\\stat_t.ini” and then the process performs\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 24 of 37\n\na GET request (same C2 server) with a modified parameter “action=gotcmd” and other parameters used before:\r\nFigure 66\r\nAs before, if everything works fine the file expects an HTTP response which contains “Success” string. The process is\r\nlooking to delete a file called “C:\\Windows\\SysWOW64\\dnlist.ini” which doesn’t exist at this time. The file will be\r\ncreated and populated with the following data:\r\nFigure 67\r\nFile stat_t.ini is deleted using DeleteFileA function and then it calls GetACP API which returns the current Windows\r\nANSI code page identifier for the operating system. Because the value of ScanAll is True in dnlist.ini, the malware\r\nscans for all available disk drives using GetLogicalDrives API and then compares the type of them with 3\r\n(DRIVE_FIXED) or 4 (DRIVE_REMOTE) using GetDriveTypeA API:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 25 of 37\n\nFigure 68\r\nLet’s suppose that “C:\\” is the first drive found by the process. The file will enumerate all files and directories from\r\nthe “C:\\” drive and the directories name will be saved as dn (where n=1,2,3, …) and the files name will be stored as fn\r\n(where n=1,2,3,…), together with filecount (total number of files) and dircount (total number of directories). All\r\ninformation described will be stored in a new file called “C:\\Windows\\SysWOW64\\enumfs.ini”:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 26 of 37\n\nFigure 69\r\nThe operation applied to “C:\\” drive is recursive and it’s applied to each directory (all information will be appended to\r\nenumfs.ini). The following information is added/modified in dnlist.ini:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 27 of 37\n\n[EnumTime]\r\nDateTime = scan date\r\n[ScanList]\r\nScanAll = False\r\nThe enumfs.ini file will be transferred to the C2 server via a GET request as before (compressed + encoded). The\r\nfilename parameter has the following form: “FileList-\u003cmonth\u003e\u003cday\u003e-\u003chour\u003e\u003cminute\u003e\u003csecond\u003e.ini”:\r\nFigure 70\r\nThe server response is expected to contain “Success:”. The attacker is interested in the following types of files: .doc,\r\n.docx, .xls, .xlsx, .txt, .rtf, .pdf (Types parameter from dnlist.ini file). The malicious process tries to open uenumfs.ini\r\nwhich doesn’t exist at this moment, and then enumerates the files found in\r\n“C:\\User\u003cUsername\u003e\\AppData\\Local\\Temp\\ntvba00.tmp\\”. This specific directory will be created by Thread2 and\r\nwill contain all files which have been selected to be exfiltrated to the C2 server:\r\nFigure 71\r\nNow the process contacts the C2 server again with the parameter “action=getdata”. It expects one of the following\r\nresponses: “A2C9AD2F:UNINSTALL”, “A2C9AD2F:UPDATE”, “A2C9AD2F:RESET” or “A2C9AD2F:UPLOAD”\r\n(note that “A2C9AD2F” is the volume serial number extracted a while ago):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 28 of 37\n\nFigure 72\r\nCase 1: (UNINSTALL)\r\nThe following registry keys are deleted using RegDeleteKeyA API:\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Enum”,\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Parameters”,\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility\\Security” and\r\n“HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\FastUserSwitchingCompatibility”. Also the\r\nprocess deletes enumfs.ini, dnlist.ini, “C:\\WINDOWS\\system32\\udidx.ini”, uenumfs.ini and stat_t.ini. One such call is\r\ndisplayed below:\r\nFigure 73\r\nThe C2 server is informed that the operation is complete by performing a GET request with “action=updated”\r\nparameter:\r\nFigure 74\r\nCase 2: (UPDATE)\r\nSame registry keys and files are deleted as described above. Moreover, there is a GET request to the Command and\r\nControl server using “action=datasize” parameter and the HTTP response is supposed to include “Success:” if\r\neverything works smoothly:\r\nFigure 75\r\nThe malware is trying to download a file named updata.exe from the C2 server (this file not available for analysis, as\r\nthe C2 server was down at the time of the analysis):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 29 of 37\n\nFigure 76\r\nThe magic bytes of the downloaded file are compared to “MZ” (the format for executable, DLL files in Windows) and\r\nalso it’s looking for “PE” string at a specific offset as well. The downloaded file is saved as “C:\\Windows\\install.exe”\r\nand run by the malicious process:\r\nFigure 77\r\nThe same request as in Figure 74 is performed once more in order to keep the server in the loop for every new step.\r\nCase 3: (RESET)\r\nThe following files are deleted: enumfs.ini, dnlist.ini, “C:\\WINDOWS\\system32\\udidx.ini”, uenumfs.ini and stat_t.ini.\r\nSame request displayed in Figure 74 is used to contact the C2 server (this step is done in every case).\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 30 of 37\n\nCase 4: (UPLOAD)\r\nThis case is identical to Case 2 (UPDATE) with the difference that no files/registry keys are deleted.\r\nAfter the execution flow passes all cases, the process sleeps for 60 seconds and then it goes back in the loop.\r\nThread2 activity\r\nRegisterClassA function is used to register a window class for use in CreateWindow/CreateWindowEx calls, it creates\r\na windows using CreateWindowExA (windows class name is “NTMainWndClass”, 0x80000000 – WS_POPUP style).\r\nAlso, the window procedure used in RegisterClassA API call (sub_10004535) is called 5 times as follows (one for\r\neach type of message): 0x81 (WM_NCCREATE), 0x83 (WM_NCCREATE), 0x01 (WM_CREATE), 0x05\r\n(WM_SIZE) and 0x03 (WM_SIZE). We should also mention the following calls: ShowWindow (Sets the specified\r\nwindow’s show state), UpdateWindow (it sends a WM_PAINT message to the window), GetMessage (gets a message\r\nfrom the calling thread’s message queue) and TranslateMessage (translates messages into character messages):\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 31 of 37\n\nFigure 78\r\nThe malware is interested in WM_DEVICECHANGE (0x219) messages with a parameter of\r\nDBT_DEVICEARRIVAL (0x8000) which means that for example a new USB drive has been plugged in or a network\r\nshared folder is mounted on the system:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 32 of 37\n\nFigure 79\r\n“USearch” and “UTypeLimit” values parsed from dnlist.ini are expected to be set to “True”, also “UAuto” value is\r\n“False” in dnlist.ini (this could indicate if the exfiltration of the targeted files should be automatically or not). The\r\nattacker is also interested in “Types” parameter (the targeted extensions) and we’ll see why in a bit. The idea is to scan\r\neach and every device inserted and also the network shares mounted on the host and create a “file system” structure in\r\nuenumfs.ini file (as it did in Thread1):\r\nFigure 80\r\nAs in the first case, this search will apply for every directory found on the drive, recursively. The process creates a\r\n“C:\\Users\\\u003cUsername\u003e\\AppData\\Local\\Temp\\ntvba00.tmp\\” directory and its attribute is set to hidden. The following\r\nfile is also created: “C:\\Windows\\SysWOW64\\uenumfs.ini” (the content of it will be similar to enumfs.ini):\r\nFigure 81\r\nFor each file found on the USB drive/network share, the process compares it’s extension with the list mentioned\r\nbefore: .doc, .docx, .xls, .xlsx, .txt, .rtf, .pdf:\r\nFigure 82\r\nLet’s suppose that “C:\\eula.1028.txt” (for the sake of simplicity) is a targeted file. The malware calculates a hash\r\n(MD5) of a combination between the filename and last modified timestamp (please note the initialize variables which\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 33 of 37\n\ncorrespond to MD5 algorithm):\r\nFigure 83\r\nFigure 84\r\nAfter the function is finished the following result will represent the hash (unique identifier) corresponding to\r\neula.1028.txt file:\r\nFigure 85\r\nNow “C:\\eula.1028.txt” is copied to “C:\\Users\\\u003cUsername\u003e\\AppData\\Local\\Temp\\ntvba00.tmp\\U2007-11-07-12-00-\r\n5f7a78e7927532ba2a930ec8d47e252a.txt” (hidden file) – 2007 (year), 11 (month), 07 (day), 12 (hour), 00 (minute),\r\n5f7a78e7927532ba2a930ec8d47e252a is the hash computed above (all values correspond to last modified timestamp):\r\nFigure 86\r\nThe process creates “C:\\Windows\\SysWOW64\\udidx.ini” file and will add all hashes computed as explained before:\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 34 of 37\n\nFigure 87\r\nLast modified timestamp of the new file is set as the value extracted from the initial file:\r\nFigure 88\r\nAn example of udidx.ini file after copying all document-related files is shown in the figure below:\r\nFigure 89\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 35 of 37\n\nFinally the file is using DefWindowProcA API to ensure that window messages the application does not process have\r\na default processing function (WM_DEVICECHANGE – 0x219, DBT_DEVICEARRIVAL – 0x8000):\r\nFigure 90\r\nReferences\r\nKaspersky report: https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2018/03/08080841/kaspersky-the-net-traveler-part1-final.pdf\r\nVirusTotal link:\r\nhttps://www.virustotal.com/gui/file/feca8db35c0c0a901556eff447c38614d14a7140496963df2e613b206527b338/detection\r\nVirusTotal link:\r\nhttps://www.virustotal.com/gui/file/ed6ad64dad85fe11f3cc786c8de1f5b239115b94e30420860f02e820ffc53924/detection\r\nMSDN: https://docs.microsoft.com/en-us/windows/win32/api/\r\nFireEye: Advanced Persistent Threat Groups (APT Groups)\r\nDarkReading: Chinese Cyberspies Pivot To Russia In Wake Of … (darkreading.com)\r\nINDICATORS OF COMPROMISE\r\nC2 domain: vipmailru[.]com\r\nSHA256: FECA8DB35C0C0A901556EFF447C38614D14A7140496963DF2E613B206527B338\r\nSHA256: ED6AD64DAD85FE11F3CC786C8DE1F5B239115B94E30420860F02E820FFC53924\r\nMutexes: “NetTravler Is Running!”, ” INSTALL SERVICES NOW!”\r\nFile names on disk:\r\n%System%\\config_t.dat\r\n%windir%\\system32\\enumfs.ini\r\n%windir%\\system32\\dnlist.ini\r\n%windir%\\system32\\udidx.ini\r\n%windir%\\system32\\uenumfs.ini\r\n%windir%\\system32\\stat_t.ini\r\n%windir%\\system32\\system_t.dll\r\n%windir%\\install.exe\r\n%TEMP%\\ntvba00.tmp\\\r\ntemp.bat\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 36 of 37\n\nSource: https://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nhttps://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/\r\nPage 37 of 37",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://cybergeeks.tech/dissecting-apt21-samples-using-a-step-by-step-approach/"
	],
	"report_names": [
		"dissecting-apt21-samples-using-a-step-by-step-approach"
	],
	"threat_actors": [
		{
			"id": "808d8d52-ca06-4a5f-a2c1-e7b1ce986680",
			"created_at": "2022-10-25T16:07:23.899157Z",
			"updated_at": "2026-04-10T02:00:04.782542Z",
			"deleted_at": null,
			"main_name": "NetTraveler",
			"aliases": [
				"APT 21",
				"Hammer Panda",
				"NetTraveler",
				"TEMP.Zhenbao"
			],
			"source_name": "ETDA:NetTraveler",
			"tools": [
				"Agent.dhwf",
				"Destroy RAT",
				"DestroyRAT",
				"Kaba",
				"Korplug",
				"NetTraveler",
				"Netfile",
				"PlugX",
				"RedDelta",
				"Sogu",
				"TIGERPLUG",
				"TVT",
				"Thoper",
				"TravNet",
				"Xamtrav"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "254f2fab-5834-4d90-9205-d80e63d6d867",
			"created_at": "2023-01-06T13:46:38.31544Z",
			"updated_at": "2026-04-10T02:00:02.924166Z",
			"deleted_at": null,
			"main_name": "APT21",
			"aliases": [
				"HAMMER PANDA",
				"TEMP.Zhenbao",
				"NetTraveler"
			],
			"source_name": "MISPGALAXY:APT21",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434695,
	"ts_updated_at": 1775826750,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/090fd0b5c914d3c45a59a1af8f24b5a31a56af77.pdf",
		"text": "https://archive.orkl.eu/090fd0b5c914d3c45a59a1af8f24b5a31a56af77.txt",
		"img": "https://archive.orkl.eu/090fd0b5c914d3c45a59a1af8f24b5a31a56af77.jpg"
	}
}