{
	"id": "230b633a-2608-4370-ac5d-6ee5ef0cde3f",
	"created_at": "2026-04-06T00:11:41.947482Z",
	"updated_at": "2026-04-10T03:23:51.377788Z",
	"deleted_at": null,
	"sha1_hash": "97084f1cf36e5dcc9bc2381122a9135e9d848e1a",
	"title": "Incident report: From CLI to console, chasing an attacker in AWS",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 589614,
	"plain_text": "Incident report: From CLI to console, chasing an attacker in AWS\r\nBy Britton Manahan, David Blanton, Kyle Pellett, Brian Bahtiarian\r\nPublished: 2022-04-05 · Archived: 2026-04-05 17:34:07 UTC\r\nRecently, our SOC detected unauthorized access into one of our customer’s Amazon Web Services (AWS)\r\nenvironments. The attacker used a long-term access key to gain initial access. Once they got in, they were able to\r\nabuse the AWS Identity and Access Management (IAM) service to escalate privileges to administrative roles and\r\ncreate two new users and access keys — creating a foothold in their environment. However, we stopped them\r\nbefore the attacker was able to get any further.\r\nIn this post, we’ll walk you through how we spotted unauthorized access, the investigative steps we took to\r\nunderstand what the attacker did in AWS, and share our lessons learned and key takeaways from the incident.\r\nQuick background\r\nBefore we tell you how it went down, for this customer we’re ingesting AWS CloudTrail logs and applying our\r\nown custom detections. This customer did not have AWS GuardDuty enabled for their monitored AWS accounts\r\n— nor did we have any visibility beyond the AWS control plane.\r\nOur initial lead\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 1 of 6\n\nOur first clue into the incident was an AWS alert based on CloudTrail logs for a console login from an IAM user\r\noriginating from an atypical country.\r\nFrom the AWS alert (screenshot below), our SOC was able to extract the following details about the console login:\r\nThe authentication originated from Indonesia\r\nThe type of AWS account was an IAM user\r\nMulti-factor authentication (MFA) was not used for the authentication\r\nThe details about the AWS console login prompted our SOC to ask the following questions:\r\nDoes this IAM user typically login from Indonesia?\r\nWhy is this IAM user authenticating to the console directly and not via an identity provider?\r\nWhy wasn’t MFA used?\r\nThese questions combined certainly raised our suspicion.\r\nSOC pro-tip: IAM accounts typically have long-term access keys associated with them. You’ll see these long-term\r\naccess keys start with “AKIA.” Most of the AWS incidents we detect were the result of a publicly exposed long-term access key.\r\nThe first step in our investigative process was to understand what happened after the successful AWS console\r\nlogin. We used one of our bots, Ruxie™, to gain some more insight. As a quick refresher, our robot Ruxie (yes –\r\nwe give our robots names) automates investigative workflows to surface up more details to our analysts.\r\nWe used Ruxie to list the most recent interesting API calls from the AWS account in the initial lead (interesting in\r\nthis context is mostly anything that isn’t Get*, List*, Describe*, and Head*). API calls that are sometimes\r\nassociated with attacker activities in AWS are highlighted in orange. We highlight these actions in orange to\r\nprovide a visual cue to our analysts that something may be amiss here.\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 2 of 6\n\nThe list of API calls returned by Ruxie showed us that the source IP address associated with the atypical console\r\nlogin also issued API calls to CreateUser, CreateAccessKey, and AttachUserPolicy. For the AWS defenders out\r\nthere, it’s important to note that AWS accounts are assigned temporary access keys when authenticating to the\r\nAWS console (these access keys typically start with “ASIA”).\r\nNow this activity really has our attention. But why?\r\nThe CreateUser API call is used to create a new IAM user. The CreateAccessKey API call creates a new long-term\r\naccess key for a specific user. AttachUserPolicy attaches a specified policy to a specified user.\r\nTherefore, an attacker can use these API calls to:\r\nCreate a new IAM user\r\nCreate a new long-term access key for the user\r\nAttach a highly privileged policy to the user for elevated access\r\nThis series of API calls can give an attacker persistent and elevated access in an AWS environment — yep, this\r\nactivity certainly has our attention.\r\nThe next question our SOC asked was, “where does this IAM user typically authenticate from?” Ruxie to the\r\nrescue. Ruxie provided our analysts with a list of login activity by region and frequency for the IAM user listed in\r\nour lead alert.\r\nBottom line? Logins from Indonesia are highly suspicious.\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 3 of 6\n\nRecently authenticated regions Ruxie action for the source IAM user\r\nOK, so at this point we have an IAM user logging in to the AWS console, from a location we’ve confirmed is\r\natypical, and that account is issuing API calls to create new users, long-term access keys, and to attach highly\r\nprivileged policies to users for elevated access.\r\nAt this point our SOC declared an incident, issued a recommendation to our customer to reset the\r\n(arn:aws:iam::123456789012:user/comp_user1) account credentials, and in parallel began working to answer:\r\nHow did the attacker obtain AWS console creds?\r\nWhat else did the attacker do in AWS?\r\nHow did the attacker obtain AWS console creds?\r\nThe next step in our investigative process was to get a more detailed timeline of all AWS API calls issued by the\r\nsource IP address associated with the lead alert for the console login. This investigative step helps us better\r\nunderstand the actions performed by the attacker.\r\nAPI calls in AWS triage timeline\r\nWhen examining the detailed timeline of API calls, the attacker first issued a ListUsers API call using the\r\narn:aws:iam::123456789012:user/comp_user2 IAM user from the AWS command line interface (aws-cli). Note\r\nthat this is a different IAM user from the lead alert. We inferred the\r\narn:aws:iam::123456789012:user/comp_user2 IAM user was also compromised since the API call originated\r\nfrom the same IP address recorded in the console login. More on this in a second.\r\nNext, the attacker issued two calls to the UpdateLoginProfile API; one for the\r\narn:aws:iam::123456789012:user/comp_user1 IAM user (succeeded) and one for the\r\narn:aws:iam::123456789012:user/comp_user2 IAM user (failed with the NoSuchEntityException reason).\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 4 of 6\n\nFinally, CloudTrail logs recorded a ConsoleLogin from the arn:aws:iam::123456789012:user/comp_user1\r\naccount.\r\nSo as a quick recap, our investigation revealed the attacker took the following steps to gain access to the AWS\r\nconsole:\r\nUsed the AWS access keys for arn:aws:iam::123456789012:user/comp_user2 to issue a ListUsers API\r\ncall.\r\nThe results of the ListUsers API call returned arn:aws:iam::123456789012:user/comp_user1 in\r\nthe results.\r\nIssued an API call to UpdateLoginProfile to change the AWS console password for the\r\narn:aws:iam::123456789012:user/comp_user1 account.\r\nAuthenticated into the AWS console using the arn:aws:iam::123456789012:user/comp_user1 account.\r\nIt’s our working theory that the AWS access keys for the arn:aws:iam::123456789012:user/comp_user2 account\r\nwere discovered by the attacker in a publicly available code repository.\r\nWhat else did the attacker do in AWS?\r\nSOC pro-tip: At this point in our investigation, CloudTrail logs indicate the attacker has access to the AWS\r\nconsole for this customer. Therefore, we’re expecting to see attacker activity recorded from different IP addresses\r\nassociated with AWS. (Don’t exclude these in your search!)\r\nImmediately following the authentication to the AWS console, the attacker issued the following API calls:\r\nCreateUser\r\nCreateAccessKey\r\nAttachUserPolicy\r\nCreateLoginProfile\r\nThis allowed the attacker to create two new IAM users with accompanying long-term access keys and attached a\r\npolicy that allowed one of the new users to create and change their AWS console password. For one of the newly\r\ncreated IAM user accounts, the attacker issued an AttachUserPolicy API call to attach an AdministratorAccess\r\npolicy to the newly created IAM user — allowing the attacker to elevate their privileges in AWS.\r\nLastly, the attacker used one of the newly created IAM users to make a call to the RequestServiceQuotaIncrease\r\nAPI in order to increase the EC2 quota. It’s our opinion that this action was taken in preparation for starting\r\nmultiple large EC2 instances for cryptocurrency mining. It is at this point that we worked with the customer to\r\nbegin remediation.\r\nCrisis averted!\r\nHere’s the final play-by-play of the actions taken by the attacker in AWS mapped to the MITRE ATT\u0026CK\r\nframework:\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 5 of 6\n\nMITRE tactics mapped to AWS API calls\r\nYou can check out additional AWS API calls we’ve seen associated with attacker activity in our AWS mind map.\r\nWith the scope of the compromise understood, we provided our customer with the following remediation\r\nrecommendations:\r\n1. Delete the two created accounts and accompanying access keys for\r\narn:aws:iam::123456789012:user/created_user1 and arn:aws:iam::123456789012:user/created_user2\r\n2. Deactivate the long term access keys associated with the arn:aws:iam::123456789012:user/comp_user1\r\nand arn:aws:iam::123456789012:user/comp_user2 IAM users\r\n3. Reset the AWS console password for the arn:aws:iam::123456789012:user/comp_user1 and\r\narn:aws:iam::123456789012:user/comp_user2 IAM users\r\nWe also recommended that the customer ensure AWS access keys are not being accidentally released to the public\r\nand implement least privilege with regards to AWS users. Additionally, we recommended the customer implement\r\nMFA for IAM user AWS console authentications.\r\nLessons learned\r\nWhat stood out the most in this incident was the attacker’s technique to use an exposed long-term access key to\r\ngain access to the AWS console — potentially for ease of access and persistence. Simply put, the attacker wants to\r\ngo from the aws-cli to the AWS console. To achieve this, the attacker issued API calls UpdateLoginProfile or\r\nCreateLoginProfile from an IAM user. We now have a detection based on CloudTrail logs that alerts our SOC\r\nanytime we see these specific API calls originating from an IAM user where the User-Agent is the aws-cli. We’ve\r\nadded some additional logic to reduce benign noise associated with AWS IP addresses.\r\nWe’re also exploring additional detections based on CloudTrail logs where we see newly created IAM users issue\r\nAPI calls to RequestServiceQuotaIncrease to increase the EC2 quota. This could be a signal of potential\r\nunauthorized activity in EC2.\r\nWhile we detected unauthorized activity early in the attack lifecycle, we’re a learning organization and always\r\nlooking for opportunities to improve our detection and response capabilities in AWS.\r\nSource: https://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nhttps://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://expel.com/blog/incident-report-from-cli-to-console-chasing-an-attacker-in-aws/"
	],
	"report_names": [
		"incident-report-from-cli-to-console-chasing-an-attacker-in-aws"
	],
	"threat_actors": [
		{
			"id": "d90307b6-14a9-4d0b-9156-89e453d6eb13",
			"created_at": "2022-10-25T16:07:23.773944Z",
			"updated_at": "2026-04-10T02:00:04.746188Z",
			"deleted_at": null,
			"main_name": "Lead",
			"aliases": [
				"Casper",
				"TG-3279"
			],
			"source_name": "ETDA:Lead",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"RbDoor",
				"RibDoor",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434301,
	"ts_updated_at": 1775791431,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/97084f1cf36e5dcc9bc2381122a9135e9d848e1a.pdf",
		"text": "https://archive.orkl.eu/97084f1cf36e5dcc9bc2381122a9135e9d848e1a.txt",
		"img": "https://archive.orkl.eu/97084f1cf36e5dcc9bc2381122a9135e9d848e1a.jpg"
	}
}