{
	"id": "8ad3cb4b-7890-4efa-b33d-35a6c195331e",
	"created_at": "2026-04-06T00:11:29.441802Z",
	"updated_at": "2026-04-10T03:21:29.939604Z",
	"deleted_at": null,
	"sha1_hash": "145a6c87ae2edbb5420669c2c844a54e0b877e65",
	"title": "New Threat: ZHtrap botnet implements honeypot to facilitate finding more victims",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1584095,
	"plain_text": "New Threat: ZHtrap botnet implements honeypot to facilitate\r\nfinding more victims\r\nBy Alex.Turing\r\nPublished: 2021-03-12 · Archived: 2026-04-05 22:09:17 UTC\r\nOverview\r\nIn the security community, when people talk about honeypot, by default we would assume this is one of the most\r\nused toolkits for security researchers to lure the bad guys . But recently we came across a botnet uses\r\nhoneypot to harvest other infected devices, which is quite interesting.\r\nFrom February 28, 2021, our BotMon system started to see one IP ( 107.189.30.190 ) continuously spreading a\r\nbatch of unknown ELF samples. After analysis, we confirmed that these samples belonged to a new botnet family,\r\nwe named it ZHtrap , and it has the following characters.\r\nZHtrap's propagation uses 4 Nday vulnerabilities, the main function is DDoS and scanning, while\r\nintegrating some backdoor features.\r\nZhtrap sets up honeypot on the infected device.\r\nZhtrap takes snapshots for the victim devices, and disables the running of new commands based on the\r\nsnapshot, thus achieving exclusivity over the device.\r\nFor C2 communication, ZHtrap takes a cue from the Matryosh botnet we previous reported, using Tor and\r\ncloud-based configuration.\r\nZHtrap Full Introduction\r\nZHtrap's code is based on Mirai and supports x86, ARM, MIPS and other major CPU architectures. However,\r\ncompared to Mirai, ZHtrap has changed a lot, which is reflected in the following aspects.\r\nIn terms of instructions, a checksum mechanism has been added\r\nIn terms of scanning propagation, the distinction between real devices and honeypots has been\r\nadded .\r\nIn terms of encryption algorithm, a set of multiple XOR encryption algorithm has been redesigned.\r\nIn terms of host behavior, it can turn the compromised device into a simple honeypot and implement a set\r\nof process control mechanisms\r\nIn terms of network architecture, it borrows some implementations of our previously exposed Matryosh\r\nbotnet\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 1 of 18\n\nThe basic process is shown in the following diagram.\r\nIn terms of functionality, in addition to DDoS attacks and scanning, ZHtrap also implements backdoor\r\nfunctionality, which increases the harmfulness of the family. specific functions of ZHtrap include\r\nProcess control\r\nReversing Shell\r\nDDoS attacks\r\nTelnet scanning\r\nExploit propagation\r\nTurn infected devices into honeypot\r\nDownload and execute Payload\r\nThe ZHtrap samples we have captured so far can be divided into 3 versions according to their functions: v1, v2\r\nand v3.\r\nv2 is based on v1 with the addition of vulnerability exploitation.\r\nv3 is based on v2 with the deletion of the network infrastructure.\r\nTheir relationship is shown in the figure below, and the analysis in this paper is based on the most fully functional\r\nv2 version.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 2 of 18\n\nCompared to other botnets we have analyzed before, the most interesting part of ZHtrap is its ability to turn\r\ninfected devices into honeypot. Honeypots are usually used by security researchers as a tool to capture attacks,\r\nsuch as collecting scans, exploits, and samples. But this time around, we found that ZHtrap uses a similar\r\ntechnique by integrating a scanning IP collection module, and the collected IPs are used as targets in its own\r\nscanning module, with the basic process shown below.\r\nZHtrap will listen to 23 designated ports (as shown in the above figure), and if it finds an IP connecting to these\r\nports it will record it as a scanner IP, and all the recorded IPs will be scanned in its own scanningmodule, so that\r\nthe target addresses used in the ZHtrap scanning process will have 2 sources.\r\nRandomly generated IPs.\r\nScanner IPs captured by the above module.\r\nMore details on this can be found in the sample analysis section below.\r\nSample Reverse Analysis\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 3 of 18\n\nHere we pick ZHtrap v2's X86 CPU architecture sample for analysis, with the following basic information.\r\nMD5：5370e0b9484cb25fb3d5a4b648b5c203\r\nELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped\r\nPacker：None\r\nAfter ZHtrap successfully infects the device, it creates a single instanceby binding local port, then decrypts the\r\nencrypted resource information and renames the process to /bin/ZoneSec , and then prints out the following\r\nmessage in the Console ZH infected your shit, message me on discord to compare assets ($reiko#0095),\r\nresearchers hmu twitter[.] com/ZoneHax . Next, a network request is made to get the address of the resource\r\nserver for the scanning \u0026 propagation phase. Then listen to 23 pre-de-fined ports to turn the device into a\r\n\"honeypot\", waiting for other compromised devices to hit the port.It uses 4 Nday vulnerability to achieve worm-like propagation. Fi-nally, it communicates with the TOR C2 and waits for the execution of the commands issued\r\nby the C2.\r\n0x0 Encryption algorithm\r\nZHtrap uses a relatively rare multiple xor encryption algorithm to hide resource information.\r\nThe equivalent python implementation is shown below.\r\nxor_key_lst = [0x51, 0x6A, 0x66, 0x6A, 0x78, 0x53, 0x52, 0x44, 0x46, 0x47, 0x53, 0x46, 0x44, 0x64, 0x66] #Qjfjx\r\nxor_key = 0xD00DBAAF\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 4 of 18\n\ndef decode(content):\r\ndesc_lst = []\r\nplaintext=\"\"\r\n xor_key_lst_idx = 1\r\nfor idx in range(0, len(content)):\r\ndesc_lst.append(chr(content[idx] ^ (xor_key % 0xFF) ^ xor_key_lst[xor_key_lst_idx - 1\r\nxor_key_lst_idx += 1\r\nif xor_key_lst_idx \u003e= len(xor_key_lst):\r\nxor_key_lst_idx = 0\r\nelse:\r\nprint(\"\".join(desc_lst))\r\nTake the following ciphertext as an example\r\ncipher =[\r\n 0x42, 0x69, 0x0B, 0x4C, 0x57, 0x76, 0x72, 0x60, 0x6B, 0x79,\r\n 0x6A, 0x39, 0x6C, 0x58, 0x55, 0x7B, 0x10, 0x49, 0x5C, 0x41,\r\n 0x75, 0x2A, 0x32, 0x43, 0x48, 0x4C, 0x5B, 0x45, 0x61, 0x56,\r\n 0x26, 0x6E, 0x68, 0x27, 0x78, 0x5C, 0x11, 0x45, 0x48, 0x4D,\r\n 0x4B, 0x54, 0x49, 0x71, 0x22, 0x43, 0x7D, 0x3C, 0x75, 0x69,\r\n 0x4E, 0x50, 0x51, 0x42, 0x2A, 0x79, 0x2B, 0x39, 0x17, 0x70,\r\n 0x50, 0x6E, 0x4F, 0x49, 0x51, 0x2E, 0x36, 0x2E, 0x28, 0x2F,\r\n 0x69, 0x6D, 0x69, 0x42, 0x51, 0x7C, 0x40, 0x5E, 0x02, 0x01,\r\n 0x3E, 0x27, 0x37, 0x20, 0x32, 0x13, 0x09, 0x1A, 0x39, 0x57,\r\n 0x2A, 0x12, 0x04, 0x63, 0x27, 0x09, 0x14, 0x11, 0x11, 0x07,\r\n 0x06, 0x51, 0x1C, 0x36, 0x2B, 0x5C, 0x14, 0x2F, 0x3C, 0x27,\r\n 0x27, 0x0D, 0x0C\r\n]\r\nAfter decryption, we get the following plaintext, which is exactly the in the Console prompt\r\nZH infected your shit, message me on discord to compare assets ($reiko#0095), researchers hmu twitter[.]com/Zon\r\nThere are 3 encrypted messages in the current sample, and the decrypted message is shown below, where /proc/\r\nand /stat are used in the next section on process control.\r\nindex plaintext\r\n2 /stat\r\n1 /proc/\r\n0 ZH infected your shit.....\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 5 of 18\n\n0x1 Process Control\r\nZHtrap realizes process control through the whitelist and snapshot mechanism to aceive the exclusivity of the\r\ndevice. A process whose executable path contains the following path is considered a whitelisted process. After\r\nZHtrap is started, it will first obtain the current process list, and then terminate the non-whitelisted processes\r\nthrough kill -9. So it is clear that ZHtrap does not want to destroy the normal operation of the system.\r\n/bin\r\n/sbin\r\n/user/bin\r\n/user/sbin\r\nNext, a snapshot of the processes is created for the system, after which the newly created processes are compared\r\nwith the snapshot and those that do not meet the requirements are removed. In this way the whole system remains\r\nunder ZHtrap's control, and even if the administrator finds a problem with the device, many system management\r\ntools are no longer working properly, making maintenance a difficult task.\r\nClean up non-whitelisted processes\r\nWhen ZHtrap runs, it iterates through the current processes on the system and reads the value of starttime, item 22\r\nin \"/proc/pid/stat\". This value is divided by _SC_CLK_TCK to get how long the process was started after the kernel\r\nstarted. The value of _SC_CLK_TCK is usually equal to 100, 10000/_SC_CLK_TCK results in 100 seconds.So all\r\nprocesses started after 100 seconds of kernel startup will be checked, and if the process path is not in the whitelist,\r\nthe process will be killed.\r\nCreate a snapshot of the processes and clean up any new processes that aren't on the mark.\r\nAfter cleaning the non-whitelisted processes, ZHtrap considers the sys-tem to be in a \"pure state\" and creates a\r\nprocess snapshot for the system first.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 6 of 18\n\nAfter that, all newly created processes will be compared with the process snapshot, and any processes that do not\r\nmeet the requirements will be directly killed.\r\n0x2 Get resource server\r\nZHtrap uses the following code snippet to get the address of the resource server (ResServ), this process can be\r\ndivided into two steps, thefirst step is to establish communication with the Tor domain, the sec-ond step sends\r\n\"GET /sfkjdkfdj.txt\" request.\r\nEstablish communication with the Tor domain\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 7 of 18\n\nZHtrap takes a cue from the Matryosh botnet, first requesting a DNS TXT record from the remote host\r\n0xdeadbeef.tw to get the list of Tor proxies in the figure below.\r\nIt will pick one proxy and send domain:port , if the proxy returns 05 00 00 01 00 00 00 00 00 00 00 , that\r\nmeans the communication has been successfully established. Then send a subsequent GET request to get the\r\nresource server address (107.189.30.190), and the network traffic in the following figure clearly reflects this\r\nprocess.\r\nThe role of Resource server\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 8 of 18\n\nAs can be seen by the IDA cross-reference in the above figure, the ResServ has two functions.\r\nActing as Reporter Server, providing information upload service for the Telnet scanning process\r\nActing as Downloader Server, to provide sample download services for the process of vulnerability\r\npropagation\r\n0x3 Honeypot\r\nZHtrap first creates two pipes for information transfer, and then implements a simple honeypot listening on the\r\nfollowing 23 ports\r\nThe actual effect is as follows.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 9 of 18\n\nWhen these ports of the device are accessed, ZHtrap passes the IP address of the visitor through the pipe for its\r\nown telnet scanning \u0026 vul-nerability scanning module to use.\r\nWhy does it do this?\r\nWe speculate that ZHtrap's authors had this in mind.\r\nMany botnets implement worm-like scan propagation, and when ZHtrap's honeypot port is accessed, its\r\nsource is most likely a device that has been infected by another botnet. This device can be infected,\r\nthere must be flaws, I can use my scanning mechanism to scan again.This could be a good chance that I\r\ncan implant my bot samples, and then with the process control function, I can have total control, is’t\r\nthat awesome?\r\n0x4 Telnet scan\r\nZHtrap uses Telnet scanning to collect devices that use weak passwords. The sources of the scanned objects are of\r\nthe following 2 types.\r\nRandomly generated IPs\r\nPassively received IPs delivered by the above mentioned honeypot\r\nAnd these two group of IPs get to treat differently.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 10 of 18\n\nFor category 1 IPs, SYN port probing is used.\r\nFor category 2 IPs, use the connect function directly.\r\nWhen the target's port 23 is found to be open, try to log in using the hardcoded credentials list, and pass the\r\nfollowing code back to the resource server for the IP, port, account, password, etc. that can successfully log in.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 11 of 18\n\nDuring the login attempt, ZHtrap will ask the scanned device to execute the following command:\r\nenable\r\nlinuxshell\r\nsystem\r\nbash\r\nls /home\r\nps aux\r\n/bin/busybox ZONESEC\r\nThe device type is then determined based on the returned information,and the device will be regarded as a\r\nhoneypot when it contains the following string.\r\nstring honeypot\r\nJun22 cowrie\r\nJun23 cowrie\r\nphil cowrie\r\nsshd: cowrie\r\nrichard cowrie\r\n@LocalHost:] cowrie\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 12 of 18\n\nstring honeypot\r\nWelcome to EmbyLinux 3.13.0-24-generic\r\ntelnet-iot-honeypot\r\nIf it is a honeypot, the device information will be reported to the resource server via port\r\n2231.\r\nIf it is a real device, the device information will be reported to the resource server on port 1282\r\n0x5 Vulnerability scanning \u0026 propagation\r\nZHtrap uses the following 4 samples of Nday vulnerability propagation\r\nJAWS_DVR_RCE\r\nNETGEAR\r\nCCTV_DVR_RCE\r\nCVE-2014-8361\r\nFirst construct a SYN packet to probe whether the device's port is open, and the list of supported ports (exp_port)\r\nis shown below\r\n80 8080 8081 8083 5500\r\n60001 52869 8089 8090 8000\r\n81 82 83 84 85\r\n8888 8181 8443 5555\r\nThen a \"GET /\" request is sent to obtain information about the service\r\nrunning on the port.\r\nThe following code snippet is then used to determine whether the banner\r\ninformation returned by the service is the target device.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 13 of 18\n\n80 8080 8081 8083 5500\r\nFinally, according to the banner information, select the corresponding vulnerability, and ResServ to assemble a\r\nvalid payload to try to implant.\r\nAs with the telnet scanning process, the sources of the scanned objectsare of the following two types.\r\nActive randomly generated IP\r\nPassively receive IPs delivered by the honeypot\r\nFor the first category of IPs, an exp_port is randomly selected for probing, and the relationship between IPs and\r\nexp_ports is 1 to 1.\r\nFor the second category of IPs, all exp_ports are probed, and the relationship between IPs and exp_ports is 1 to N.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 14 of 18\n\nThe network traffic in the following figure illustrates this situation visually.\r\n0x6 C2 communication\r\nZHtrap uses Tor C2 and therefore has to communicate with C2 with the help of a proxy. This process is described\r\nin section above and will not be repeated here. The network traffic shown in the figure below indicates that the\r\nconnection with C2 has been successfully established.\r\nNext, the following code snippet is used to send a registration message to C2\r\nThe actual network traffic generated is as follows.\r\nThe command packet of ZHtrap consists of two packets, the first packet is the header and the second packet is the\r\nbody, where the format of the header is\r\n//5 bytes ,big endian\r\nstruct header\r\n{\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 15 of 18\n\nuint16 body_len;\r\nuint8 cmd_type;\r\nuint16 checksum;\r\n}\r\nTake the above registration packet traffic as an example, the meaning of each field is as follows.\r\nheader:\r\n00 07 -- length of body\r\ne5 -- hardcode,cmd type,\"e5\",\r\n1a fa -- tcp/ip checksum of (\"00 07 e5 00 00\")\r\nbody:\r\n5a 6f 6e 65 53 65 53 -- body string,\"ZoneSec\"\r\nAfter sending the registration packet, bot starts to wait for C2 to send the command, and when the header of the\r\ncommand packet successfully passes the check, it selects the corresponding processing flow based on the\r\ncommand type specified by the third byte in the header.\r\nIt can be seen that a total of five kinds of commands are supported at present, and the correspondence between\r\ncommand codes and functions is shown in the following table.\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 16 of 18\n\nValue Function\r\n0x22 heartbeat\r\n0x45 exit\r\n0x89\r\ndownload\u0026exec\r\npayload\r\n0xF5 reverse shell\r\n0xFE DDoS\r\nTaking heartbeat as an example, the heartbeat packet network flow in the following\r\nfigure verifies our analysis.\r\nReaders are always welcomed to reach us on twitter, or email to netlabat 360dot cn.\r\nIOC\r\nSample MD5\r\n5370e0b9484cb25fb3d5a4b648b5c203\r\n6c7cfbe0277e2ca0cbe7157cad7c663e\r\nf1f70dc1274112ae5287ceb06f096d0e\r\n9dded61f7de47409bc00e74c0a12210e\r\n7b593fbbd6f81a3e9a2043a46949879d\r\nba17282481acca9636c5d01f5c2dd069\r\nURL\r\n0xdeadbeef.tw\r\nh5vwy6o32sdcsa5xurde35dqw5sf3cdsoeewqqxmhoyzsvar4u6ooead.onion:8080\r\nC2\r\noemojwe5loscudytzfo273nkdvalf7mumctwcm42zyutoo6tpfjsphyd.onion:3000\r\nReporter\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 17 of 18\n\n107.189.30.190:1282\r\n107.189.30.190:2231\r\nProxy Ip\r\n51.178.54.234:9095\r\n51.79.157.89:9095\r\n167.114.185.33:9095\r\n147.135.208.44:9095\r\n198.245.53.58:9095\r\n142.93.247.244:9050\r\n66.70.188.235:9095\r\n139.99.134.95:9095\r\n144.217.243.21:9095\r\n46.101.61.9:9050\r\nDownloader\r\nx86 arm5 arm6 arm7 mips\r\nhxxp://107.189.30.190/bins/z.{CPU_ARCH}\r\noemojwe5loscudytzfo273nkdvalf7mumctwcm42zyutoo6tpfjsphyd.onion:8080/z.{CPU_ARCH}\r\nSource: https://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nhttps://blog.netlab.360.com/new_threat_zhtrap_botnet_en/\r\nPage 18 of 18",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.netlab.360.com/new_threat_zhtrap_botnet_en/"
	],
	"report_names": [
		"new_threat_zhtrap_botnet_en"
	],
	"threat_actors": [],
	"ts_created_at": 1775434289,
	"ts_updated_at": 1775791289,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/145a6c87ae2edbb5420669c2c844a54e0b877e65.pdf",
		"text": "https://archive.orkl.eu/145a6c87ae2edbb5420669c2c844a54e0b877e65.txt",
		"img": "https://archive.orkl.eu/145a6c87ae2edbb5420669c2c844a54e0b877e65.jpg"
	}
}