Internals of TA428 Operation LagTime IT

Threat research on TA428 activities around 2020

Chinese Government Whistleblower on truth of wrongdoing of Chinese Government in a interview with 60 minutes that aired on YouTube on Nov 24, 2019.

Executive Summary

In this blog i will walk you through the internals of tools deployed by “TA428” in “OPERATION LAGTIME IT” when “TA428" hacked into Japan “NTT Security” monitoring system. The attack was carried in Feb 2020 by deploying Poison Ivy & Cotx RAT and attackers also performed lateral movement in network to further carry away the breach.


In this blog i will reflect & shade light on Chinese APT espionage group “TA428” that targets East Asia governments for carrying out espionage operations & minorities ethnic groups in China.

In depth Analysis


After running Eternal Blue on several host attacker of “TA428” ran newly discovered RAT at that time dubbed as “Tmanger”. It was dubbed as “Tmanger” as what it’s PDB file named as Tmanger which is typo like other typo in export table of pefile as “Entery”. Tmanger and Smanager are both related, that is later discussion-ed in this blog. During that time NTT Security has observed active development of RAT from version 1.0 to 4.5.

View of pop-up on dropping version 4.4 MloadDll in IDA.

Basically RAT consists of following three parts:-

SetUp — Expand and Run MloadDll

MloadDll — Deploy and run Client

Client — RAT body.

All names of the file are described as in PDB files.


Basic Analysis: Using PE Studio
View of Information Gathering using PE Studio on SetUp PE file.
Advanced Analysis

On execution this “SetUp” file create event using CreateEvent with specific lpName as “{A14D0DC3-E26A-4551–8F84–08E738AEC720} “ though Japan NTT Security observed value change during different versions of Tmanger which all satisfies following regular expression:

/ [0–9a-f] {8}-[0–9a-f] {4}-4551–8f84–08e738aec [0–9a-f] {3} /

Then as moving further in the WinMain module of SetUp file , there is check using the “IsUserAnAdmin” which is done for establishing differ persistence mechanism on the basis of if the user is Admin or not.

Pseudocode of WinMain function.

If user is ADMIN

On hovering to the “unk_4643E8” i came across xored data with key “0x88”.

Subroutine “sub_401F00” is the function describes the algorithm used for xoring the data.

Call Graph and Pseudocode of “sub_401F00”.

Likewise, there are many other xored data after some null bytes . Pulling up cyberchef for this task makes task easier in decoding data.

This decoded data is later used for registering for service. Decoded data is as:-

DFS Replication

FTP Publishing Service


Software Licensing

SL UI Notification Service

Terminal Services Configuration

Windows Media Center Extender Service

Windows Media Center Service Launcher .

Then as moving further in WinMain module there is the subroutine “sub_402F90”.

View of call graph and pseudocode of that subroutine named “sub_402F90”.

It is used to registry the Dll in the System32.

Other than that these are the decoded data from this module:-

SOFTWARE/Microsoft/Windows NT/CurrentVersion/Svchost


%SystemRoot%/System32/svchost.exe -k netsvcs






/ Parameters

Basically what happens in this module “ sub_402F90” is that registry subkey and cmds are being xored with key “0x88” as like before it was done in the WinMain module & the function that does is the “Xoring_func_with_key_0x88”.

And after that registry operations with xored key is being performed using function “registry_key_ops”.

View of call graph and pseudocode of that subroutine named as “registry_key_ops”.

And moving back to WinMain module, next in the WinMain module execution of else statement occurs which happens when, “User is not Admin”.

In that case, what happen is that using function FindFirstFileA in if statement it checks for the file which is Buffer -> “Rahoto.exe” in TEMP directory & if that condition is satisfied as negative value of 1 then it copies file using CopyFileA function in the TEMP directory.

Using “registry_ops” function registers a registry with key HKEY_CURRENT_USER and subkey as “CurrentVersion/Run” to set it to autostart & it acts as MloadDll.

Hashed value “xmmword_420750” is the subkey to the key “HKEY_CURRENT_USER” passed on to the “registry_key_ops” function. This registry is used by it to set it to autostart & it works as MloadDll.

Pseudocode of “registry_ops” function.

Basic Analysis : Using PE Studio

View of Information gathering on MloadDll using PE Studio.
Advanced Analysis

Basically this dll file has 3 exports file which are as follows:




export table of MloadDll.

Since i had performed dynamic analysis on the executable in Online Sandbox Any.Run which shows that the this dll file executes using the following command.

“C:\Windows\System32\rundll32.exe” “C:\Users\admin\AppData\Local\Temp\MloadDll.dll.exe”, Entery

When i had looked into the binary in Ida disassembler there is execution point of both Entery and ServiceMain module from the .rdata section of binary.

IDA text view along with the ServiceMain function.

& it suggests that the on execution this dll firstly ServiceMain module is executed which is a nested subroutine “sub_10001850” inside the Entery function.

ServiceMain module:-

In this module , if you see that in the end the call to “call_rc4_key_genr” module is being made , other than that in this function service is being registered using function RegisterServiceCtrlHandlerW and handle to the service status which is “hServiceStatus”.

Call graph & pseudocode of ServiceMain function.
call_rc4_key_genr function:-

The first call is made to rc4_key_genr() function which is the rc4 based encryption key generation function.

Call graph & Pseudocode of rc4_key_genr() function.

And as the key data is generated it decrypts the Config data to connect to C&C server at port 8080.

On executing sample in online sandbox (Any Run).

Then the extraction of the obtained data happens . And this data obtained is the Client.dll .


Basic Analysis

Information gathering on Client.dll using PE Studio.
Advanced Analysis

In this dll on loading it in the IDA , i had observed the it has 2 exports which are as follows:-


DllEntryPoint .

export table of Client.dll.

On execution of this dll in Online Sandbox Any Run, i had observed that it executes the following command :

“C:\Windows\System32\rundll32.exe” “C:\Users\admin\AppData\Local\Temp\85a53a2525643a84509b10d439734509203a2a74e1a167d5c3494e37a47c8c8c.bin.exe”, callfunc

which tells that on execution module callfunc is being called.

By this time , i hovered cursor to the text view of disassembly to the address where “callfunc” which is also present in the .rdata section of dll.

Text View in IDA showing .rdata section where callfunc is present.
Callfunc function:-

In this module, there is the call to “ops_func”.

Call Graph & Pseudocode of callfunc() function.
ops_func function:

In this module, firstly the func “GetInputState” is being called to check that if the cursor is on the current thread, then current thread identifier is being fetched using “GetCurrentThreadId” and passed on to v2.

Call Graph & Pseudocode of ops_func() function.

Then after performing Message ops and getting system time in UTC , event is being created using CreateEventW function with the event object as “{B14D0DC3-b26c-4551–8F84–08E738AEC710}” & then after it WSAStartup is called to init use of Winsock Dll in the if statement, otherwise the in else statement execution firstly call to following function is being made :






From which through the “get_proc_addr_info” function, process and address information is being gathered.

Call Graph & Pseudocode of get_proc_addr_info() function.

And after that call to “get_drive_info” function is being called which fetch drive information using “GetDriveTypeA”.

Call Graph & Pseudocode of get_drive_info() function.

Then func “rw_chcp_cmd” read and write ops are being performed after creating pipe , fetching startup information and system directory information.

Call Graph & Pseudocode of rw_chcp_cmd() function.

In the module “get_C2_info” information on local host machine is being gathered for C2.

Call Graph & Pseudocode of get_C2_info() function.

In the next function “get_session_info” to which call is made perform task of getting active console session id.

Call Graph & Pseudocode of get_session_info() function.

Then after creating thread using “CreateThread” , socket connection is being created using “socket” function if that succeeds Mutex object named as “sock_hmutex” & “cmd_hmutex” are being created. Then after that connection with C2 Server is being checked in parameters of while loop through the “connect_wth_C2” function.

Call Graph & Pseudocode of connect_wth_C2() function.

Then after that Sleep for while if statement is being executed passed with the parameter “communicate_with_C2” function .

Call Graph & Pseudocode of communicate_with_C2() function.

In this communication with C2 server is being made using functions as follows:-
send_info_to_connected_sock / send_info_to_sock

In first function, “send_info_to_connected_sock” information buffer is being send in the in form of encrypted rc4 packet is being send to C2 server using “encrypt_netw_traffic_with_rc4” function.

Call Graph & Pseudocode of send_info_to_sock() function.

Similarly second function, “recv_info_from_C2” receives information buffer in form of rc4 encrypted packet from C2 server, & for receiving packet from in rc4 encrypted form it uses same function “encrypt_netw_traffic_with_rc4”.

Here is the pseudocode and call graph of “encrypt_netw_traffic_with_rc4” function.

Call Graph & Pseudocode of encrypt_netw_traffic_with_rc4() function.

That’s how it communicate with C2 server. & inside if statement call to “buffr_ops_via_pipe_func” function is being made. In this module, operations on buffer received from C2 earlier is being performed like reading buffer & information buffer is being send to the C2 server through “send_info_to_connected_sock” function & this function is passed into the “dword_10027484”.

Call Graph & Pseudocode of buffr_ops_via_pipe_func() function.

Next in the conditional if statement it is checked if “dword_10027484” is satisfied as false.& if that stratifies thread is being terminated, otherwise using function “WaitForSingleObject” with parameter “dword_10027484” is being executed & what it does is that it waits for the “dword_10027484” execution and after again sending information buffer to C2 server through socket connection socket is being closed through “closesocket”.

Then after that function “exec_cmd_command” executes, in which firstly module and temp directory path is fetched then in the if statement satisfying condition “&Buffer[strlen(Buffer) + 1] != &Buffer[1]” , system directory is been obtained and file named “tmp_22.bat” is being copied to “v1” and then the file is being created & inside the if statement file is being written to “v3” and handle to “v3” is being closed. And in another if statement “cmd.exe /c” command is being executed. And in the end file which is created and passed to v0 is being returned by this function to the ops_func and then by the execution of “WSACleanup” use of the Winsock 2 DLL(Ws2_32.dll) is being terminated and the value as true is being returned by this function to Callfunc function.

Call Graph & Pseudocode of exec_cmd_command() function.


Around July 2020 Japan NTT Security observed new variant of malware which has slightly different behavior as compared to all of those RATs variants of Tmanger. All the Tmanger variant analyzed are having similar behavior but the malware found at that time is quiet different. It was dubbed as the “Albaniiutas” malware because of it’s filename at the time it was found.

Due to the similarity in the structure of this malware , it can said that it is being developed by same author compared to as that of the Tmanger.

Albaniiutas resource data is similar to that of Tmanger.

From Japan NTT Security analyst “Hiroki Hada” , it was observed that initial attack is launched by the albaniiutas.rar. When the .rar file is unzipped it pops out “utas.xlsx .exe” file is the exe file, disguised as an XLSX file. On executing this file, it opens the file XLSX and EXE file packed in the resource area. The XLSX file contains contact information of the members of Citizens’ Representative Hural in Mongolia. It suggests that the TA428 is targeting Mongolian political organizations & it is relevant with the characteristics of TA428. Whereas the EXE file named as “cssrs.exe” is being created in directory “C: \ MSBuild \ WindowsUpdate \ S-1–2 \”. Several other files are created but their role is similar to that of the Tmanger. It was all according to “ Hiroki Hada” analysis.

Overall flow (if not Admin) [Source: Japan NTT Security].

Jumping into the WinMain module , firstly the event is been created with event object named as “{F14E0EF3-E26A-4551–8F84–08E738AEC912}” using CreateEventW function, which matches with the regular expression earlier i had mentioned during analysis of Tmanger.

Call graph & pseudocode of WinMain() function.

Then after that in the if statement check for the condition if user is an admin is being done.

In case of user turned out to be admin , the data encrypted with the RC4 encryption key “L!Q@W#E$R%T^Y&U*A|}t~k” is decrypted.

Mapping RC4 key in IDA text view using rc4_encrypt_init() function.

For that purpose two functions “rc4_encrypt_init” & “rc4_encrypt_xor_loop” are being used , where “rc4_encrypt_init” is being used for initialization and scrambling phase and “rc4_encrypt_xor_loop” act as xoring stage for RC4 encryption.

rc4_encrypt_init function:

This module carries out initialization and scrambling stage in RC4 encryption.

Call graph & pseudocode of rc4_encrypt_init() function.

rc4_encrypt_xor_loop function:

This module carries out xoring stage for the RC4 encryption.

Call graph & pseudocode of rc4_encrypt_xor_loop() function.

Decrypted data by using these two function is “XpEXPrint.dll”, which is a dll that is created later. Then follows up the call to “call_AES_256_decrypt” function in which another data 162 from resource section is been decrypted using AES-256 Decryption Algorithm using function “AES_256_Decrypt” & string “e4e5276c00001ff5” which is copied in v35 is used to generate key at that time.

This is pseudocode and call graph of AES 256 based decryption algorithm in which Crypto APIs are used. Data decrypted is in deflated form , inflate it & save it in SYSTEM32 as “XpEXPrint.dll” .

Call Graph & Pseudocode of AES_256_Decrypt() function.

Again obtain data from the resource section , obtained data is 163 & 165. Like before using RC4 encryption key “L!Q@W#E$R%T^Y&U*A|}t~k” decrypt data 163 as the file name vjsc.dll and 165 is named as the file name Scrpt.exe & both are saved to System32 & for that functions rc4_encrypt_init & rc4_encrypt_xor_loo are used.

Then call to get_sys_info function is being made in which the while creating file “vjsc.dll” , it has string “C: \ Users \ power \ AppData \ Local \ Microsoft \ Internet Explorer \ CXXX.dll” , but rewrite that part to your own PATH & it is being used by attackers for creating malware.

Then as move out this function, then inside the if statement call to “execute_shell_cmd” function is made in which Scrpt.exe is run-ed with ShellExecuteExW.

Call Graph & Pseudocode of execute_shell_cmd function.

Where “ Scrpt.exe” is a Microsoft Visual J# cmdline tool . It sideloads vjsc.dll in same directory at run time and call function “VJSCCommandLineCompile” from “vjsc.dll” exports.

Viewing Script.exe in PE-Bear.

Firstly the xored data with key “0x88” is being decoded by “vjsc.dll”. Following is the decoded data:

DFS Replication

FTP Publishing Service


Software Licensing

SL UI Notification Service

Terminal Services Configuration

Windows Media Center Extender Service

Windows Media Center Service Launcher

SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Svchost





% SystemRoot% \ System32 \ svchost.exe -k netsvcs

MACHINE \ SYSTEM \ CurrentControlSet \ Services \


GetSystemDirectoryA .

& copies XpEXPrint.dll with random 4-character filename. Then using the previously decoded string , register it as service.

If user is not Admin

From resource area obtain 161, 164 &165 decrypt it using rc4_encrypt_init & rc4_encrypt_xor_loop with same symmetric RC4 key “L!Q@W#E$R%T^Y&U*A|}t~k” , where 161 is decrypted as “vjsc.dll”, 164 as “Xwreg.exe” & 165 as “Scrpt.exe”, is being written to Application Data\\Microsoft\\Internet Explorer\\ location during execution of function “get_sys_info” ending. At that point of time, vjsc.dll is C: \ Users \ Wasten \ AppData \ Local \ Microsoft \ Internet Explorer \ FindX.exe, and Xwreg.exe is C: \ Users \ Wasten \ AppData \ Local \ Microsoft \ Internet Explorer \ WSMprovhost. Then as like during the analysis of Tmanger, this time also date file manipulation time is being set to date of 10 years ago.

Another file named “Scrpt.exe” is used to side-load “vjsc.dll” with the ShellExecuteExW is also present is same directory. “vjsc.dll” is also named as “RegAdd.dll” & another file that exists in same directory is being set to start automatically as applying registry key “CurrentVersion \ Run”.

Then the main file “Cssrs.exe” removes “vjsc.dll”, then the .rdata section being decrypted using AES-256. When this decrypted of .rdata section is being done while making use of Crypto APIs , string “e4e5276c00001ff5” is being used to generate key to decrypt encrypted data.

Resultant data is “vjsc.dll” & it’s being written to “AppData \ Local \ Microsoft \ Internet Explorer” as before. In the end, “vjsc.dll” is again sideloaded using ShellExecuteExW through “Scrpt.exe” from same directory.


Other than this name these are following names of this file:-

When loading this file from ServiceMain event with event object named “{A24D0DC3-E26A-4551–8F84–08E738AEC718}” is being created.

In the DllEntryPoint function call to “bof_mitigation” & “call_Dll_Main” function is being made.

Stepping into the “call_Dll_Main”, in function “call_Dll_Main”, call to main function “DllMain” is being made.

Then the call to “StartAddress” function is being made, in which the data is again decrypted as like seen before previous sample using AES-256 decryption from .rdata section. Same string “e4e5276c00001ff5” is used for decryption key generation for encrypted data present in .rdata section. This produce Dll file for loading and running & it named as ClientX.dll.


This file also act as the main part of RAT as like Client.dll in Tmanger. In sub-routine “sub_10002DE0” which is being executed from .rdata section this .dll file.

As it can be observed that two functions rc4_init_stage() & rc4_xor_stage() are being used for decrypting data with RC4 symmetric encryption/decryption key which is “L!Q@W#E$R%T^Y&U*A|}t~k” in “rc4_init_stage()” function. Followed by function “ rc4_xor_stage()” performs xoring operation which is quiet similar to function “rc4_encrypt_xor_loop” as seen earlier in this blog.

Mapping RC4 key.

Decrypted config is as follows:-

http [:] //go.vegispaceshop [.] org / shop.htm




also decrypts User-Agent with the same RC4 algorithm. Just after that, it gets the host name using gethostname. Following User-Agents are being used.

Mozilla / 5.0 (Windows NT 6.1; Win64; x64; rv: 71.0) Gecko / 20100101 Firefox / 71.0 [HOSTNAME])

After decrypting all of the RC4 encrypted data, next process accessing decrypting URL and decrypt the new C&C server IP address from HTML is being downloaded.

Downloaded HTML file. [ Source : JP NTT Security ]

After decrypting IP address, ClientX.dll send infected terminal information and information necessary to process commands for control server (C&C).

Call Graph & Pseudocode of C2_server_ops function.

The URL is to be sent in the following format & the path of part consists of information on infected terminal and important information for communication encryption for command processing.

Putting all the entities in the particular ordering form , string can be easily decrypted as follows. [ Source: JP NTT Security ] : URL for sending info. on infected terminals & info. required for command execution.

At the end of the path part of URL, is encrypted with the AES-256 encryption and base encoded with base64 which are: “hostname command execution result” , “GUID formed from “CoCreateGuid” which is done in the “StartAddress” function.

Call Graph & Pseudocode of StartAddress function.

“return value of GetTickCount” in function”call_AES_256_encrypt” which is a also called in the function “C2_server_ops” that executes from the .rdata section, in which data is being send and received from C2 server.

Call Graph & Pseudocode of call_AES_256_encrypt() function.

In this function call to “AES_256_Encrypt” is being made which handles the encrypting execution commands that are carried during the time of communication with C2 server.

Call Graph & Pseudocode of AES_256_Encrypt function.[ Source: JP NTT Security ] : Data structure of encrypted string contained in URL path.

Based on data as input received from C2 server ClientX.dll executes command.

[ Source : JP NTT Security ] : List of commands can executed.

Communication made to execute commands based on C&C server are being encrypted with AES-256 algorithm. ClientX decrypts the data using the following function “AES_256_Decrypt”.

Call Graph & Pseudocode of AES_256_Decrypt function.[ Source : JP NTT Security ] : Data format received when executing a command.



On execution of this file, it writes CAB file %USERPROFILE%\ test \,

Pseudocode & Call Graph of subroutine “sub_4020F0”.

then expand as “C:\windows\apppatch\netapi32.dll” when it’s running with admin privileges otherwise it expands as tmp in % TEMP% directory \\ WMedia \ [GetTickCount () & this DLL internally called as “Smanager_ssl.dll” that why it’s called Smanager.

Pseudocode & Call Graph of subroutine “sub_402C10”.

Only the string “f4f5276c00001ff5” for encryption key is overwritten with the same value. Config data is being overwritten with dummy data.

:- -> vgca.homeunix [.] org: 443

:- (null) -> office365.blogdns [.] com: 443

:- (null) -> 10 [.] 0.14.196: 53

:- f4f5276c00001ff5 -> f4f5276c00001ff5

Config data is being stored at “0041D608” location in .data section.

And if it is running with admin privileges , it writes registers the key “ HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows NT \ CurrentVersion \ Svchost “ for registering as DLL as service as showcases below image of call graph and pseudocode of subroutine “sub_4026C0” & executes ServiceMain & if it is not running as admin privileges , it runs rundll32.exe in WinExec and runs “Entery” Dll’s export function.


As like VVSup.exe, SACEventLog.exe has a sample similar to Tmanger‘s setup. It has same implementation as VVSup.exe, only the config data which data can be decoded using hexdump (HexView) of IDA is being different which is located at the second half of address “0041D600” with hex values starting with “6F 66” which is highlighted in below image in blue.

Config data written in SACEventLog.exe is as following:-> office365.blogdns [.] com: 443

(null)-> office365.blogdns [.] com: 80

(null)-> 154 [.] 202.56.188: 80

f4f5276c00001ff5-> f4f5276c00001ff5

Hex View of hexdump values decoded in ASCII in SACEventLog.exe.

Smanager_ssl.dll can be dumped using CAPE Sandbox process dump feature. It’s a sample that is being expanded and executed in VVSup.exe and SACEventLog.exe. This sample is being similar to Tmanger’s MlloadDll. When Smanager_ssl.dll runs , it connects with the C&C server using Microsoft Security Service Provider Interface for authentication and encryption.

View of x32-dbg when Smanager_ssl.dll communicates with C&C server.

& then as connection is established with C2 server, it executes commands according to the data received from C2 server. Command is being used for sending terminal information of infected client ( victim system) to C2 server & it also does download & execute PE file. Command is being used for sending terminal information of infected client ( victim system) to C2 server & it also does download & execute PE file.

View of synced pseudocode & hexview of subroutine “sub_737D4B10” that takes cares of credentials between Client and Server.

Information collected by C2 server from client ( victim system) is as follows that can be observed in the subroutine “sub_737D45D0”:-

  • hostname
  • Computer name
  • IP address
  • OS version
  • Language information
  • username
  • Default browser
  • Existence of administrator authority
Call graph & Pseudocode of subroutine sub_737D45D0.

It was not observed by Hiroki Hada team that after establishing connection with the C2 server it downloads any kind of executable file whereas it can seen that in the pseudocode of subroutine “sub_737D6240” as it runs a process of checking MZ header ( 0x5A4D ) & PE header ( 0x4550 ) & process of calling the function of the executable file.

Call Graph & Pseudocode of subroutine “ sub_737D6240”.

Where in the subroutine “sub_737D6FC0” it is been confirmed that it uses a command for getting executable from C2 server & execute it as implemented in the subroutine “sub_737D6380” which is reversed as “get_function_addr”.

Reversed pseudocode of “ sub_737D6FC0” as get_function_addr”. Process of calling a function called GetPluginObject () from an executable file [Source: Japan NTT Security].

From the observations it can be concluded that “Smanager_ssl.dll” shares the similarity with the MlloadDll & executable plugin obtained from C&C server shares similarity with the Tmanger Client which has RAT ( Remote Access Tool) kind of functionality.

From the research blog of Hiroki Hada team Smanagerx64_release_tcp.dll is another file having similar features as like Smanager_ssl.dll. Only the config data differs as follows :-

  • coms[.]documentmeda [.] com: 443
  • f4f5276c00001ff5
Keep it low, your cover is blown.












Note : For rest of the IOCs refer “Hiroki Hada” blogs on NTT Security Blogs. Link is the references.


NTT Security Blogs:-

Others:- .


Activities carried out by Chinese TA428 APT group during this operation is being overlaps with activites of Maudi Surveillance Operation by China carried against human rights groups in China who fights for the Uyghurs ethnic groups, other than that these malware like Poison Ivy are also used against Hong Kong student protest groups protesting for democracy in Hong Kong in past few years. Even after warning issued by F.B.I ( Federal Bureau of Investigation ) to stop Chinese Government for it’s shady notorious activities against Uyghurs ethnic minorities as Chinese state actors groups continues their notorious activities. It’s called & it’s like “ I better suicide and become ghost to see him loose his powers of nothingness.”

Thank you for reading. Giving your precious time in reading my research blog that i was working on for a while.

Article Link: Internals of TA428 Operation LagTime IT | by Honey | Jan, 2022 | Medium