{
	"id": "91199e98-8a51-4fa1-bb4d-ced271993f33",
	"created_at": "2026-04-06T00:09:14.429825Z",
	"updated_at": "2026-04-10T13:12:50.07671Z",
	"deleted_at": null,
	"sha1_hash": "c589d0b60dbcddcd02590499a58f0d37c6d6c3a1",
	"title": "Summit Route - Investigating malicious AMIs",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 124338,
	"plain_text": "Summit Route - Investigating malicious AMIs\r\nArchived: 2026-04-05 16:29:55 UTC\r\nA few weeks ago a CVE appeared for the AWS CLI, CVE-2018-15869. The explanation is that if you don’t\r\nspecify an --owners flag when describing AMI images via the AWS CLI, you can end up with “potentially\r\nmalicious Amazon Machine Image (AMI) from the uncurated public community AMI catalog”.\r\nLinked from there is a Github issue where someone stated:\r\n“I encountered exactly this bug last week, ended up with a Monero miner instead of a vanilla Ubuntu\r\nAMI when the owner filter was missed.”\r\nThis post will investigate one of these malicious AMIs and introduce a new CloudMapper command amis to\r\nhelp you investigate your existing EC2s.\r\nInvestigating a malicious AMI\r\nSomeone privately told me they encountered this and had saved a copy of the AMI. They were kind enough to\r\nshare this with my account so I could investigate.\r\nNormally if you had a compromised EC2 running, you could take a snapshot, but in this case, I needed to actually\r\nstart the AMI as an EC2 in order to snapshot it so I could investigate it. I don’t believe it is possible to analyze an\r\nAMI without doing that. This was the first time I ran into the scenario of an AMI without an EC2 already running,\r\nand this process worked for this situation.\r\nGrabbing a snapshot by starting an AMI\r\nIf you do start a suspicious AMI as an EC2 as I did, ensure you do not give it an IAM role so it does not have any\r\nprivileges. You’ll also want to start it in an isolated VPC with a Security Group that does not allow it to call out.\r\nWhen you do local malware anlysis it is best practice to not have Internet access to avoid any indication that\r\nyou’re doing analysis, so I’m trying to recreate that here, even though I’ll only be running this instance for about a\r\nminute in order to create the snapshot.\r\nYou also should create it in a VPC that has enableDnsSupport disabled, as DNS is a possible beaconing path\r\neven when Security Groups are locked down. This is because by default DHCP on AWS tells instances to use\r\nAWS’s own DNS services at 169.254.169.253 , and traffic to/from 169.254.0.0/16 (the link-local range) can’t\r\nbe denied by Security Groups. That traffic is also not recorded in VPC Flow Logs, and you have no access to\r\nthose DNS logs, which is doubly annoying because the AWS GuardDuty service does have access to them.\r\nRanting about DNS and these oddities is a story for another day though. Back to DFIR!\r\nSo I go to start up the instance backed with this AMI, and oddly this AMI doesn’t support HVM virtualization,\r\nwhich means instead of using a free-tier t2.micro, I have to use an old-school t1.micro and pay a penny for the\r\nboot -\u003e snapshot -\u003e stop process. :(\r\nhttps://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nPage 1 of 5\n\nOnce running, in the web console, you can click on the Root device volume, then the EBS ID that pops up, then\r\nclick Actions -\u003e Create Snapshot. Then Stop the instance.\r\nAttaching the Snapshot\r\nOnce you have a snapshot, create a volume from it. Start up a new, trusted, EC2 instance, and attach this volume\r\nto it after it boots. I ran an Amazon Linux AMI. I then ssh’d in and ran lsblk which tells me the devices\r\nattached to the EC2, and then sudo mount /dev/xvdf /mnt . For those that have played my flaws.cloud CTF,\r\nyou’ll recognize this process from here in Level 4.\r\nFinding the malicious files\r\nJust like in flAWS, I decided to then look for recently created files, using find /mnt -type f -mtime 100 and\r\ndiscovered /etc/cron.d/root that contained the single line:\r\nInvestigating the malware\r\nThe .tk domains are free domains and almost all of them are malicious. I ran dig on that domain and found a\r\nsingle A record for 185.199.108.153 . Running whois on that IP shows it belongs to Github, so this must be\r\nhosted out of a repo. I searched on Github for that domain and found the Github repo\r\nhttps://github.com/tightsoft/tightsoft.github.io which contains that domain in a CNAME file. That repo shows me\r\nthe other malicious files and that it has been around for over a year, with 236 commits to it, so this appears to be\r\nthe central repo used by this actor.\r\nWhile searching for the domain, I also discovered that Palo Alto Networks had recently published a story about\r\nthis malware titled Xbash Combines Botnet, Ransomware, Coinmining in Worm that Targets Linux and Windows.\r\nYou can read their write-up to learn more about what the malware does (mines cryptocurrencies, asks for ransom\r\nmoney, and tries to exploit things to spread).\r\nThe actor seems to add look-alike domains for anyone that publishes stories on them as I’ve seen the domains\r\npaloaltonetworks[.]tk and threatpost[.]tk associated with this campaign. … So I guess I can expect that for my\r\ndomain. :(\r\nhttps://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nPage 2 of 5\n\nThe domain d.paloaltonetworks[.]tk was the only domain I found that was not directly tied to a Github repo, and\r\ninstead is hosted behind Cloudflare. The threatpost[.]tk Github repo is slightly different and is hosted on Github in\r\nthe aptly named repo https://github.com/freebtcminer/freebtcminer.github.io\r\nMalicious github repos download\r\nAs I’ve reported these repos to Github, I assume they’ll remove them, so I’ve collected these repos and saved a\r\ncopy in the password-protected zip file at http://summitroute-password-protected-malware-for-analysis.s3.amazonaws.com/infected_ami_research.zip\r\nThe password is: infect3d\r\nLooking for more infected AMIs\r\nThe person that provided this AMI to me did not know much about its origin unfortunately. They simply said they\r\nhad been alerted to the existance of a coin miner in their account and had traced it back to this AMI which they\r\nmade a copy of. This malware will attempt to exploit vulnerabilities associated with Hadoop, Redis, and\r\nActiveMQ, so one possibility is that the creator of this AMI had been a victim and had their system infected\r\nbefore they created the AMI. This AMI did have ActiveMQ installed on it.\r\nUpdate 2018.09.24: I removed a paragraph here regarding a misunderstanding on my part about AMI IDs.\r\nIn an email with aws-security@amazon.com, I received the response:\r\n“currently there are no infected Community AMIs to our knowledge and we are taking all necessary\r\nactions in regards to this issue.”\r\nI also received an email a few days ago from AWS informing me about a public EBS snapshot I have (part of\r\nflaws.cloud). I believe all AWS customers with public AMIs or EBS snapshots received this email, so it looks like\r\nAWS has taken some action to clean up their AMI and EBS snapshot marketplace.\r\nCampaign history\r\nI have the following dates to try to track down when this campaign started:\r\n2017-06-21: Github repo github.com/tightsoft/tightsoft.github.io created.\r\n2018-03-24: First cron logs recorded in instance, so this appears to the be the boot date of the instance.\r\n2018-04-17: Cron log shows repeated requests to download and execute lnk0[.]com/VhscA1 and\r\nlnk0[.]com/BtoUt4 I believe this must have been the original download server and this must have been\r\nwhen the instance was first exploited.\r\n2018-04-20: Creation date of /etc/cron.d/root on the malicious AMI, and also the cron log switches over to\r\ntrying to download and execute xmr.enjoytopic[.]tk/l2/r88.sh and x[.]co/6nPMR This is likely just the\r\nadversary changing how their malware works.\r\n2018-04-23: Last logs recorded, so this must have been when this instance was shutdown to create the\r\nAMI.\r\n2018-05-07: CNAME file created in the tightsoft github repo for xmr.enjoytopic[.]tk\r\nhttps://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nPage 3 of 5\n\n2018-08-13: The github issue appears where someone mentions they ended up with a malicious AMI.\r\n2018-09-14: CVE-2018-15869 is made public.\r\nAvoiding malicious AMIs\r\nYou should ensure you are running the latest version of the AWS CLI and other libraries to avoid CVE-2018-\r\n15869.\r\nYou should also ensure you are getting AMIs from trusted sources. You should have procedures for how new\r\nEC2s should be created, including what AMI’s they should use. This will also help you avoid problems of a\r\nfraction of your servers running Centos and another fraction running Ubuntu or some other combination of\r\noperating systems and features.\r\nAs a first step, you should identify the OS vendor you want to use and document their account ID so you can\r\nensure you get AMIs from that account. Eventually you’ll start creating your own AMIs, in which case you’ll\r\neither create the AMIs directly in the account where they’ll be used, or have a trusted account that you pull AMIs\r\nfrom. One philosophy, used by Netflix, advocates baking an AMI for every single code update as written in their\r\npost How We Build Code at Netflix.\r\nChecking your existing EC2s\r\nThe above advice is good for the future, but you already have existing EC2s and you might be wondering where\r\nthey came from? Don’t worry, Summit Route has your back. I’ve added a new command amis to Duo Security’s\r\nCloudMapper that will cross-check all of the AMI IDs for your EC2s with the private AMIs in your account and\r\nthe public AMIs that exist. You first need to get a copy of the public AMIs with:\r\nmkdir -p data/aws\r\ncd data/aws\r\naws ec2 describe-regions | jq -r '.Regions[].RegionName' | xargs -I{} mkdir {}\r\naws ec2 describe-regions | jq -r '.Regions[].RegionName' | xargs -I{} sh -c 'aws --region {} ec2 describe-images\r\nThen you can run the command. Here is some sample output from the flaws.cloud account:\r\n$ python cloudmapper.py amis --account flaws\r\nAccount Name Region Name Instance Id Instance Name AMI ID Is Public AMI Descriptio\r\nflaws us-west-2 i-05bef8a081f307783 None ami-7c803d1c public ubuntu/images/hvm-ssd/u\r\nThis is tab-deliminated so it looks nicer in Excel. You’ll see that it identifies all of the EC2 instances in the\r\naccount and their associated AMI IDs. It then determines if this is public , private , or unknown . The label\r\npublic means this is public AMI, and private means this AMI is owned by this account. Having an unknown\r\nAMI is fairly common as it means it is not private to this account and not currently public, so it may have been\r\npublic previously and removed, may have been privately created in this account and then removed, or may have\r\nbeen shared from another account. It will then attempt to find a description for the AMI, and finally lists the\r\nhttps://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nPage 4 of 5\n\naccount ID that this came from. In this case 099720109477 is the Ubuntu account’s ID. Unforrtunately, there is no\r\nway I know of to easily confirm that.\r\nI’ve found this command most useful when assessing accounts to do counts of what external accounts the AMIs\r\ncame from. You can sometimes find a single EC2 that was built from an AMI that came from an account that no\r\nother EC2s were built from. These are always interesting and worth further inspection.\r\nNote that both gathering the public AMIs and running this command can take a few minutes to complete. You can\r\ndownload a copy of the public AMI list I have from at public_amis-2018_09_22.tar.gz. This 92MB file will\r\ndecompress to 1.3GB.\r\nConclusion\r\nAmazon appears to have taken action to avoid this problem, but you should still take steps to ensure you are\r\ngetting your AMIs, or any resources in your supply chain, from trusted sources. I also reported my findings to\r\nGithub, CloudFlare, Amazon, and Palo Alto Networks, so hopefully this campaign will be further crippled.\r\nIOCs\r\nDomains used for downloading parts of the malware.\r\nlnk0[.]com/VhscA1\r\nlnk0[.]com/BtoUt4\r\nxmr.enjoytopic[.]tk - Points to https://github.com/tightsoft/tightsoft.github.io\r\nx[.]co/6nPMR\r\nd.paloaltonetworks[.]tk\r\nthreatpost[.]tk - Points to https://github.com/freebtcminer/freebtcminer.github.io/blob/master/CNAME\r\n3g2upl4pq6kufc4m[.]tk\r\ne3sas6tzvehwgpak[.]tk - Points to https://github.com/yj12ni/yj12ni.github.io\r\nsample.sydwzl[.]cn - Points to https://github.com/rocke/rocke.github.io\r\nSource: https://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nhttps://summitroute.com/blog/2018/09/24/investigating_malicious_amis/\r\nPage 5 of 5",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://summitroute.com/blog/2018/09/24/investigating_malicious_amis/"
	],
	"report_names": [
		"investigating_malicious_amis"
	],
	"threat_actors": [
		{
			"id": "7c053836-8f50-4d40-bc5c-7088967e1b57",
			"created_at": "2022-10-25T16:07:24.549525Z",
			"updated_at": "2026-04-10T02:00:05.03048Z",
			"deleted_at": null,
			"main_name": "Rocke",
			"aliases": [
				"Aged Libra",
				"G0106",
				"Iron Group",
				"Rocke"
			],
			"source_name": "ETDA:Rocke",
			"tools": [
				"Godlua",
				"Kerberods",
				"LSD",
				"Pro-Ocean",
				"Xbash"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "eb3f4e4d-2573-494d-9739-1be5141cf7b2",
			"created_at": "2022-10-25T16:07:24.471018Z",
			"updated_at": "2026-04-10T02:00:05.002374Z",
			"deleted_at": null,
			"main_name": "Cron",
			"aliases": [],
			"source_name": "ETDA:Cron",
			"tools": [
				"Catelites",
				"Catelites Bot",
				"CronBot",
				"TinyZBot"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "905eabd9-2b7f-483d-86bd-0c72f96b4162",
			"created_at": "2023-01-06T13:46:39.02749Z",
			"updated_at": "2026-04-10T02:00:03.185957Z",
			"deleted_at": null,
			"main_name": "Rocke",
			"aliases": [
				"Aged Libra"
			],
			"source_name": "MISPGALAXY:Rocke",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "0b02af5f-2027-42b7-a6f2-51e2fd49ba7f",
			"created_at": "2022-10-25T15:50:23.360509Z",
			"updated_at": "2026-04-10T02:00:05.337702Z",
			"deleted_at": null,
			"main_name": "Rocke",
			"aliases": [
				"Rocke"
			],
			"source_name": "MITRE:Rocke",
			"tools": null,
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434154,
	"ts_updated_at": 1775826770,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/c589d0b60dbcddcd02590499a58f0d37c6d6c3a1.pdf",
		"text": "https://archive.orkl.eu/c589d0b60dbcddcd02590499a58f0d37c6d6c3a1.txt",
		"img": "https://archive.orkl.eu/c589d0b60dbcddcd02590499a58f0d37c6d6c3a1.jpg"
	}
}