{
	"id": "55ab576e-4516-47b7-a9f3-83360cbed803",
	"created_at": "2026-04-06T00:17:59.736013Z",
	"updated_at": "2026-04-10T03:26:42.743447Z",
	"deleted_at": null,
	"sha1_hash": "fd8b47c06985a6f4425d14b6aad1cffee826863c",
	"title": "Daxin Backdoor: In-Depth Analysis, Part One",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 71424,
	"plain_text": "Daxin Backdoor: In-Depth Analysis, Part One\r\nBy About the Author\r\nArchived: 2026-04-05 22:08:35 UTC\r\nFollowing on from our earlier blog detailing the discovery of Backdoor.Daxin, Symantec’s Threat Hunter Team,\r\npart of Broadcom Software, would like to provide further technical details on this threat.\r\nUsed by a China-linked espionage group, Daxin exhibits technical sophistication previously unseen by such\r\nactors. In particular, it implements communications features that appear to have been designed for deep\r\npenetration of highly-secured networks. The focus of this blog series is to document how these features were\r\nimplemented.\r\nDaxin comes in the form of a Windows kernel driver. In this blog, we will detail the driver initialization,\r\nnetworking, key exchange, and backdoor functionality. In our next blog, the second of two, we will examine the\r\ncommunications and network features of the malware.\r\nOur analysis is based on a Backdoor.Daxin sample (SHA256:\r\nea3d773438c04274545d26cc19a33f9f1dbbff2a518e4302addc1279f9950cef). The forensic evidence collected by\r\nus indicates that this sample had been deployed in November 2021 against two separate organizations.\r\nThe described Daxin features are contained in many earlier Daxin variants unless stated otherwise. The recent\r\nchanges to the driver codebase are to support more recent Windows versions and fix certain bugs.\r\nDriver initialization\r\nThe Daxin sample analyzed appears to be packed with a standard VMProtect packer. Many earlier samples feature\r\nan additional, outside, packing layer on top of VMProtect. That outside packer was custom-made for the driver\r\nand even reused the same customized encryption algorithm used in the final payload. We believe that the attackers\r\ndecided to remove that custom packer due to compatibility issues with recent Windows releases.\r\nWhenever the driver is started, the code added by the packer decrypts and decompresses the final payload, and\r\nthen passes control to the entry point of the decompressed payload. At this point, the malicious code is visible in\r\nkernel memory, albeit with some obfuscations.\r\nThe bulk of the payload initialization code is involved with the network stack of the Windows kernel. This\r\nincludes identification of some non-exported structures and hooking of the Windows TCP/IP stack.\r\nDaxin hooks the Network Driver Interface Specification (NDIS) layer by modifying every pre-existing\r\nNDIS_OPEN_BLOCK for the TCP/IP protocol, where the ReceiveNetBufferLists and\r\nProtSendNetBufferListsComplete handlers are replaced with its own. For each of these NDIS_OPEN_BLOCKs,\r\nthe related NDIS_M_DRIVER_BLOCK may also be modified by replacing any existing\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 1 of 7\n\nSendNetBufferListsHandler. When the SendNetBufferListsHandler is not present, the corresponding\r\nNDIS_MINIPORT_BLOCK is modified by replacing NextSendNetBufferListsHandler.\r\nTo identify all NDIS_OPEN_BLOCKs for the TCP/IP protocol, the driver relies on calling NdisRegisterProtocol()\r\nto create and return a new head of non-exported ndisProtocolList. Then it walks ndisProtocolList of every\r\nNDIS_PROTOCOL_BLOCK comparing the Name attribute of each visited NDIS_PROTOCOL_BLOCK structure\r\nwith the string “TCPIP”. The OpenQueue field of the matching structure points to the list of\r\nNDIS_OPEN_BLOCKs to hook. This basic technique is known and documented, but Daxin hooks a slightly\r\ndifferent set of handlers. We believe that these adjustments are not exclusive to Daxin and are driven by\r\narchitectural changes in Windows Network Architecture.\r\nIn order to identify the related NDIS_M_DRIVER_BLOCKs and NDIS_MINIPORT_BLOCKs, the driver analyses\r\n“ndis.sys” machine code to locate non-exported ndisFindMiniportOnGlobalList() and ndisMiniDriverList. The\r\nrelevant NDIS_MINIPORT_BLOCKs are then obtained starting with the previously identified\r\nNDIS_OPEN_BLOCKs, where the RootDeviceName of each instance is passed as a parameter for the\r\nndisFindMiniportOnGlobalList() call that returns the structure to hook. Finally, to locate related\r\nNDIS_M_DRIVER_BLOCKs, the driver walks ndisMiniDriverList checking the MiniportQueue list of each item\r\nfor the already identified NDIS_MINIPORT_BLOCKs.\r\nDetails of the hooking process demonstrated in this blog were captured in the lab using a virtual machine with a\r\nkernel debugger attached.\r\nWhen registering the fake protocol, Daxin calls the NdisRegisterProtocol() API passing a ProtocolCharacteristics\r\nargument with the hardcoded Name attribute “NDISXRPT”.\r\nBecause the layout of the NDIS_OPEN_BLOCK structure changes between different Windows builds, Daxin\r\nneeds to determine the correct offsets to use. First it checks NtBuildNumber against a set of hardcoded values for\r\nwhich NDIS_OPEN_BLOCK offsets are explicitly given (Figure 2).\r\nThe most recent Windows build number hardcoded in Daxin’s codebase is 17763. It corresponds to Windows\r\nServer 2019 and Windows 10 version 1809 (Redstone 5). When the Windows build is not recognized, Daxin\r\nattempts to use an alternative method to determine the NDIS_OPEN_BLOCK offsets.\r\nDaxin then collects details of all NDIS structures to hook, as discussed earlier, along with information about the\r\nrelated network interfaces. Finally, for each network interface, it replaces the original handlers with its own.\r\nNetworking\r\nBoth the ReceiveNetBufferLists hook and the SendNetBufferListsHandler (or NextSendNetBufferListsHandler)\r\nhook implement logic to inspect the network packets and then hijack some packets before passing the remaining\r\npackets to the original handlers. The ProtSendNetBufferListsComplete hook completes any send operation\r\ninitiated by Daxin, such that NET_BUFFER_LIST structures owned by malware are removed and deallocated\r\nbefore calling the original handler.\r\nBefore describing the hooks’ implementation in detail, we will first examine a few examples of the observed\r\nbehavior in Daxin.\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 2 of 7\n\nIn the first scenario, the ReceiveNetBufferLists hook checks the data section of certain TCP packets for predefined\r\npatterns. Any matching TCP packets are then removed from the NetBufferLists before calling the original\r\nReceiveNetBufferLists handler. At the same time, for each removed TCP packet, the malicious driver sends two\r\nnew packets. The first packet is a spoofed RST TCP packet sent to the original destination, so that its recipient\r\nmarks the TCP connection as closed. The second packet is an ACK TCP packet sent to the original source. From\r\nthat point, the malicious driver maintains the TCP connection with the original source, relying on the\r\nReceiveNetBufferLists hook to hijack any related network packets. A test demonstrating this scenario is illustrated\r\nin Figure 4.\r\nWhen generating its network traffic, Daxin uses its own code to forge network packets, bypassing the legitimate\r\nWindows TCP/IP stack. To illustrate this, we reconfigured the Windows TCP/IP stack to use non-standard Time to\r\nLive (TTL). Since Daxin does not respect the updated parameter, its traffic stands out in the Wireshark capture\r\nshown in Figure 4.\r\nThe TCP retransmissions in the Wireshark capture are due to our scripts for the kernel debugger that slow down\r\ndriver response. The retransmissions are not expected otherwise. We decided to activate these scripts to illustrate\r\nthe internal working of the driver, where we can recognize individual packets from our Wireshark capture, as\r\nillustrated in Figure 5.\r\nIn another scenario, Daxin initiates a new TCP connection and maintains it over the whole lifetime of the TCP\r\nsession. The malware relies on the ReceiveNetBufferLists hook to hijack any network packets related to this\r\nconnection. The hijacked packets do not reach the legitimate Windows TCP/IP driver. An example TCP\r\nconnection initiated by the malicious driver will be discussed later in this blog series.\r\nIn the last scenario, Daxin sends a DNS request using the UDP protocol. The response UDP packet is hijacked by\r\nthe ReceiveNetBufferLists hook and the DNS response is parsed by the malicious driver. We exercised this\r\nfunctionality in our lab when exploring configuration options related to command-and-control connectivity.\r\nThe described scenarios indicate that Daxin implements its own TCP/IP stack. This was confirmed with further\r\nreverse engineering of the driver, where we identified both data structures and subroutines implementing IPv4,\r\nTCP, and UDP.\r\nThe main purpose of the NDIS hooks installed by Daxin is to allow for its malicious TCP/IP stack to coexist with\r\nthe legitimate Windows TCP/IP stack on the same machine. When certain conditions are met, the hooks also allow\r\nit to hijack pre-existing TCP connections.\r\nThe ReceiveNetBufferLists hook checks the NblFlags member of the NET_BUFFER_LIST structure at the head of\r\nits NetBufferLists argument for the NDIS_NBL_FLAGS_IS_LOOPBACK_PACKET flag. Whenever the flag is set,\r\nthe hook simply passes the network data to the original ReceiveNetBufferLists handler with no other processing.\r\nOtherwise, it calls a helper subroutine passing the NetBufferLists linked list of NET_BUFFER_LISTs. The helper\r\nsubroutine divides the original linked list of NET_BUFFER_LISTs into two chains: one chain of allowed packets\r\nfor further processing by the legitimate stack and another chain of hijacked packets to drop. The hook then passes\r\nthe chain of allowed packets to the original ReceiveNetBufferLists handler. Next, if the\r\nNDIS_RECEIVE_FLAGS_RESOURCES flag is not set in its ReceiveFlags argument, the hook releases ownership\r\nof the chain of hijacked packets using NdisReturnNetBufferLists().\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 3 of 7\n\nThe SendNetBufferListsHandler hook checks if the NdisPoolHandle member of the NET_BUFFER_LIST\r\nstructure, passed as its NetBufferList argument, corresponds to the pool created by Daxin itself to use when\r\nsending malicious traffic. If so, the hook simply passes the network data to the original\r\nSendNetBufferListsHandler with no other processing. Otherwise, it calls the same helper subroutine as used by the\r\nReceiveNetBufferLists hook to divide its NetBufferList argument into two chains. It then passes the chain of\r\nallowed packets to the original SendNetBufferListsHandler. Finally, the chain of hijacked packets is retired using\r\nthe NdisMSendNetBufferListsComplete() or ProtSendNetBufferListsComplete handler.\r\nThe helper subroutine used by both hooks walks the original linked list of NET_BUFFER_LISTs extracting\r\nnetwork packets from each visited NET_BUFFER_LIST structure and calling the malicious packet filter for each\r\nextracted packet. The verdict returned by the packet filter for the first packet from the visited\r\nNET_BUFFER_LIST structure determines if the structure should be allowed for further processing by the\r\nlegitimate stack or dropped by the hook.\r\nThe packet filter is central to the networking capabilities of Daxin as it controls dispatching of the extracted\r\npackets to various Daxin's sub-modules, where each sub-module implements different functionality. The filter\r\nreturns an “accept” or “drop” verdict to indicate if relevant packets should reach the legitimate TCP/IP stack or\r\nnot. It operates as follows:\r\n1. Checks if the packet is related to any of the network flows from the malicious network tunnel. If so, it\r\ncaptures the packet for forwarding to the remote attacker via an encrypted channel and returns with a\r\n“drop” verdict.\r\n2. Checks if the Ethernet source and destination MAC addresses are equal. If so, it returns with an “accept”\r\nverdict.\r\n3. In cases where it was called from the ReceiveNetBufferLists hook, it checks if the Ethernet source MAC\r\naddress corresponds to any of the network interfaces of the local machine. If so, it returns with an “accept”\r\nverdict.\r\n4. In cases of TCP over IPv4 packets, it tracks certain parameters of an active TCP connection for use by TCP\r\nhijacking logic in the future (if needed).\r\n5. In cases of non-IPv4 packets or when called from the ReceiveNetBufferLists hook, it calls each handler\r\nfrom the list of Daxin’s packet handlers, stopping on the first handler that claims ownership of the packet.\r\nWhenever Daxin’s handler claims ownership on the IPv4 packet, the filter returns with a “drop” verdict.\r\nThese Daxin packet handlers are dynamically registered and unregistered by the malicious TCP/IP stack as\r\nrequired, minimizing the overhead. Furthermore, in case of TCP, the list of handlers is bucketed by the\r\nserver port (which supports TCP servers listening for new connections) or the combination of client and\r\nserver ports (which supports TCP sessions). The packet is parsed before calling handlers and the parser\r\nlogic limits the combination of supported protocols to ARP, UDP over IPv4, and TCP over IPv4.\r\n6. In cases of TCP over IPv4 packets when called from the ReceiveNetBufferLists hook, it checks that the\r\nTCP data in the packet:\r\nStarts with the string “POST” and contains the string “756981520337” without any line break “\\r\\n”\r\nin-between, or\r\nStarts with the sequence of bytes 0x10 0x99 0x10 and is at least eight-bytes long, or\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 4 of 7\n\nStarts with the sequence of bytes 0x10 0x99 0x11 and is at least eight-bytes long\r\nWhen a match is found, it triggers hijacking of the related TCP connection and returns with a “drop”\r\nverdict. It should be noted that these checks are not limited to the start of the TCP conversation, and so it is\r\npossible to trigger hijacking after exchanging an arbitrary amount of data. This provides the option to start\r\ncommunication with the malicious driver at the end of a long conversation with a legitimate server hosted\r\non the infected computer.\r\nFinally, the ProtSendNetBufferListsComplete hook walks the list of NET_BUFFER_LIST structures passed as its\r\nsecond argument checking if the NdisPoolHandle member of the visited NET_BUFFER_LIST structure\r\ncorresponds to the pool created by the malicious driver itself to use when sending malicious traffic. The matching\r\nstructures are removed from the list and, after validating the Flags member, deallocated. The hook then passes the\r\nmodified list to the original ProtSendNetBufferListsComplete handler.\r\nA technical paper by Kaspersky on the Slingshot advanced persistent threat (APT) group describes a technique to\r\nidentify NET_BUFFER_LIST that is very similar to how the ProtSendNetBufferListsComplete hook works,\r\nincluding the use of NdisAllocateNetBufferListPool() and NdisAllocateNetBufferAndNetBufferList(). However,\r\nthere are no other significant structural overlaps.\r\nKey exchange\r\nWhenever Daxin hijacks a TCP connection, it checks the received data for a specific message. The expected\r\nmessage initiates a custom key exchange, where two peers follow complementary steps. When discussing this key\r\nexchange protocol, we are going to use the term “initiator” when referring to the side sending the initial message.\r\nThe opposite side will be called “target”. Interestingly, the analyzed sample can implement both the initiator side\r\nand the target side of this custom key exchange protocol.\r\nFirstly, Daxin starts the target-side protocol for each hijacked TCP connection. Additionally, it can be configured\r\nto connect to a remote TCP server, where it exchanges a certain handshake and then also starts the target-side\r\nprotocol. This scenario will be discussed in our next blog in this series in a section titled “External\r\ncommunication.” Finally, Daxin can be instructed to connect to a remote TCP server, where it starts the initiator-side protocol. We will expand on this in the next section.\r\nBackdoor capabilities\r\nA successful key exchange opens an encrypted communication channel. Daxin uses this communication channel\r\nto exchange various messages. Some messages instruct the malware to perform various operations, such as\r\nstarting an arbitrary process on the affected computer. Others carry results of these operations, such as output\r\ngenerated by the started process, for example. The set of operations recognized by Daxin is rather compact, with\r\nthe most basic operations being reading and writing arbitrary files.\r\nDaxin can also execute arbitrary EXE and DLL binaries. In the case of EXE files, Daxin starts a new user-mode\r\nprocess. The standard input and output of the started process is redirected, so that the remote attacker can\r\ninteractively send input and receive output. When ordered to execute a DLL file, Daxin performs injection into\r\none of the pre-existing “svchost.exe” processes.\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 5 of 7\n\nDaxin provides a dedicated communication mechanism for any additional components deployed by the attacker\r\non the affected computer. Any compatible component can open a “\\\\.\\Tcp4” device created by Daxin to register\r\nitself for communication, where it can optionally assign a 32-bit service identifier to distinguish itself from other\r\nservices that may be active on the same computer. Daxin then forwards any matching communication between the\r\nremote attacker and registered services.\r\nNext, the remote attacker can inspect and update the backdoor configuration. The configuration is implemented as\r\na generic key-value structure that is stored in an encrypted form in the Windows Registry for persistence. All used\r\nconfiguration items will be listed in the “External communication” section in a subsequent blog.\r\nThere are also dedicated messages that encapsulate raw network packets to be transmitted via a local network\r\nadapter. Any response packets are then captured by the malicious driver and forwarded to the remote attacker. This\r\nallows the remote attacker to establish communications with any servers reachable from the affected machine on\r\nthe target’s network, creating a network tunnel for the remote attacker to interact with servers of interest.\r\nFinally, a special message can be used to set up new connectivity across multiple malicious nodes, where the list\r\nof nodes is included in a single command. For each node, the message provides the details required to establish\r\ncommunication, specifically the node IP address, its TCP port number, and the credentials to use during custom\r\nkey exchange. When Daxin receives this message, it picks the next node from the list. Then it uses its malicious\r\nTCP/IP stack to connect to the TCP server listed in the picked entry. Once connected, Daxin starts the initiator-side protocol. On the peer computer, if it is infected with a copy of Daxin, the initiator traffic causes the TCP\r\nconnection to be hijacked, as explained earlier. This is followed by the custom key exchange to open a new\r\nencrypted communication channel. Next, the connecting driver sends an updated copy of the original message\r\nover this new channel, where the position of the next node to use is incremented. The process then repeats for the\r\nremaining nodes on the list.\r\nThe TCP connections created during the above process, along with the connection that received the original\r\nconnectivity setup instruction are then used for subsequent communications. Whenever an intermediate node\r\nreceives a message, it may execute the requested operation or forward it along the connectivity path. For certain\r\noperations, the node to execute the operation is specified by the position along the path. In some remaining cases,\r\nthe operation is always forwarded to the last node. Finally, certain operations are always executed by the first node\r\nonly.\r\nThis method to create multi-hop connectivity is noteworthy. It is not uncommon for the attackers to jump through\r\nmultiple hops in victim networks to get around firewalls or to better blend in with usual network traffic. This\r\nusually involves multiple steps when using other malware, where each jump requires a separate action. However,\r\nin the case of the analyzed sample, the attackers combined these into a single operation. This may indicate that\r\nDaxin is optimized for attacks against well-protected networks and cases when the attackers need to periodically\r\nreconnect into the compromised network.\r\nThe ability to use hijacked TCP connections for backdoor communications is also significant. This may be\r\nrequired when exploiting tightly controlled networks, with strict firewall rules or when the defenders monitor for\r\nnetwork anomalies. On the infected machine, any malicious network connections are bypassing the Windows\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 6 of 7\n\nTCP/IP stack, and this could provide some degree of stealth. The attackers invested significant effort in\r\nimplementing these features with a malicious TCP/IP stack supporting TCP connection hijacking.\r\nThe implementation of network tunneling, where the malicious driver passes the packets directly between the\r\nremote attacker and the target’s network demonstrates how the attackers attempt to minimize their footprint\r\nwithout sacrificing functionality.\r\nBackdoor demonstration\r\nIn order to demonstrate Daxin’s backdoor capabilities, we prepared a lab setup to both illustrate what was\r\ndescribed in the previous section and also to collect some examples of malicious network traffic to discuss later.\r\nOur lab setup consisted of four separate networks and five machines. Some of the machines had two network\r\ninterfaces to communicate with different networks, but all packet forwarding functionality was disabled. Each\r\nmachine ran various network services that were reachable from its neighbors only.\r\nIn our setup, the attackers can communicate with “Alice-PC”, while all of the other machines are unreachable\r\ndirectly to the attackers. This simulates the network of a hypothetical victim, where machines serving different\r\nroles have very restrictive connectivity. “Alice-PC” could represent a DMZ service that is accessible from the\r\ninternet, but all the other machines are tightly isolated.\r\nWe infected all of the configured machines with Daxin, except for just one machine deep in our network that was\r\nleft clean. Next, based on our understanding of the malicious communications protocol gained during reverse\r\nengineering of the malicious driver, we implemented a rough client to interact with the Daxin backdoor running\r\non “Alice-PC”. We used this client to instruct the backdoor on “Alice-PC” to create a communications channel to\r\n“Dave-PC” passing via two intermediate nodes: “Bob-PC” and “Charlie-PC”. The connectivity was established\r\nsuccessfully, and we were able to interact with all the infected machines. Finally, we were able to use this\r\nmalicious network tunnel via “Dave-PC” to communicate with legitimate services on “Clean-PC”.\r\nConclusion\r\nThis concludes the first part of our technical analysis of Daxin. In our second, and final blog, we will examine the\r\ncommunications and networking features of the malware.\r\nSource: https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nhttps://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://symantec-enterprise-blogs.security.com/blogs/threat-intelligence/daxin-malware-espionage-analysis"
	],
	"report_names": [
		"daxin-malware-espionage-analysis"
	],
	"threat_actors": [
		{
			"id": "72aaa00d-4dcb-4f50-934c-326c84ca46e3",
			"created_at": "2023-01-06T13:46:38.995743Z",
			"updated_at": "2026-04-10T02:00:03.175285Z",
			"deleted_at": null,
			"main_name": "Slingshot",
			"aliases": [],
			"source_name": "MISPGALAXY:Slingshot",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "f55c7778-a41c-4fc6-a2e7-fa970c5295f2",
			"created_at": "2022-10-25T16:07:24.198891Z",
			"updated_at": "2026-04-10T02:00:04.897342Z",
			"deleted_at": null,
			"main_name": "Slingshot",
			"aliases": [],
			"source_name": "ETDA:Slingshot",
			"tools": [
				"Cahnadr",
				"GollumApp",
				"NDriver"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434679,
	"ts_updated_at": 1775791602,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/fd8b47c06985a6f4425d14b6aad1cffee826863c.pdf",
		"text": "https://archive.orkl.eu/fd8b47c06985a6f4425d14b6aad1cffee826863c.txt",
		"img": "https://archive.orkl.eu/fd8b47c06985a6f4425d14b6aad1cffee826863c.jpg"
	}
}