{
	"id": "826ad606-2997-4fdb-a56b-9290d53e91e9",
	"created_at": "2026-04-06T00:21:19.167422Z",
	"updated_at": "2026-04-10T13:12:43.521449Z",
	"deleted_at": null,
	"sha1_hash": "ff5bc26da0de686838ed36b0e3c4658458839cb2",
	"title": "Analysis of Uroburos, using WinDbg",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 318148,
	"plain_text": "Analysis of Uroburos, using WinDbg\r\nBy MN\r\nPublished: 2017-06-19 · Archived: 2026-04-05 23:03:31 UTC\r\n06/02/2014\r\nReading time: 6 min (1664 words)\r\nUroburos was already described as a very sophisticated and highly complex malware in our G DATA Red Paper,\r\nwhere we had a look at the malware’s behavior. This malware belongs to a specific type called rootkit. The general\r\npurpose of a rootkit is to modify the behavior of the system and, especially, to hide its activity. Generally, a rootkit\r\nresides in the kernel. To analyze this kind of malicious software, analysts need to use specific tools, such as\r\nWinDbg, to debug the Microsoft Windows kernel. WinDbg is a debugger provided by Microsoft. One can use this\r\ntool to debug user mode applications and kernel mode applications (for example the drivers).\r\nToday, we would like to give you an understanding of how analysts work their way through malware and give you\r\nsome insights into the code of one of the most sophisticated digital threats. In this current example case, we\r\ndecided to work with a memory dump (crash dump) of a system infected with Uroburos. To facilitate the analysis,\r\nwe added an extension to add the support of python, called: PyKd. WinDbg has its own script language, but it is\r\nnot easy to understand. One can download this python extension here, for free: http://pykd.codeplex.com/.\r\nTo realize this article, the machine was infected by the Uroburos dropper with the following md5:\r\n626576e5f0f85d77c460a322a92bb267.\r\nVisualization of the hooks\r\nThe Uroburos rootkit adds several hooks to hide its activity. In our specific case, the hooking is a technique used\r\nto alter the behavior of specific system functions; the rootkit fakes the output of the Microsoft Windows API. For\r\nexample, it hides registry entries, files and more.\r\nTo perform this task, the rootkit developers decided to use interrupts. We can display the Interrupt Descriptor\r\nTable (IDT), as shown below. The IDT table stores pointers to ISR (Interrupt Service Routines), which are called\r\nwhen an interrupt is triggered.\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 1 of 12\n\nOne of the pointers (0x859e84f0) is unknown and cannot be resolved. All other pointers have a function name,\r\nfollowing the address. The last digits of the first column are the ID of the interrupt (in our case 0xC3). We can\r\ndisassemble the code available at this address:\r\nThe last argument of the WinDbg command is the length (L0x16) to disassemble. The function starts by a series of\r\nNOP. The interrupt 0xC3 is used by the malware, the next step is to identify how and when this interrupt is\r\ntriggered. Here is the code of the beginning of the function IoCreateDevice():\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 2 of 12\n\nWe can see that the second instruction is int 0xC3 (interrupt 0xC3). Thanks to the PyKd extension, we can easily\r\ncreate a python script to detect every function with this interrupt:\r\nThis script starts to list each exported function in ntoskrnl.exe. Secondly, for each function it checks if the second\r\ninstruction is int 0xC3 (cdc3). If it is the case, the exported function’s name is displayed. Here is the output of the\r\nscript regarding the current analysis:\r\nWe could use the function: !chkimg to easily identify the hook. However, it was a good exercise to play with\r\nPyKd.\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 3 of 12\n\nAnother interesting step is to dump the code of the driver. To perform this task, we first need to find the beginning\r\nof the PE. We can find the address thanks to the address of the code executed when an interrupt is triggered:\r\nThis output shows us two remarkable things:\r\n First, the driver uses a well-known Windows kernel memory pool tag called \"NtFs\". The Windows\r\ncomponents mark allocated memory block with a unique tag. But the rootkit uses the same tag as the\r\nlegitimate ntfs.sys driver. This choice was made to hide the rootkit and dupe the analyst.\r\nSecondly, the output looks like the beginning of a PE. But this PE is broken: the MZ is not available and\r\nsome information is missing. For example, the value of the SizeOfImage (85980000+0x140) is null...\r\nThe rootkit alters the beginning of the PE to hide itself. Some tools parse the memory and look for the MZ string\r\nto identify the beginning of a PE. In our current case, if we used these tools looking for a PE file, we would never\r\nidentify our malware using this automation. Manual analysis is needed here. To dump our driver we need to\r\nreconstruct the PE but we don't know the size of the binary, as mentioned above, so we need to make a large\r\ndump, to be sure to not forget a part of the binary.\r\nModules, drivers and devices\r\nWe can now display the loaded (and unloaded) modules with WinDbg:\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 4 of 12\n\nIn our case, the rootkit’s module is fdisk.sys. According to the code shown above, it seems to be unloaded, but as\r\nwe analyzed before, the code is really present on the infected system. So, the developers found a way to unload\r\nthe modules while the malicious code is still running!\r\nWe can list the drive\r\nThe driver used by our module is \\driver\\Null. All other modules are legitimate modules used by Windows. We\r\ncan display the devices associated to the driver we are focusing on:\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 5 of 12\n\nThe device objects associated to our driver are:\r\n  0x864473e0\r\n  0x862531e0\r\n  0x86253748\r\n  0x8576a2d0\r\nFurthermore, we can see the description of those devic\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 6 of 12\n\nTwo objects are particularly interesting: FWPMCALLOUT and RawDisk1\r\nWFP callout\r\nThis first device is FWPMCALLOUT. Thanks to the name of the device we can guess that the rootkit registers a\r\ncallout for Windows Filtering Platform (WFP). The WFP is a set of API and system services which provides a\r\nplatform for creating network filtering applications. In our case, the rootkit uses this technology to perform Deep\r\nPacket Inspection (DPI) and modifications of the network flow. The purpose of this device is to intercept relevant\r\ndata as soon as a connection to the Command \u0026 Control server or other local infected machines used as relay is\r\nestablished and to receive commands.\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 7 of 12\n\nAs there is no command to simply list the WFP callouts, we have to extract the information needed using different\r\nsteps:\r\nFirst, the netio!gWfpGlobal variable contains the starting point for the WFP data structures:\r\nA global table stores the number of callouts and the array of the corresponding callout structures.\r\nHere is a method to find suitable offsets:\r\nThe first number is the offset that contains the number of total callouts made, in hex, of course:\r\nThe second number is the offset that contains the array in which the callout structure is stored:\r\nThe pool tag of this address confirms our findings so far and proves that we have found the right track:\r\nWe can now extract the size of each structure stored within the array. As it is not documented by Microsoft, we\r\nidentify the size by disassembling the function InitDefaultCallout():\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 8 of 12\n\nFinally, we use a one-liner command to list the elements of this array:\r\nThe list of elements reminds us of the information we have seen in the IDT: two addresses are not resolved. Those\r\ntwo WFP callouts are: 0x859b5040 and 0x859b5520. WinDbg is not able to resolve these two addresses because\r\nthe addresses are unknown. These are not addresses of a Microsoft. Now that we have the addresses, we can use\r\nthe command !pool to validate that the addresses are in the same region as the code executed when an interrupt is\r\ntriggered:\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 9 of 12\n\nVirtual file system\r\nPreviously, when looking at the device objects, we came across two devices with very similar names: RawDisk1\r\nand RawDisk2. Let us have a detailed look at the first one:\r\nAs we can see, RawDisk1 device is in fact an NTFS file system; a virtual file system used by the rootkit to store\r\nits configuration, the exfiltrated data…\r\nWe can identify the used files (opened handles) within the file system, like \\queue and \\klog:\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 10 of 12\n\nThanks to this command we are able to list the files hidden from the operating system.\r\nDigital signature enforcement\r\nMicrosoft created a Driver Signing Policy for its 64-bit versions of Windows Vista and later versions.  To load a\r\ndriver, the .sys file must be signed by a legitimate publisher. Developers may disable the Driver Signature\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 11 of 12\n\nEnforcement process during the development phase of a driver, which means a developer does not have to sign\r\neach compiled driver version during development phase. This mode is called “Test-mode”. In our case, the rootkit\r\nis not signed, which would usually mean that it had no chance to be accepted by Microsoft’s policy, but it disables\r\nthe digital signature process to circumvent the checks. The status of this feature is stored in the global variable\r\nnt!g_cienabled. Compare the value of this variable on a clean system, without infection with the same information\r\non an infected system:\r\nThe code above shows that the value is set to 1\r\nWe can clearly identify that the malware disabled the driver signature enforcement. Generally speaking, we could\r\ndo the same by using bcdedit.exe -set TESTSIGNING OFF, to switch into testing mode to be able to load\r\nunsigned driver. The difference is: Using bcdedit.exe triggers a message window which is shown to the user, at the\r\nbottom of the desktop, and this is not very secretive. The action could be detected immediately.\r\nMore information about the malware’s circumvention of the driver signature enforcement can be found in our\r\nSecurityBlog article: Uroburos – Deeper travel into kernel protection mitigation\r\nConclusion\r\nWhat you have seen now, is a very limited part of the extensive analysis of complicated malware and a very short\r\nintroduction into WinDbg. Generally, it is very hard to apprehend such an extensive tool, but when working on\r\nsuch a case of kernel land analysis, researchers do not have a choice.\r\nProcessed like this, in an article with code snippets, the results seem logic and do make perfect sense. But, believe\r\nus, working with malware code costs a lot of extensive training, experience and time.\r\nRelated articles\r\n2014/05/13 Uroburos rootkit: Belgian Foreign Ministry stricken\r\n2014/03/07 Uroburos – Deeper travel into kernel protection mitigation\r\n2014/02/28 Uroburos - highly complex espionage software with Russian roots\r\n2014/02/28 G DATA RedPaper about Uroburos\r\nSource: https://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nhttps://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg\r\nPage 12 of 12",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"ETDA"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.gdatasoftware.com/blog/2014/06/23953-analysis-of-uroburos-using-windbg"
	],
	"report_names": [
		"23953-analysis-of-uroburos-using-windbg"
	],
	"threat_actors": [
		{
			"id": "75108fc1-7f6a-450e-b024-10284f3f62bb",
			"created_at": "2024-11-01T02:00:52.756877Z",
			"updated_at": "2026-04-10T02:00:05.273746Z",
			"deleted_at": null,
			"main_name": "Play",
			"aliases": null,
			"source_name": "MITRE:Play",
			"tools": [
				"Nltest",
				"AdFind",
				"PsExec",
				"Wevtutil",
				"Cobalt Strike",
				"Playcrypt",
				"Mimikatz"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "a97fee0d-af4b-4661-ae17-858925438fc4",
			"created_at": "2023-01-06T13:46:38.396415Z",
			"updated_at": "2026-04-10T02:00:02.957137Z",
			"deleted_at": null,
			"main_name": "Turla",
			"aliases": [
				"TAG_0530",
				"Pacifier APT",
				"Blue Python",
				"UNC4210",
				"UAC-0003",
				"VENOMOUS Bear",
				"Waterbug",
				"Pfinet",
				"KRYPTON",
				"Popeye",
				"SIG23",
				"ATK13",
				"ITG12",
				"Group 88",
				"Uroburos",
				"Hippo Team",
				"IRON HUNTER",
				"MAKERSMARK",
				"Secret Blizzard",
				"UAC-0144",
				"UAC-0024",
				"G0010"
			],
			"source_name": "MISPGALAXY:Turla",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434879,
	"ts_updated_at": 1775826763,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ff5bc26da0de686838ed36b0e3c4658458839cb2.pdf",
		"text": "https://archive.orkl.eu/ff5bc26da0de686838ed36b0e3c4658458839cb2.txt",
		"img": "https://archive.orkl.eu/ff5bc26da0de686838ed36b0e3c4658458839cb2.jpg"
	}
}