{
	"id": "8df9d2be-bbf4-4ef7-aa6a-91d24ac2aa0c",
	"created_at": "2026-04-06T00:14:08.257591Z",
	"updated_at": "2026-04-10T03:33:56.188752Z",
	"deleted_at": null,
	"sha1_hash": "7bbb84f357561c7812b078f90e0f1db20476f4c5",
	"title": "Threat Spotlight: Group 72, Opening the ZxShell",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 917875,
	"plain_text": "Threat Spotlight: Group 72, Opening the ZxShell\r\nBy Talos Group,\r\nPublished: 2014-10-28 · Archived: 2026-04-05 12:43:13 UTC\r\nThis post was authored by Andrea Allievi, Douglas Goddard, Shaun Hurley, and Alain Zidouemba.\r\nRecently, there was a blog post on the takedown of a botnet used by threat actor group known as Group 72 and\r\ntheir involvement in Operation SMN.  This group is sophisticated, well funded, and exclusively targets high\r\nprofile organizations with high value intellectual property in the manufacturing, industrial, aerospace, defense, and\r\nmedia sector. The primary attack vectors are watering-hole, spear phishing, and other web-based attacks.\r\nFrequently, a remote administration tool (RAT) is used to maintain persistence within a victim’s organization.\r\nThese tools are used to further compromise the organization by attacking other hosts inside the targets network.\r\nZxShell (aka Sensocode) is a Remote Administration Tool (RAT) used by Group 72 to conduct cyber-espionage\r\noperations. Once the RAT is installed on the host it will be used to administer the client, exfiltrate data, or leverage\r\nthe client as a pivot to attack an organization’s internal infrastructure.  Here is a short list of the types of tools\r\nincluded with ZxShell:\r\nKeylogger (used to capture passwords and other interesting data)\r\nCommand line shell for remote administration\r\nRemote desktop\r\nVarious network attack tools used to fingerprint and compromise other hosts on the network\r\nLocal user account creation tools\r\nFor a complete list of tools please see the MainConnectionIo section.\r\nThe following paper is a technical analysis on the functionality of ZxShell. The analysts involved were able to\r\nidentify command and control (C2) servers, dropper and installation methods, means of persistence, and identify\r\nthe attack tools that are core to the RAT’s purpose. In addition, the researchers used their analysis to provide\r\ndetection coverage for Snort, Fireamp, and ClamAV.\r\nTable of Contents\r\n1. Background\r\n2. Distribution and Delivery\r\n3. Analysis of the main ZxShell module\r\nDllMain\r\nInstall\r\nServiceMain\r\nShellMain\r\nShellMainThread\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 1 of 20\n\nGetIpListAndConnect\r\nMainConnectionIo\r\nUninstall\r\nZxFunction001\r\nZxFunction002\r\n4. Command and Control server\r\n5. Malware Package\r\n6. Version Information\r\n7. Extracted URL Analysis\r\n8. Conclusion\r\n9. Protecting Users From These Threats\r\n10. Appendix A: Snort rules\r\n11. Appendix B: ClamAV signatures\r\n12. Appendix C: List of Memory Offsets for Some ZxShell Functions\r\n13. Appendix D: Other Collateral\r\nBackground\r\nZxShell has been around since 2004. There are a lot of versions available in the underground market. We have\r\nanalyzed the most common version of ZxShell, version 3.10. There are newer versions, up to version 3.39 as of\r\nOctober 2014.\r\nDistribution and Delivery\r\nAn individual who goes by the name LZX in some online forums is believed to be the original author of ZxShell.\r\nSince ZxShell has been around since at least 2004, numerous people have purchased or obtained the tools\r\nnecessary to set up ZxShell command and control servers (C\u0026C) and generate the malware that is placed on the\r\nvictim’s network. ZxShell has been observed to be distributed through phishing attacks, dropped by exploits that\r\nleverage vulnerabilities such as CVE-2011-2462, CVE-2013-3163, and CVE-2014-0322.\r\nAnalysis of the Main ZxShell Module\r\nTo illustrate the functionality of main ZxShell module, Let’s take a look at the following sample:\r\nMD5: e3878d541d17b156b7ca447eeb49d96a\r\nSHA256: 1eda7e556181e46ba6e36f1a6bfe18ff5566f9d5e51c53b41d08f9459342e26c\r\nIt exports the following functions, which are examined in greater detail below:\r\nDllMain\r\nInstall\r\nUnInstall\r\nServiceMain\r\nShellMain\r\nShellMainThread\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 2 of 20\n\nzxFunction001\r\nzxFunction002\r\nDllMain\r\nDllMain performs the initialization of ZxShell. It allocates a buffer of 0x2800 bytes and copies the code for the\r\nZxGetLibAndProcAddr function. To copy memory, the memcpy function is invoked. It is not directly used from\r\nmsvcrt.dll but is instead copied to another memory chunk before being called. Finally, the trojan Import Address\r\nTable (IAT) is resolved and the file path of the process that hosts the dll is resolved and saved in a global variable.\r\nInstall\r\nZxShell.dll is injected in a shared SVCHOST process. The Svchost group registry key\r\nHKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost is opened and the netsvc group value data\r\nis queried to generate a name for the service.\r\nBefore the malware can be installed a unique name must to be generated for the service. The malware\r\naccomplishes this through querying the netsvc group value data located in the svchost group registry key which is\r\nHKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost.\r\nAt startup, Svchost.exe checks the services part of the registry and constructs a list of services to load. Each\r\nSvchost session can contain multiple shared services that are organized in groups. Therefore, separate services can\r\nrun, depending on how and where Svchost.exe is started.\r\nImage 1. Svchost Groups registry key\r\nSvchost.exe groups are identified in the above registry key. Each value under this key represents a separate\r\nSvchost group and appears as a separate instance when you are viewing active processes. Each value is a\r\nREG_MULTI_SZ value and contains the services that run under that Svchost group. Each Svchost group can\r\ncontain one or more service names that are extracted from the following registry key, whose Parameters key\r\ncontains a ServiceDLL value:\r\nHKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Services\\Service\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 3 of 20\n\nOn a Windows machine, the netsvc group contains names of both existing and non-existing services. ZxShell\r\nexploits this fact by cycling between each of the names, verifying the existence of the real service. The service’s\r\nexistence is verified with the ServiceExists function, which attempts to open the relative registry sub-key in\r\nHKLM\\SYSTEM\\CurrentControlSet\\Services. The first service name that is not installed on the system becomes\r\nthe ZxShell service name.\r\nA new service is then created using the service parser function ProcessScCommand. ZxShell implemented its own\r\nversion of the Windows SC command. There are minor differences between the ZxShell implementation of this\r\ncommand and the original Windows one, but they are irrelevant for the purpose of the analysis The command used\r\nto install the service is:\r\nsc create \u003cservice name\u003e \u003cservice name\u003e “%SystemRoot%\\System32\\svchost.exe -k netsvcs”\r\nwhere \u003cservice name\u003e is the chosen infected service name.\r\nImage 2. “SC” command used to create the target service,\r\nand parsed by “ProcessScCommand” routine\r\nThe installed service registry key is opened and the 2 values under its Parameter subkey are created. These 2\r\nvalues, ServiceDll and ServiceDllUnloadOnStop are needed for services that run in a shared process.\r\nBefore the service is started ChangeServiceConfig is called to modify the service type to shared and interactive. If\r\nthe service fails to start then a random service name formatted as netsvc_xxxxxxxx, where xxxxxxxx represent an\r\n8-digit random hex value, is added to the netsvc group and the entire function is repeated.\r\nServiceMain\r\nThis function is the entry point of the service. It registers the service using the RegisterServiceCtrlHandler\r\nWindows API function. The ZxShell service handler routine is only a stub: it responds to each service request\r\ncode, doing nothing, and finally exits. It sets the service status to RUNNING and finally calls the ShellMain\r\nfunction of ZxShell.\r\nShellMain\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 4 of 20\n\nThe ShellMain function is a stub that relocates the DLL to another buffer and spawns a thread that starts from\r\nShellMainThreadInt at offset +0xC0CD. The ShellMainThreadInt function gets the HeapDestroy Windows API\r\naddress and replaces the first 3 bytes with the RET 4 opcode. Subsequently, it calls the FreeLibrary function to\r\nfree its own DLL buffer located at its original address. Because of this, the allocated heaps will not be freed. It re-copies the DLL from the new buffer to the original one using the memcpy function. Finally, it spawns the main\r\nthread that starts at the original location of ShellMainThread procedure, and terminates. At this point, the ZxShell\r\nlibrary is no longer linked in the module list of the host process. This is important because if any system tool tries\r\nto open the host process it will never display the ZxShell DLL.\r\nShellMainThread\r\nThis thread implements the main code, responsible for the entire botnet DLL.\r\nFirst, it checks if the DLL is executed as a service. If so, it spawns the service watchdog thread. The watchdog\r\nthread checks the registry path of the ZxShell service every 2 seconds, to verify that it hasn’t been modified. If a\r\nuser or an application modifies the ZxShell service registry key, the code restores the original infected service key\r\nand values.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 5 of 20\n\nImage 3. The watchdog thread of ZxShell service\r\nThe buffer containing the ZxShell Dll in the new location is freed using the VirtualFree API function. A handle to\r\nthe DLL file is taken in order to make its deletion more difficult. The ZxShell mutex is created named\r\n@_ZXSHELL_@.\r\nZxShell plugins are parsed and loaded with the AnalyseAndLoadPlugins function. The plugin registry key\r\nHKLM\\SYSTEM\\CurrentControlSet\\Control\\zxplug is opened and each value is queried. The registry value\r\ncontains the plugin file name. The target file is loaded using the LoadLibrary API function, and the address of the\r\nexported function zxMain is obtained with GetProcAddress.\r\nIf the target filename is incorrect or invalid the plugin file is deleted and the registry value is erased. That is\r\nperformed by the function DeleteAndLogPlugin. Otherwise, the plugin is added to an internal list. Here is the data\r\nstructure used to keep track of the plugins:\r\ntypedef struct _ZX_PLUGINS_STRUCT {\r\n LPSTR lpStrRegKey; // + 0x00 - ZxShell Plugins registry key string\r\n// (like 'SYSTEM\\CurrentControlSet\\Control\\zxplug')\r\n DWORD dwUnknown2; // + 0x04 - Unknown DWORD value\r\n LPVOID lp138hBuff; // + 0x08 - Plugins list\r\n DWORD dwZero; // + 0x0C - Always zero\r\n HANDLE hReg; // + 0x10 - Handle to plugin registry key\r\n} ZX_PLUGINS_STRUCT, *PZX_PLUGINS_STRUCT;\r\nThe thread KeyloggerThread is spawned and is responsible for doing keylogging on the target workstation. We\r\nwill take a look at the keylogger later on. Finally the main network communication function GetIpListAndConnect\r\nis called.\r\nGetIpListAndConnect\r\nThis function is at the core of the RAT’s network communication. It starts by initializing a random number\r\ngenerator and reading 100 bytes inside the ZxShell Dll at a hardcoded location. These bytes are XOR encrypted\r\nwith the byte-key 0x85 and contains a list of remote hosts where to connect. The data is decrypted, the remote host\r\nlist is parsed and verified using the BuildTargetIpListStruct function. There are 3 types of lists recognized by\r\nZxShell: plain ip addresses, HTTP and FTP addresses.\r\nIf the list does not contain any item, or if the verification has failed, the ZxShell sample tries to connect to a\r\nhardcoded host  with the goal of retrieving a new updated list.\r\nOtherwise, ZxShell tries to connect to the first item of the list. If ZxShell successfully connects to the remote host,\r\nthe function DoHandshake is called. This function implements the initial handshake which consists of exchanging\r\n16 bytes, 0x00001985 and 0x00000425,  with the server. The function GetLocalPcDescrStr is used to compose a\r\nlarge string that contains system information of the target workstation. That information is the following:\r\nlocal hostname\r\norganization\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 6 of 20\n\nowner\r\noperating system details\r\nCPU speed\r\ntotal physical memory\r\nThe string is sent to the remote host and the response is checked to see if the first byte of the response is 0xF4, an\r\narbitrary byte. If it is, the botnet connection I/O procedure is called through the MainConnectionIo function.\r\nImage 4. The GetLocalPcDescrStr and DoHandshake functions called before\r\nstarting the command processing\r\nOtherwise, the ZxShell code closes the socket used and sleeps for 30 seconds. It will then retry the connection\r\nwith the next remote host, if there is one.\r\nIt is noteworthy that this function includes the code to set the ZxShell node as a server: if one of the hardcoded\r\nboolean value is set to 1, a listening socket is created. The code waits for an incoming connection. When the\r\nconnection is established a new thread is spawned that starts with the MainConnectionIo function.\r\nMainConnectionIo\r\nThe MainConnectionIo function checks if the Windows Firewall is enabled, sets the Tcp Keep Alive value and\r\nNon-blocking mode connection options and receives data from the remote host through the ReceiveCommandData\r\nfunction. If the communication fails, ZxShell disables the firewall by modifying the registry key:\r\nHKLM\\SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\StandardProfile\r\nThen the connection is retried. The received command is then processed by the ZxShell function with the\r\nProcessCommand function.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 7 of 20\n\nThe command processing function starts by substituting the main module name and path in the hosting process\r\nPEB, with the one of the default internet browser. The path of the main browser of the workstation is obtained by\r\nreading the registry value:\r\nHKLM\\SOFTWARE\\Classes\\HTTP\\shell\\open\\command\r\nImage 5. Our test workstation use Windows Internet Explorer as default browser\r\nThis trick renders identification by firewall more cumbersome. A host firewall  will recognize the outgoing\r\nconnection as originated by the browser instead of the ZxShell service host process. The browser process always\r\nperforms outgoing connections and the firewall shouldn’t block them.\r\nThe command processing is straightforward. Here is the list of common commands:\r\nCOMMAND MEANING\r\nHelp / ? Get help\r\nExit / Quit Exit and shut down the botnet client\r\nSysInfo Get target System information\r\nSYNFlood Perform a SYN attack on a host\r\nPs Process service Unix command implementation\r\nCleanEvent Clear System Event log\r\nFindPass Find login account password\r\nFileTime Get time information about a file\r\nFindDialPass List all the dial-up accounts and passwords\r\nUser Account Management System\r\nTransFile Transfer file in or from remote host\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 8 of 20\n\nExecute Run a program in the remote host\r\nSC Service control command, implemented as the Windows one\r\nCA Clone user account\r\nRunAs Create new process as another User or Process context.\r\nTermSvc Terminal service configuration (working on Win Xp/2003)\r\nGetCMD Remote Shell\r\nShutdown Logout, shutdown or restart the target system\r\nZXARPS Spoofing, redirection, packet capture\r\nZXNC Run ZXNC v1.1 – a simple telnet client\r\nZXHttpProxy Run a HTTP proxy server on the workstation\r\nZXSockProxy Run a Sock 4 \u0026 5 Proxy server\r\nZXHttpServer Run a custom HTTP server\r\nPortScan Run TCP Port MultiScanner v1.0\r\nKeyLog\r\nCapture or record the remote computer’s keystrokes. The implementation is a userland\r\nkeylogger that polls the keymap with each keystroke.\r\nLoadDll Load a DLL into the specified process\r\nEnd Terminate ZxShell DLL\r\nUninstall Uninstall and terminate ZxShell bot DLL\r\nShareShell Share a shell to other\r\nCloseFW Switch off Windows Firewall\r\nFileMG File Manager\r\nwinvnc Remote Desktop\r\nrPortMap Port Forwarding\r\ncapsrv Video Device Spying\r\nzxplug Add and load a ZxShell custom plugin\r\nThis set of functionality allows the operator complete control of a system. Being able to transfer and execute files\r\non the infected system means the attacker can run any code they please. Further, the keylogging and remote\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 9 of 20\n\ndesktop functionality allows the operator to spy on the infected machine, observing all keystrokes and viewing all\r\nuser actions.\r\nUninstall\r\nUnloads ZxShell and deletes all of the active components. This simply deletes the ZxShell service key from the\r\nWindows registry (using SHDeleteKey Api) and all of the subkeys. Finally, it marks ZxShell main Dll for deletion\r\nwith the MoveFileEx Windows API.\r\nZxFunction001\r\nThis function is the supporting functionality for WinVNC. To allow the VNC session to connect, the current\r\nnetwork socket WSAProtcol_Info structure is written to a named pipe prior to calling zxFunction001. Once the\r\nnamed pipe has been created, CreateProcessAsUserA is called with the following as the CommandLine parameter\r\n:\r\n\u003csystemroot\u003e\\\\rundll32.exe \u003czxshell dll name\u003e,zxFunction001 \u003cname of NamedPipe\u003e\r\nzxFunction001 modifies the current process memory, uses data contained in the named pipe to create a socket, and\r\nthen executes the code that sends the remote desktop session to the server controller.\r\nZxFunction002\r\nThis function will either bind the calling process to a port or has the calling process connect to a remote host. The\r\nfunction is called in the following manner:\r\n\u003csystemroot\u003e\\\\rundll32.exe \u003czxshell dll name\u003e,zxFunction002 \u003cname of NamedPipe\u003e\r\nThe functionality (connect or bind) depends on the data contained within the named pipe. Unlike zxFunction001,\r\nthis is not used by  any of the RAT commands in the zxshell.dll.\r\nKernel Device Driver LoveUSD\r\nApart from user-mode ZxShell droppers mentioned earlier, there is a file (SHA256:\r\n1e200d0d3de360d9c32e30d4c98f07e100f6260a86a817943a8fb06995c15335) that installs a kernel device driver\r\ncalled loveusd.sys. The architecture of this dropper is different from the others: it starts extracting the main driver\r\nfrom itself. It adds the SeLoadDriver privilege to its access token and proceeds to install the driver as a fake disk\r\nfilter driver. ZxShell opens the registry key that describes the disk class drivers:\r\nSYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E967-E325-11CE-BFC1-08002BE10318}\r\nIt then adds the “Loveusd.sys” extracted driver name to the upper filter list. In our analysed sample the\r\n“Loveusd.sys” driver is installed with the name “USBHPMS”. Finally the driver is started using the\r\nZwLoadDriver native API.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 10 of 20\n\nThe ZxShell driver starts by acquiring some kernel information and then hooking “ObReferenceObjectByHandle”\r\nAPI. Finally it spawns 2 system threads.\r\nThe first thread is the “communication” thread. ZxShell employs a strange method for communication: it hooks\r\nthe NtWriteFile API and recognizes 5 different special handle values as commands:\r\n0x111111111 – Hide “Loveusd” driver from the system kernel driver list\r\n0x22222222 – Securely delete an in-use or no-access target file-name\r\n0x44444444 – Unhook the ZwWriteFile API and hook KiFastCallEntry\r\n0x55555555 – Remove the ZxShell Image Load Notify routine\r\n0x88888888 – Set a special value called “type” in Windows registry key\r\nHKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\DriverMain\r\nThe second Loveusd system thread does a lot of things. Its principal duties are to create the ZxShell main DLL in\r\n“c:\\Windows\\System32\\commhlp32.dll” and to install the Kernel “Load Image Notify routine”. The code then\r\ntries to kill each process and service that belongs to the following list of AV products:\r\nSymantec Firewall\r\nNorton\r\nESET\r\nMcAfee\r\nAvast\r\nAvira\r\nSophos\r\nMalwarebytes\r\nNext, the ZxShell Load-Image Notify function prevents the AV processes from restarting.\r\nThe installation procedure continues in the user-mode dropper. The ZxShell service is installed as usual, and the\r\nin-execution dropper is deleted permanently using the special handle value 0x22222222 for the WriteFile API call.\r\nThis handle value is invalid: all the windows kernel handle values are by design a multiple of 4. The ZxShell hook\r\ncode knows that and intercept it.\r\nObReferenceObjectByHandle is a Kernel routine designed to validate a target object and return the pointer to its\r\nobject body (and even its handle information), starting from the object handle (even the user-mode one). The hook\r\ninstalled by ZxShell implements one of its filtering routine. It filters each attempt to open the ZxShell protected\r\ndriver or the main DLL, returning a reference to the “netstat.exe” file. The protection is enabled to all processes\r\nexcept for ones in the following list: Svchost.exe, Lsass.exe, Winlogon.exe, Services.exe, Csrss.exe, ctfmon.exe,\r\nRundll32.exe, mpnotify.exe, update.exe.\r\nIf the type of the object that the system is trying to validate is a process, the hook code rewrites again the\r\nconfiguration data of the ZxShell service in the windows registry.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 11 of 20\n\nImage 6. Our test Windows XP workstation trying to open the sys file of ZxShell LOVEUSD driver\r\nThe last type of Kernel modification that ZxShell rootkit performs is the system call dispatcher (KiFastCallEntry)\r\nhook. In this manner, ZxShell is able to completely hide itself, intercepting the following Kernel API calls:\r\nZwAllocateVirtualMemory, ZwOpenEvent, ZwQueryDirectoryFile, ZwWriteFile, ZwEnumerateKey, and\r\nZwDeviceIoControlFile.\r\nCommand and Control Server\r\nSample (SHA256: 1eda7e556181e46ba6e36f1a6bfe18ff5566f9d5e51c53b41d08f9459342e26c) is configured to\r\nact as a server. The symbol “g_bCreateListenSck” is set to 1. This means that, as seen above, the ZxShell Dll is\r\nstarted in listening mode. It connects to the first remote C\u0026C that tries to contact it and succeeds in the handshake.\r\nThe encrypted IP address is “127.0.0.2” (used as loopback) and no connection is made on that IP address (due to\r\nthe listening variable set to 1).\r\nMalware Package\r\nWe used the ZxShell package for version 3.10 (SHA256:\r\n1622460afbc8a255141256cb77af61c670ec21291df8fe0989c37852b59422b4).The convenient thing about this is\r\nthat the CNC panel worked with any version, 3.10 and above. The buttons are all in Chinese, with the help of\r\nGoogle Translate and keen detective skills (read: button clicking), we’ve deciphered the functionality.\r\nWhen you start the controller, you need to set the port you want to listen on and if you’ve set a password, add it\r\nhere.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 12 of 20\n\nOnce an\r\ninfected machine connects, you see its information displayed in a selection box at the top. There are some built in\r\nfunctions on the side for the more common features. These include remote desktop, webcam spying, remote shell,\r\nand file management. You can also select a host and type help for a full list of commands.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 13 of 20\n\nI have the same\r\nmachine infected with two different version of ZxShell. Sending the help command for each, you can see the extra\r\nfeatures added between version 3.1 and 3.2.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 14 of 20\n\nKeylogging, ZXARPS (IP and URL spoofing), and\r\nSYNFlood are some of the interesting features added to version 3.2.\r\nVersion Information\r\nWe wrote a script to extract version info from the binaries we have.\r\n3.100 : 914\r\n3.200 : 152\r\n3.210 : 118\r\n3.220 : 14\r\n3.390 : 3\r\nIn versions 3.1 – 3.21, the configuration info is xor encoded with 0x85. This configuration info can be changed\r\nwith a tool included in the ZxShell package.\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 15 of 20\n\nIn versions 3.22 and 3.39 the routine changes. The new\r\nxor encoding byte is 0x5B. The data is stored in the last 0x100 bytes of the file. The first 8 bytes of data are static.\r\nThen there is the dll install name, the domain, and the port.\r\nKnowing the obfuscation routines for this data we wrote a script to extract the URLs / IPs and ports stored.\r\nThe most common ports used are, 80, 1985, 1986, and 443. 1985 is the default port for the malware, 1986 is the\r\nlazy variation of that port. Port 80 and 443 are the default ports for HTTP and HTTPS traffic. The next most\r\ncommon is port 53. This is used in some of the newer 3.22 and 3.39 samples. After that, the count for each port\r\nstarts declining sharply. The choices are interesting though, many correspond to what looks like the birth year of\r\nthe controller (ie. years in the late 1980s and early 1990s), and others seem to match what year the malware was\r\nlaunched in (ie. in the 2000s, relatively close to the current year).\r\nSince this malware dates back to around 2004, there are many samples containing CNC URLs from the 3322.org\r\npage. This page used to offer no-ip type hosting and was widely used by malware authors. So much so that\r\nMicrosoft did a takedown in 2012. A similar service, vicp.net, is also seen in many of the domains.\r\nIn the malware, if a domain is configured, it will retrieve domain.tld/myip.txt. This file contains a list of IP\r\naddresses for the infected machine to connect back to. Otherwise, if an IP address is configured, it will connect\r\ndirectly to that IP address.\r\nCloning the ZxShell Server\r\nWe have written a simple C++ ZxShell Server that implements the communication and the handshake for the\r\nversion 3.10 and 3.20 of the ZxShell DLL. The implementation is quite simple: After the handshake, 2 threads that\r\ndeal with data transfer are spawned. Here we have some screenshots that show the Server and the ZxShell\r\nKeylogger in action:\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 16 of 20\n\nOur server has accepted a connection from a remote host\r\nThe ZxShell keylogger has captured 2 user passwords\r\n(gmail.com and amazon.com)\r\nThe last image shows a very interesting feature of the ZxShell keylogger: once installed and activated, the\r\nkeylogger is able to catch each password that the user inserts in the login box of each website (like Google,\r\nAmazon and so on…). This makes the keylogger a perfect weapons for the attackers. They will be able to steal\r\nand resell in the underground market the sensitive data of each victim.\r\nConclusion\r\nAdvanced persistent threats will remain a problem for companies and organizations of all sizes, especially those\r\nwith high financial or intellectual property value.  Group 72’s involvement in Operation SMN is another example\r\nof what sort of damage that can be done if organizations are not diligent in their efforts to secure their networks. \r\nZxShell is one sample amongst several tools that Group 72 used within their campaign.\r\nZxShell is a sophisticated tool employed by Group 72 that contains all kinds of functionality.  Its detection and\r\nremoval can be difficult due to the various techniques used to conceal its presence, such as disabling the host anti-virus, masking its installation on a system with a valid service name, and by masking outbound traffic as\r\noriginating from a web browser.  While other techniques are also utilized to conceal and inhibit its removal,\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 17 of 20\n\nZxShell’s primary functionality is to act as a Remote Administration Tool (RAT), allowing the threat actor to have\r\ncontinuous backdoor access on to the compromised machine.\r\nAs our analysis demonstrates, ZxShell is an effective tool that can be ultimately used to steal user credentials and\r\nother highly valuable information. The threat posed by ZxShell to organizations is one that cannot be ignored. \r\nOrganizations with high financial or intellectual property value should take the time to ensure their security\r\nrequirements are met and that employee’s are educated about the security threats their organizations face.\r\nFor additional information, please see our blog post.\r\nProtecting Users from These Threats\r\nAdvanced Malware Protection (AMP) is ideally suited to detect the sophisticated malware used by this threat\r\nactor.\r\nCWS or WSA web scanning prevents access to malicious websites, including watering hole attacks, and detects\r\nmalware used in these attacks.\r\nThe Network Security protection of IPS and NGFW have up-to-date signatures to detect malicious network\r\nactivity by threat actors.\r\nESA can block spear phishing emails sent by threat actors as part of their campaign.\r\nAppendix A: Snort Rules\r\nInitial connection from the infected computer’s perspective – after it connects to the controller –\r\nRECV: 85190000250400000000404000000000\r\nSEND: 86190000040100006666464000000000\r\nRECV: 4edf9340780100000000000000000000\r\nSEND: 00000000000000000000000000000000\r\nThe rules are on the first 8 bytes of the first two packets. They are hard coded in the binaries. The rest of the bytes\r\nare variable (for example, 66664640 is a floating point version number of ZxShell).\r\nSnort rules:\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 18 of 20\n\nsid:32180\r\nsid:32181\r\nThese rules have been released in our community ruleset and can be downloaded and used directly, or via\r\npulledpork from Snort.org\r\nAppendix B: ClamAV Signatures\r\nWin.Trojan.ZxShell-11\r\nWin.Trojan.ZxShell-12\r\nWin.Trojan.ZxShell-13\r\nWin.Trojan.ZxShell-14\r\nWin.Trojan.ZxShell-15\r\nWin.Trojan.ZxShell-16\r\nWin.Trojan.ZxShell-17\r\nWin.Trojan.ZxShell-18\r\nWin.Trojan.ZxShell-19\r\nWin.Trojan.ZxShell-20\r\nWin.Trojan.ZxShell-21\r\nWin.Trojan.ZxShell-22\r\nWin.Trojan.ZxShell-23\r\nWin.Trojan.ZxShell-24\r\nWin.Trojan.ZxShell-25\r\nWin.Trojan.ZxShell-26\r\nThese signatures are available within the ClamAV database.  Please run freshclam to ensure you stay updated with\r\nthe latest coverage.\r\nAppendix C: List of Memory Offsets for Some ZxShell Functions\r\nHere’s a list for some ZxShell functions for sample SHA256:\r\n1eda7e556181e46ba6e36f1a6bfe18ff5566f9d5e51c53b41d08f9459342e26c:\r\nFUNCTION NAME BRIEF DESCRIPTION OFFSET\r\nZxGetLibAndProcAddr ZxShell GetProcAddress implementation 0x12CDA\r\nCopyMemoryFromNewMsvcrt ZxShell memory copy routine 0x12C4C\r\nServiceExists Get if a service is installed in the system or not 0x0A7C7\r\nProcessScCommand ZxShell “SC” command implementation 0x0E3EF\r\nAnalyseAndLoadPlugins Parse the installed plugin list and load each one of them 0x0127B7\r\nDeleteAndLogPlugin Delete a corrupted plugin and log the problem 0x012597\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 19 of 20\n\nKeyloggerThread ZxShell keylogger implementation 0x0D591\r\nGetIpListAndConnect Analyse the IP list inside the ZxShell PE and tries to connect 0x011496\r\nBuildTargetIpListStruct Build remote server Ip list structure 0x11419\r\nDoHandshake Perform initial connection handshake 0xB8E8\r\nGetLocalPcDescrStr Build a string containing the target workstation data 0x0B627\r\nMainConnectionIo ZxShell main connection I/O routine 0x1126C\r\nReceiveCommandData Receive each byte from the socket until a newline char 0x016DF\r\nProcessCommand Main ZxShell command processing routine 0x10C2B\r\nAppendix D: Other Collateral\r\nHere is a non-exhaustive list of ZxShell samples that were analyzed for this report.\r\nHere is a list of Domains organized by port.\r\nSource: https://blogs.cisco.com/security/talos/opening-zxshell\r\nhttps://blogs.cisco.com/security/talos/opening-zxshell\r\nPage 20 of 20",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"ETDA",
		"MITRE",
		"Malpedia"
	],
	"references": [
		"https://blogs.cisco.com/security/talos/opening-zxshell"
	],
	"report_names": [
		"opening-zxshell"
	],
	"threat_actors": [
		{
			"id": "cea5ceec-0f14-4e34-bd0e-4074bc1a707d",
			"created_at": "2022-10-25T15:50:23.629983Z",
			"updated_at": "2026-04-10T02:00:05.362084Z",
			"deleted_at": null,
			"main_name": "Axiom",
			"aliases": [
				"Group 72"
			],
			"source_name": "MITRE:Axiom",
			"tools": [
				"ZxShell",
				"gh0st RAT",
				"Zox",
				"PlugX",
				"Hikit",
				"PoisonIvy",
				"Derusbi",
				"Hydraq"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "4b076dcb-516e-42fb-9c8f-f153902cd5e9",
			"created_at": "2022-10-25T16:07:23.708745Z",
			"updated_at": "2026-04-10T02:00:04.720108Z",
			"deleted_at": null,
			"main_name": "Hidden Lynx",
			"aliases": [
				"Aurora Panda",
				"Group 8",
				"Heart Typhoon",
				"Hidden Lynx",
				"Operation SMN"
			],
			"source_name": "ETDA:Hidden Lynx",
			"tools": [
				"AGENT.ABQMR",
				"AGENT.AQUP.DROPPER",
				"AGENT.BMZA",
				"AGENT.GUNZ",
				"BlackCoffee",
				"HiKit",
				"MCRAT.A",
				"Mdmbot.E",
				"Moudoor",
				"Naid",
				"PNGRAT",
				"Trojan.Naid",
				"ZoxPNG",
				"gresim"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "a7aefdda-98f1-4790-a32d-14cc99de2d60",
			"created_at": "2023-01-06T13:46:38.281844Z",
			"updated_at": "2026-04-10T02:00:02.909711Z",
			"deleted_at": null,
			"main_name": "APT17",
			"aliases": [
				"BRONZE KEYSTONE",
				"G0025",
				"Group 72",
				"G0001",
				"HELIUM",
				"Heart Typhoon",
				"Group 8",
				"AURORA PANDA",
				"Hidden Lynx",
				"Tailgater Team"
			],
			"source_name": "MISPGALAXY:APT17",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "f9806b99-e392-46f1-9c13-885e376b239f",
			"created_at": "2023-01-06T13:46:39.431871Z",
			"updated_at": "2026-04-10T02:00:03.325163Z",
			"deleted_at": null,
			"main_name": "Watchdog",
			"aliases": [
				"Thief Libra"
			],
			"source_name": "MISPGALAXY:Watchdog",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "2a24d664-6a72-4b4c-9f54-1553b64c453c",
			"created_at": "2025-08-07T02:03:24.553048Z",
			"updated_at": "2026-04-10T02:00:03.787296Z",
			"deleted_at": null,
			"main_name": "BRONZE ATLAS",
			"aliases": [
				"APT41 ",
				"BARIUM ",
				"Blackfly ",
				"Brass Typhoon",
				"CTG-2633",
				"Earth Baku ",
				"GREF",
				"Group 72 ",
				"Red Kelpie ",
				"TA415 ",
				"TG-2633 ",
				"Wicked Panda ",
				"Winnti"
			],
			"source_name": "Secureworks:BRONZE ATLAS",
			"tools": [
				"Acehash",
				"CCleaner v5.33 backdoor",
				"ChinaChopper",
				"Cobalt Strike",
				"DUSTPAN",
				"Dicey MSDN",
				"Dodgebox",
				"ForkPlayground",
				"HUC Proxy Malware (Htran)"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "ee39ecf0-d311-49e5-b0ae-3e3d71f71def",
			"created_at": "2025-08-07T02:03:24.626625Z",
			"updated_at": "2026-04-10T02:00:03.605175Z",
			"deleted_at": null,
			"main_name": "BRONZE KEYSTONE",
			"aliases": [
				"APT17 ",
				"Aurora Panda ",
				"DeputyDog ",
				"Group 72 ",
				"Hidden Lynx ",
				"TG-8153 ",
				"Tailgater Team"
			],
			"source_name": "Secureworks:BRONZE KEYSTONE",
			"tools": [
				"9002",
				"BlackCoffee",
				"DeputyDog",
				"Derusbi",
				"Gh0stHTTPSDropper",
				"HiKit",
				"InternalCMD",
				"PlugX",
				"PoisonIvy",
				"ZxShell"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "5c74936a-79d1-41b8-81eb-01d03c90a26b",
			"created_at": "2022-10-25T16:07:23.371052Z",
			"updated_at": "2026-04-10T02:00:04.570621Z",
			"deleted_at": null,
			"main_name": "Axiom",
			"aliases": [
				"G0001",
				"Group 72",
				"Operation SMN"
			],
			"source_name": "ETDA:Axiom",
			"tools": [
				"9002 RAT",
				"Agent.dhwf",
				"AngryRebel",
				"BlackCoffee",
				"BleDoor",
				"Chymine",
				"Darkmoon",
				"DeputyDog",
				"Derusbi",
				"Destroy RAT",
				"DestroyRAT",
				"Farfli",
				"Fexel",
				"Gen:Trojan.Heur.PT",
				"Gh0st RAT",
				"Ghost RAT",
				"Gresim",
				"HOMEUNIX",
				"HiKit",
				"HidraQ",
				"Homux",
				"Hydraq",
				"Kaba",
				"Korplug",
				"McRAT",
				"MdmBot",
				"Moudour",
				"Mydoor",
				"PCRat",
				"PNGRAT",
				"PlugX",
				"Poison Ivy",
				"RbDoor",
				"RedDelta",
				"RibDoor",
				"Roarur",
				"SPIVY",
				"Sensocode",
				"Sogu",
				"TIGERPLUG",
				"TVT",
				"Thoper",
				"Winnti",
				"Xamtrav",
				"ZXShell",
				"Zox",
				"ZoxPNG",
				"ZoxRPC",
				"gresim",
				"pivy",
				"poisonivy"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434448,
	"ts_updated_at": 1775792036,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7bbb84f357561c7812b078f90e0f1db20476f4c5.pdf",
		"text": "https://archive.orkl.eu/7bbb84f357561c7812b078f90e0f1db20476f4c5.txt",
		"img": "https://archive.orkl.eu/7bbb84f357561c7812b078f90e0f1db20476f4c5.jpg"
	}
}