{
	"id": "7cdebe81-b346-4c6f-be21-548f8108c9d8",
	"created_at": "2026-04-06T01:30:36.332474Z",
	"updated_at": "2026-04-10T13:13:07.233075Z",
	"deleted_at": null,
	"sha1_hash": "944a846fa1dff0aefb5b925f02b8480f0d16131c",
	"title": "BPFDoor - Part 1 - The Past",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1056935,
	"plain_text": "BPFDoor - Part 1 - The Past\r\nBy haxrob\r\nPublished: 2025-06-02 · Archived: 2026-04-06 00:07:09 UTC\r\n💡\r\nThis is the first part on a series of posts on the BPFDoor malware.\r\nIn Part 2 we look at evasive changes in samples reported in a significant telecommunication company's breach -\r\nalong with IoCs.\r\nIn this post we follow breadcrumbs sprinkled across the Internet's past in an attempt to understand BPFDoor\r\npotential code origin which span almost 20 years ago. We also uncover a fork or early version which appeared in\r\nthe wild in 2016\r\nRefer to the following timeline of events described:\r\nA timeline spanning almost 20 years\r\nThis post attempts to mostly avoid what's already been covered in prior literature. For readers not familiar with\r\nBPFDoor , the following resources are recommended for prior reading: Trend Micro (2025), Sandfly Security\r\n(2022), Elastic (2022).\r\n💡\r\nThis post makes no assertion related to the attribution of BPFDoor's developer(s) nor attributed threat actor(s).\r\nJust for fun\r\nCentral to this post is sniffdoor - the source code is not easy to find. A mirror can be found here.\r\nMany early samples of BPFDoor found in the wild use the hardcoded password justforfun . We also see this in\r\nleaked source code:\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 1 of 14\n\nPivoting off this phrase, we land back to the year 2011, stumbling on an archived blog, \"Just for fun\", also sharing\r\nits title with the name of book by Linus Torvalds, published in 2001. The domain was registered in 2011:\r\nBPFDoor includes a hardcoded epoch timestamp used for time stomping. The date is October 30, 2008 GMT\r\nNotably the most recent samples have retained this code, but never call it.\r\n21 days after this hardcoded date, a program titled \"Program Just for Fun!\" was published by the developer of\r\nsniffdoor :\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 2 of 14\n\nIf you compile and run the program, you will be greeted with an ASCII animation of a tank firing shells across\r\nyour terminal.\r\nAlso in 2006, the developer released source to soshell (source mirror)\r\nAnd sniffdoor (cloud-sec.org archive.org, archive.org, archive.org):\r\nBoth sniffdoor and BPFDoor use the pty control handling from another program, bindtty (mirror). While\r\nbindtty is not dated, there is some code overlap with a kernel rootkit, published in Phrack #58 in 2001 by\r\nsd@fs.cz .\r\nTimestamps from the obtained sniffdoor archive align with the posting date on forum.eviloctal.com\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 3 of 14\n\ne08028d5582f14b3f810a299330318119deb03a8d6e3ffac43cb7782a1f8c25e\r\nevaloctal.com forum post\r\nThe comment section in the compiled binaries in the tarball indicate the binary compiled on the Asianux\r\ndistribution giving a compilation date sometime after January 23rd 2006:\r\nAs such, we can date sniffdoor to be likely developed and released between 2006-2007.\r\nSimilarities between BPFDoor and sniffdoor (v1.0):\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 4 of 14\n\nSharing the same code for its pseudo terminal handling (taken from bindtty ).\r\nNumerous overlapping function names/routines\r\nUses raw sockets to intercept magic / wakeup packets\r\nSupports both connect/bind and reverse shells\r\nBPFDoor has improved stealth capability and other improvements that's not present in sniffdoor :\r\nUses a BPF filter to reduce volume of traffic hitting the process as it looks for magic packets\r\nIn addition to TCP for magic packets, UDP and ICMP is also supported\r\nPayload is encrypted\r\nAnti-forensics such as masquerading its process name, time-stomping, overwriting environment variables\r\nInjects iptables rules in bind mode\r\nAs an example with BPFDoor on the left and sniffdoor on the right. Both routines originate their code from\r\nbindtty.c :\r\nBPFDoor (left) and sniffdoor (right)\r\nBPFDoor 's decompiled controller's getshell function overlaps with sniffdoor 's getshell_local . Note that\r\nthere is no known source for the controller in the public domain at the time of writing.\r\n💡\r\n2026-03-27 update: Source code for a recent variant has been identified. Find it here.\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 5 of 14\n\nBPFDoor controller (left) and snniffdoor (right)\r\nAs sniffdoor and soshell borrowed code from bindtty.c . The soshell client source includes a comment\r\nthat code was also taken from conntty which could not be found archived or otherwise.\r\nIn the todo file of snniffDoor 's code we can see features that would make it's way into BPFDoor :\r\nIn future (I hope):\r\n - Support ICMP,UDP protocol woke up.\r\n - Make it more stable.\r\nAlso found are comments on an intention to add process name masquerading - in a dynamic manner - another\r\nfeature which also made its way into BPFDoor\r\nAn (automated) translation:\r\nHide, hide, now the initial plan is to use a fake process name to fool around, making it look like -bash,\r\nhehe, then create an LKM to hide it, ideally achieving dynamic hiding.\r\nWe see that BPFDoor did 'fake' it's process name from by randomly selecting from a predefined list. (The newest\r\nversions removed the random selection, as seen in part 2 of this post)\r\nAn LKM would also too eventuate as the WNPS rootkit - also sharing code overlaps with both sniffdoor and\r\nthe bpfdoor client:\r\nbfpdoor client\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 6 of 14\n\nwnps client\r\nThe circumstantial details here provides no evidence in respect to the attribution of the author of BPFDoor . The\r\nchoice of the password justforfun for BPFDoor is an curious one though. Some possible explanations:\r\nThe sniffdoor developer, WZT was the very first initial developer of BPFDoor\r\nAnother developer visited WZT 's blogs, obtained the sniffdoor or soshell code and was influenced\r\nwith the phrasing \"Just for fun\" or added the term as password as a means of a false flag (misattribution)\r\nThe phrasing is a complete coincidence, the developers of BPFDoor and WZT being Linux enthusiasts,\r\nboth enjoyed reading Linus's book, titled \"Just For Fun\".\r\nAlso must be considered is the possibility that BPFDoor and sniffdoor both borrowed code from a\r\ncommon source other then bindtty.c . This code goes back many decades and version/derivates are likely\r\nto have been shared amongst individuals and groups.\r\nThe sniffdoor developer released other (more well known) software in that era, such as the adore-ng rootkit\r\n(which was reported to be included in APT 41's toolset (Mandiant report, page 47).\r\n💡\r\nThe timing of the development of sniffdoor developer was coincides around the time they were reported to\r\nhave left the NCPH Group (source, page 203).\r\nNotably, some remaining members of NCPH Group became associated to APT 41. Also for interesting reading is\r\nthis testimony by Adam Kozy.\r\nNotBPFDoor - An early direct descendent\r\nWhile testing YARA rule sets for BPFDoor for part 2 of this post, a very early version of BPFDoor was\r\nidentified. The two samples are not compatible with the observed clients to date: and more notably, does not use a\r\nBPF filter (as sniffdoor ). Hence, to differentiate, we give the name - NotBPFDoor .\r\nTwo samples were uploaded in August 2016, with the initial submitters originating from Hong Kong (link). This\r\nwas before the source code had leaked into the public domain.\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 7 of 14\n\nb2d3c212e71ddbaf015d8793d30317e764131c9beda7971901620d90e6887b30\r\nebffd115918f6d181da6d8f5592dffb3e4f08cd4e93dcf7b7f1a2397af0580d9\r\nNotBPFDoor shares significant code overlap with BPFDoor . Although there is extra functionality which has been\r\nremoved in BPFDoor samples:\r\nOptional boot persistence mechanism\r\nAbility to re-configure it's process name and password through a configuration menu\r\nAdditionally, NotBPFDoor :\r\nUses a single password rather then two (to differentiate mode of operation)\r\nUses a semaphore as a mutex lock rather then writing a file to disk\r\nInitial process name and passwords\r\nA single hardcoded process name is used ( portmap and rhnsd ). Later BPFDoor samples randomly select from\r\na list of process names. The malware then goes full circle as we will see with the most recent variants revert back\r\nto a single process name.\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 8 of 14\n\nb2d3c212e71ddbaf015d8793d30317e764131c9beda7971901620d90e6887b30\r\nMutex Lock\r\nThe mutex lock uses libc's semget function to set a semaphore for the process rather then to write a file to\r\ndisk. The semaphore key is 1433490800 ( 0x55715570) which corresponds to a epoch date of Friday,\r\nJune 5, 2015 UTC. This could hit at the approximate year the code was in development.\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 9 of 14\n\nebffd115918f6d181da6d8f5592dffb3e4f08cd4e93dcf7b7f1a2397af0580d9\r\nIf the process abnormally terminates, the semaphore is still held by the kernel, meaning it will have to be manually\r\nremoved before the process can be started again (unless the system is rebooted)\r\n$ ipcs\r\n...\r\n------ Semaphore Arrays --------\r\nkey semid owner perms nsems\r\n0x55715570 0 root 600 1\r\n$ ipcrm -S 0x55715570\r\nPersistence\r\nA feature that seems to be removed in later BPFDoor samples is the ability for maintaining persistence across\r\nsystem reboot. If the x flag is used, the file /etc/profile.d/lang.sh is checked to contain the string unset\r\nLC_TIME . It then adds itself to this script which will be run every time a user logs in with a shell.\r\nSelf Modifying Configuration\r\nThe masqueraded process name and password can be configured with the C switch. A \"start time\" and \"end\r\ntime\" can also be configured.\r\nThe start/end time options appear to be unused.\r\nRather then write to an external configuration file, the changed parameters appended to itself, increasing the ELF\r\nbinary file size by 598 bytes. The first 64 bytes is a fixed byte sequence originating from a global in the .ro\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 10 of 14\n\nsection. If these 64 bytes are not found at the end of itself, then they will be written - followed by 534 bytes of the\r\nactual configuration:\r\nThe 'marker' bytes Shannon entropy: 5.65625 . It's origin has not been identified.\r\nIn one version it looks as if hex encoded bytes were pasted into the source as a string, rather then as as actual byte\r\nvalues (a likely mistake, fixed in the second identified sample)\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 11 of 14\n\nb2d3c212e71ddbaf015d8793d30317e764131c9beda7971901620d90e6887b30\r\nIf others would like to have a go at trying to identify what the byte sequence could be, here it is:\r\n4A 8A BA AB A8 80 F7 F0 24 C6 A5 4B 4A B4 0D DD E4 C6 FF 80 75 0E B7 25 7C 95 B2 9A E6 6C A6 87 B2 CC 06 FF 26\r\nAn early packet_loop\r\nWe see a very early version of the packet_loop routine. Only TCP is supported and no setsockopt with\r\nSO_ATACH_FILTER . The hardcoded magic bytes are 0x5571 .\r\n( BPFDoor samples have been observed to use 0x7255 , 0x5293 and 0x39393939 ).\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 12 of 14\n\nebffd115918f6d181da6d8f5592dffb3e4f08cd4e93dcf7b7f1a2397af0580d9\r\nIn summary, NotBPFDoor appears to either an early fork or early version of BPFDoor with slightly different\r\nfunctionality.\r\nNext, onto part 2 where we jump to the year 2025 and look at how the malware has evolved.\r\nAppendix\r\nCitations\r\nA list of links referenced in this post series (This is the only content in which an LLM was used to assist in writing\r\nthis post)\r\nMalpedia details on BPFDoor\r\nTechCrunch timeline of SKT data breach\r\nBoho (KrCERT) samples page\r\nTrend Micro BPFDoor research (2025)\r\nSandfly Security BPFDoor analysis (2022)\r\nElastic security labs on BPFDoor (2022)\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 13 of 14\n\nSniffdoor Mirror\r\nBindtty Mirror\r\nArchived cloud-sec blog\r\nJust for Fun book on Goodreads\r\nArchived XSec releases page\r\nsoshell Mirror\r\nArchived cloud-sec.org homepage\r\nArchived lengmo.net post\r\nArchived huaidan.org post\r\nArchived eviloctal forum post\r\nMandiant APT41 report\r\nArchived WickedRose document\r\nAVIEN Malware Defense Guide PDF\r\nJustice Department APT41 press release\r\nFBI wanted page for APT 41\r\nUSCC Adam Kozy testimony\r\nVirusTotal file analysis page\r\nBPFDoor dump\r\nElastic BPFDoor configuration extractor\r\nNeo23x0 signature-base YARA rule\r\nArchived Just for Fun book on Archive.org\r\nAdore-ng GitHub repository\r\nArchived program details on Baidu blog\r\nSource: https://haxrob.net/bpfdoor-past-and-present-part-1/\r\nhttps://haxrob.net/bpfdoor-past-and-present-part-1/\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://haxrob.net/bpfdoor-past-and-present-part-1/"
	],
	"report_names": [
		"bpfdoor-past-and-present-part-1"
	],
	"threat_actors": [
		{
			"id": "c7d9878a-e691-4c6f-81ae-84fb115a1345",
			"created_at": "2022-10-25T16:07:23.359506Z",
			"updated_at": "2026-04-10T02:00:04.556639Z",
			"deleted_at": null,
			"main_name": "APT 41",
			"aliases": [
				"BrazenBamboo",
				"Bronze Atlas",
				"Double Dragon",
				"Earth Baku",
				"G0096",
				"Grayfly",
				"Operation ColunmTK",
				"Operation CuckooBees",
				"Operation ShadowHammer",
				"Red Kelpie",
				"SparklingGoblin",
				"TA415",
				"TG-2633"
			],
			"source_name": "ETDA:APT 41",
			"tools": [
				"9002 RAT",
				"ADORE.XSEC",
				"ASPXSpy",
				"ASPXTool",
				"AceHash",
				"Agent.dhwf",
				"Agentemis",
				"AndroidControl",
				"AngryRebel",
				"AntSword",
				"BLUEBEAM",
				"Barlaiy",
				"BlackCoffee",
				"Bladabindi",
				"BleDoor",
				"CCleaner Backdoor",
				"CHINACHOPPER",
				"COLDJAVA",
				"China Chopper",
				"ChyNode",
				"Cobalt Strike",
				"CobaltStrike",
				"Crackshot",
				"CrossWalk",
				"CurveLast",
				"CurveLoad",
				"DAYJOB",
				"DBoxAgent",
				"DEADEYE",
				"DEADEYE.APPEND",
				"DEADEYE.EMBED",
				"DEPLOYLOG",
				"DIRTCLEANER",
				"DUSTTRAP",
				"Derusbi",
				"Destroy RAT",
				"DestroyRAT",
				"DodgeBox",
				"DragonEgg",
				"ELFSHELF",
				"EasyNight",
				"Farfli",
				"FunnySwitch",
				"Gh0st RAT",
				"Ghost RAT",
				"HDD Rootkit",
				"HDRoot",
				"HKDOOR",
				"HOMEUNIX",
				"HUI Loader",
				"HidraQ",
				"HighNoon",
				"HighNote",
				"Homux",
				"Hydraq",
				"Jorik",
				"Jumpall",
				"KEYPLUG",
				"Kaba",
				"Korplug",
				"LATELUNCH",
				"LOLBAS",
				"LOLBins",
				"LightSpy",
				"Living off the Land",
				"Lowkey",
				"McRAT",
				"MdmBot",
				"MessageTap",
				"Meterpreter",
				"Mimikatz",
				"MoonBounce",
				"MoonWalk",
				"Motnug",
				"Moudour",
				"Mydoor",
				"NTDSDump",
				"PACMAN",
				"PCRat",
				"PINEGROVE",
				"PNGRAT",
				"POISONPLUG",
				"POISONPLUG.SHADOW",
				"POTROAST",
				"PRIVATELOG",
				"PipeMon",
				"PlugX",
				"PortReuse",
				"ProxIP",
				"ROCKBOOT",
				"RbDoor",
				"RedDelta",
				"RedXOR",
				"RibDoor",
				"Roarur",
				"RouterGod",
				"SAGEHIRE",
				"SPARKLOG",
				"SQLULDR2",
				"STASHLOG",
				"SWEETCANDLE",
				"ScrambleCross",
				"Sensocode",
				"SerialVlogger",
				"ShadowHammer",
				"ShadowPad Winnti",
				"SinoChopper",
				"Skip-2.0",
				"SneakCross",
				"Sogu",
				"Speculoos",
				"Spyder",
				"StealthReacher",
				"StealthVector",
				"TERA",
				"TIDYELF",
				"TIGERPLUG",
				"TOMMYGUN",
				"TVT",
				"Thoper",
				"Voldemort",
				"WIDETONE",
				"WINNKIT",
				"WINTERLOVE",
				"Winnti",
				"WyrmSpy",
				"X-Door",
				"XDOOR",
				"XMRig",
				"XShellGhost",
				"Xamtrav",
				"ZXShell",
				"ZoxPNG",
				"certutil",
				"certutil.exe",
				"cobeacon",
				"gresim",
				"njRAT",
				"pwdump",
				"xDll"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "4d5f939b-aea9-4a0e-8bff-003079a261ea",
			"created_at": "2023-01-06T13:46:39.04841Z",
			"updated_at": "2026-04-10T02:00:03.196806Z",
			"deleted_at": null,
			"main_name": "APT41",
			"aliases": [
				"WICKED PANDA",
				"BRONZE EXPORT",
				"Brass Typhoon",
				"TG-2633",
				"Leopard Typhoon",
				"G0096",
				"Grayfly",
				"BARIUM",
				"BRONZE ATLAS",
				"Red Kelpie",
				"G0044",
				"Earth Baku",
				"TA415",
				"WICKED SPIDER",
				"HOODOO",
				"Winnti",
				"Double Dragon"
			],
			"source_name": "MISPGALAXY:APT41",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "e698860d-57e8-4780-b7c3-41e5a8314ec0",
			"created_at": "2022-10-25T15:50:23.287929Z",
			"updated_at": "2026-04-10T02:00:05.329769Z",
			"deleted_at": null,
			"main_name": "APT41",
			"aliases": [
				"APT41",
				"Wicked Panda",
				"Brass Typhoon",
				"BARIUM"
			],
			"source_name": "MITRE:APT41",
			"tools": [
				"ASPXSpy",
				"BITSAdmin",
				"PlugX",
				"Impacket",
				"gh0st RAT",
				"netstat",
				"PowerSploit",
				"ZxShell",
				"KEYPLUG",
				"LightSpy",
				"ipconfig",
				"sqlmap",
				"China Chopper",
				"ShadowPad",
				"MESSAGETAP",
				"Mimikatz",
				"certutil",
				"njRAT",
				"Cobalt Strike",
				"pwdump",
				"BLACKCOFFEE",
				"MOPSLED",
				"ROCKBOOT",
				"dsquery",
				"Winnti for Linux",
				"DUSTTRAP",
				"Derusbi",
				"ftp"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "2a24d664-6a72-4b4c-9f54-1553b64c453c",
			"created_at": "2025-08-07T02:03:24.553048Z",
			"updated_at": "2026-04-10T02:00:03.787296Z",
			"deleted_at": null,
			"main_name": "BRONZE ATLAS",
			"aliases": [
				"APT41 ",
				"BARIUM ",
				"Blackfly ",
				"Brass Typhoon",
				"CTG-2633",
				"Earth Baku ",
				"GREF",
				"Group 72 ",
				"Red Kelpie ",
				"TA415 ",
				"TG-2633 ",
				"Wicked Panda ",
				"Winnti"
			],
			"source_name": "Secureworks:BRONZE ATLAS",
			"tools": [
				"Acehash",
				"CCleaner v5.33 backdoor",
				"ChinaChopper",
				"Cobalt Strike",
				"DUSTPAN",
				"Dicey MSDN",
				"Dodgebox",
				"ForkPlayground",
				"HUC Proxy Malware (Htran)"
			],
			"source_id": "Secureworks",
			"reports": null
		}
	],
	"ts_created_at": 1775439036,
	"ts_updated_at": 1775826787,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/944a846fa1dff0aefb5b925f02b8480f0d16131c.pdf",
		"text": "https://archive.orkl.eu/944a846fa1dff0aefb5b925f02b8480f0d16131c.txt",
		"img": "https://archive.orkl.eu/944a846fa1dff0aefb5b925f02b8480f0d16131c.jpg"
	}
}