{
	"id": "f93eed99-fbc7-4fa7-b645-5de25d121f83",
	"created_at": "2026-04-06T00:22:36.625302Z",
	"updated_at": "2026-04-10T03:30:30.181999Z",
	"deleted_at": null,
	"sha1_hash": "3ac96651d22bcce099e33c7ae3f569ecae40f4b5",
	"title": "DynoWiper: From Russia with Love",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1119436,
	"plain_text": "DynoWiper: From Russia with Love\r\nBy t0asts\r\nPublished: 2026-02-06 · Archived: 2026-04-05 17:33:34 UTC\r\nOverview\r\nIOCs\r\nInitial Inspection\r\nPRNG Setup\r\nData Corruption\r\nData Deletion\r\nMITRE ATT\u0026CK Mapping\r\nAcknowledgment\r\nOverview\r\nhttps://t0asts.com/dynowiper\r\nPage 1 of 13\n\nIn this post I’m going over my analysis of DynoWiper, a wiper family that was discovered during attacks against\r\nPolish energy companies in late December of 2025. ESET Research and CERT Polska have linked the activity and\r\nsupporting malware to infrastructure and tradecraft associated with Russian state-aligned threat actors, with ESET\r\nassessing the campaign as consistent with operations attributed to Russian APT Sandworm, who are notorious for\r\nattacking Ukrainian companies and infrastructure, with major incidents spanning throughout years 2015, 2016,\r\n2017, 2018, and 2022. For more insight into Sandworm or the chain of compromise leading up to the deployment\r\nof DynoWiper, ESET and CERT Polska published their findings in great detail, and I highly recommend reading\r\nthem for context.\r\nIOCs\r\nThe sample analyzed in this post is a 32-bit Windows executable, and is version A of DynoWiper.\r\nSHA-256 835b0d87ed2d49899ab6f9479cddb8b4e03f5aeb2365c50a51f9088dcede68d5\r\nInitial Inspection\r\nTo start, I ran the binary straight through DIE (Detect It Easy) catch any quick wins regarding packing or\r\nobfuscation, but this sample does not appear to utilize either (unsurprising for wiper malware). To IDA we go!\r\nFigure 1: Detect It Easy\r\nPRNG Setup\r\nJumping right past the CRT setup to the WinMain function, DynoWiper first initializes a Mersenne Twister\r\nPRNG (MT19937) context, with the fixed seed value of 5489 and a state size of 624.\r\nhttps://t0asts.com/dynowiper\r\nPage 2 of 13\n\nFigure 2: Main Function\r\nFigure 3: Mersenne Twister Init\r\nThe MT19937 state is then re-seeded and reinitialized with a random value generated using\r\nstd::random_device , the 624 word state is rebuilt, and a 16-byte value is generated.\r\nhttps://t0asts.com/dynowiper\r\nPage 3 of 13\n\nFigure 4: Mersenne Twister Seed\r\nData Corruption\r\nImmediately following the PRNG setup, the data corruption logic is executed.\r\nFigure 5: Data Corruption Logic\r\nDrives attached to the target host are enumerated with GetLogicalDrives() , and GetDriveTypeW() is used to\r\nidentify the drive type, to ensure only fixed or removable drives are added to the target drive vector.\r\nhttps://t0asts.com/dynowiper\r\nPage 4 of 13\n\nFigure 6: Drive Enumeration\r\nDirectories and files on said target drives are walked recursively using FindFirstFileW() and\r\nFindNextFileW() , while skipping the following protected / OS directories to avoid instability during the\r\ncorruption process.\r\nhttps://t0asts.com/dynowiper\r\nPage 5 of 13\n\nExcluded Directories\r\nsystem32\r\nwindows\r\nprogram files\r\nprogram files(x86)\r\ntemp\r\nrecycle.bin\r\n$recycle.bin\r\nboot\r\nperflogs\r\nappdata\r\ndocuments and settings\r\nhttps://t0asts.com/dynowiper\r\nPage 6 of 13\n\nhttps://t0asts.com/dynowiper\r\nPage 7 of 13\n\nFigures 7-8: Directory Traversal\r\nFor each applicable file, attributes are cleared with SetFileAttributesW() , and a handle to the file is created\r\nusing CreateFileW() . The file size is obtained using GetFileSize() , and the start of the file located through\r\nSetFilePointerEx() . A 16 byte junk data buffer derived from the PRNG context is written to the start of the file\r\nusing WriteFile() . In cases where the file size exceeds 16 bytes, pseudo-random locations throughout the file\r\nare generated, with the count determined by the file size, and a maximum count of 4096. The current file pointer is\r\nagain repositioned to each generated location with SetFilePointerEx() , and the same 16 byte data buffer is\r\nwritten again, continuing the file corruption process.\r\nFigure 9: Random File Offset Generation\r\nhttps://t0asts.com/dynowiper\r\nPage 8 of 13\n\nFigure 10: File Corruption\r\nData Deletion\r\nWith all the target files damaged and the data corruption process complete, the data deletion process begins.\r\nhttps://t0asts.com/dynowiper\r\nPage 9 of 13\n\nFigure 11: Data Deletion Logic\r\nSimilar to the file corruption process, drives attached to the target host are enumerated, target directories are\r\nwalked recursively and target files are removed with DeleteFileW() instead of writing junk data, as seen in the\r\nfile corruption logic.\r\nhttps://t0asts.com/dynowiper\r\nPage 10 of 13\n\nhttps://t0asts.com/dynowiper\r\nPage 11 of 13\n\nFigure 12: File Deletion\r\nTo finish, the wiper obtains its own process token using OpenProcessToken() , enables SeShutdownPrivilege\r\nthrough AdjustTokenPrivileges() , and issues a system reboot with ExitWindowsEx() .\r\nFigure 13: Token Modification and Shutdown\r\nMITRE ATT\u0026CK Mapping\r\nDiscovery (TA0007)\r\nT1680: Local Storage Discovery\r\nT1083: File and Directory Discovery\r\nDefense Evasion (TA0005)\r\nT1222: File and Directory Permissions Modification\r\nT1222.001: Windows File and Directory Permissions Modification\r\nT1134: Access Token Manipulation\r\nPrivilege Escalation (TA0004)\r\nT1134: Access Token Manipulation\r\nImpact (TA0040)\r\nT1485: Data Destruction\r\nT1529: System Shutdown/Reboot\r\nAcknowledgment\r\nFeedback and corrections are welcome.\r\nMany thanks to the SANS ISC for crossposting my analysis!\r\nhttps://t0asts.com/dynowiper\r\nPage 12 of 13\n\nSource: https://t0asts.com/dynowiper\r\nhttps://t0asts.com/dynowiper\r\nPage 13 of 13\n\nPRNG Setup Jumping right past the CRT setup to the WinMain function, DynoWiper first initializes a Mersenne Twister\nPRNG (MT19937) context, with the fixed seed value of 5489 and a state size of 624.\n    Page 2 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://t0asts.com/dynowiper"
	],
	"report_names": [
		"dynowiper"
	],
	"threat_actors": [
		{
			"id": "8941e146-3e7f-4b4e-9b66-c2da052ee6df",
			"created_at": "2023-01-06T13:46:38.402513Z",
			"updated_at": "2026-04-10T02:00:02.959797Z",
			"deleted_at": null,
			"main_name": "Sandworm",
			"aliases": [
				"IRIDIUM",
				"Blue Echidna",
				"VOODOO BEAR",
				"FROZENBARENTS",
				"UAC-0113",
				"Seashell Blizzard",
				"UAC-0082",
				"APT44",
				"Quedagh",
				"TEMP.Noble",
				"IRON VIKING",
				"G0034",
				"ELECTRUM",
				"TeleBots"
			],
			"source_name": "MISPGALAXY:Sandworm",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "7bd810cb-d674-4763-86eb-2cc182d24ea0",
			"created_at": "2022-10-25T16:07:24.1537Z",
			"updated_at": "2026-04-10T02:00:04.883793Z",
			"deleted_at": null,
			"main_name": "Sandworm Team",
			"aliases": [
				"APT 44",
				"ATK 14",
				"BE2",
				"Blue Echidna",
				"CTG-7263",
				"FROZENBARENTS",
				"G0034",
				"Grey Tornado",
				"IRIDIUM",
				"Iron Viking",
				"Quedagh",
				"Razing Ursa",
				"Sandworm",
				"Sandworm Team",
				"Seashell Blizzard",
				"TEMP.Noble",
				"UAC-0082",
				"UAC-0113",
				"UAC-0125",
				"UAC-0133",
				"Voodoo Bear"
			],
			"source_name": "ETDA:Sandworm Team",
			"tools": [
				"AWFULSHRED",
				"ArguePatch",
				"BIASBOAT",
				"Black Energy",
				"BlackEnergy",
				"CaddyWiper",
				"Colibri Loader",
				"Cyclops Blink",
				"CyclopsBlink",
				"DCRat",
				"DarkCrystal RAT",
				"Fobushell",
				"GOSSIPFLOW",
				"Gcat",
				"IcyWell",
				"Industroyer2",
				"JaguarBlade",
				"JuicyPotato",
				"Kapeka",
				"KillDisk.NCX",
				"LOADGRIP",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"ORCSHRED",
				"P.A.S.",
				"PassKillDisk",
				"Pitvotnacci",
				"PsList",
				"QUEUESEED",
				"RansomBoggs",
				"RottenPotato",
				"SOLOSHRED",
				"SwiftSlicer",
				"VPNFilter",
				"Warzone",
				"Warzone RAT",
				"Weevly"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434956,
	"ts_updated_at": 1775791830,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3ac96651d22bcce099e33c7ae3f569ecae40f4b5.pdf",
		"text": "https://archive.orkl.eu/3ac96651d22bcce099e33c7ae3f569ecae40f4b5.txt",
		"img": "https://archive.orkl.eu/3ac96651d22bcce099e33c7ae3f569ecae40f4b5.jpg"
	}
}