Section 4: Detecting AWS Atomic Red Team Attacks
By Sean Fernandez | Threat Researcher | Binary Defense
In part 4 of our series on Threat Hunting AWS CloudTrail with Sentinel, we simulated three Atomic Red Team Attacks with “Atomics” built specifically for AWS. The attacks were deployed on a test AWS environment that emulated a small organization with a set of users, roles, groups, and policies. We utilized Microsoft Sentinel to gather raw event information and to analyze the logs produced during the simulation.
We’ll walk through the steps to conduct the simulation, how to analyze the logs uncovered by Sentinel, and most importantly, the way we can detect threat activity with KQL queries, which can be applied in your own threat hunts.
Attack 01: Create A New AWS IAM User
In this scenario, the adversary has already gained a foothold on the target cloud account by stealing an API key from a developer or source code repository. The attacker would first authenticate with stolen keys via the AWS CLI, where attack commands will be carried out
The adversary has gained initial access using programmatic keys from the admin user “Jacko.”. The attack creates a new IAM user with the name “atomicredteam.” –(It is important to note that in a real scenario the adversary would potentially create a username that would better blend with other users, which may go unnoticed.)
Prereq:
Before initiating the attack, the AWS CLI must be installed and configured with the AWS default profile using:
~$ aws configure
Attack Commands: Run with sh
!
aws iam create-user --user-name #{username}
1: Install Invoke-AtomicRedTeam
// installed the Invoke-AtomicRedTeam Execution framework from the PowerShell prompt
PS /root> IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing);
Install-AtomicRedTeam
// creates the new IAM user “atomicredteam”
PS /root/AtomicRedTeam> Invoke-AtomicTest -PathToAtomicsFolder /root/AtomicsRedTeam/atomics/ T1136.003
After the attack was completed, the “atomicredteam” is listed as a IAM user in our test environment.
Attack 02: Create an Access Key and a Secret Key in AWS – T1098.001
The screenshot below displays that the “atomicredteam” user has a field without an Access key ID before the simulation was carried out.
In order to interact with the AWS environment using the AWS CLI, an access key and secret key are created for the new IAM user with the previously compromised admin account.
Attack Commands: Run with sh
!
aws iam create-access-key --user-name #{username}
// creates a new access key for the atomicredteam user
PS /root/AtomicRedTeam> Invoke-AtomicTest -PathToAtomicsFolder /root/AtomicsRedTeam/atomics/ T1098.001 -TestNumbers 3
// creates a new access key for the atomicredteam user
PS /root/AtomicRedTeam> Invoke-AtomicTest -PathToAtomicsFolder /root/AtomicsRedTeam/atomics/ T1098.001 -TestNumbers 3
Returning back to our test environment displays that the attack successfully created an Access key for the “atomicredteam” user.
Attack 3: Create a group and add a user to the group in AWS – T1098
Using the same admin account, the threat simulation creates a new AWS group and adds the “atomicredteam” user to the specific group. The adversary creates groups to elevate their privileges to gain additional access to the environment.
Attack Commands: Run with sh
!
aws iam create-group --group-name #{username}
aws iam add-user-to-group --user-name #{username} --group-name #{username}
Before conducting the simulation, the screenshot displays three user groups in our test environment.
// creates a new group
// adds the atomicredteam user to the group
PS /root/AtomicRedTeam> Invoke-AtomicTest -PathToAtomicsFolder /root/AtomicsRedTeam/atomics/ T1098
After successfully executing the attack, the new group “atomicredteam” is listed in our test environment.
Additionally, the “atomicredteam” user was added to the “atomicredteam” group
Hunting CloudTrail Logs in Sentinel with KQL Queries
The following is a breakdown of our CloudTrail log analysis and hunting process of the API calls during our simulation.
The CloudTrail logs ingested into Sentinel were first analyzed with basic KQL queries. To further narrow in on the attacks, more specific queries were executed.
Hunting for suspicious source IP accessing AWS Services
Query filters: SourceIpAddress
AWSCloudTrail
| summarize count() by SourceIpAddress
Hunting for suspicious user agents
Query filters: “Kali”
AWSCloudTrail
| where UserAgent has "kali"
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
Hunting for suspicious API Activities
Query filters: UserIdentityUserName
AWSCloudTrail
| where UserIdentityUserName =="Jacko"
| where EventName !startswith “List” and EventName !startswith “Descrirbe” and EventName !startswith “Get” and EventName !startswith “Lookup”
| summarize count(), min(TimeGenerated), max(TimeGenerated) by EventSource, EventName
Hunting for actions taken by AWS admin users
Query filters: UserIdentityUserName
// investigating admin activity
AWSCloudTrail
| where UserIdentityUserName in ("AWSCloudAdmin", "BackupAdmin", "Jacko")
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
The logs display that the admin user “Jacko” was the only admin user active in the timeframe under investigation and created a new IAM user named “atomicredteam” and also created an “access key” for the new user.
Hunting all activity related to the new IAM user
Query filters: RequestParameters
// investigating new user actions
AWSCloudTrail
| where RequestParameters contains "atomicredteam"
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
The logs revealed that the “atomicredteam” IAM user was added to a newly created group
Hunting for access key creation
Query filters: CreateAccessKey
// Check Specific API – CreateKeyPair detail
AWSCloudTrail
| where EventName in ("CreateAccessKey") and isempty(ErrorMessage) and UserIdentityUserName == 'Jacko'
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
After analyzing the above logs with the KQL queries, you can begin to correlate events by filtering your search to the most interesting data. The final KQL query searches for API calls made from AWS user “Jacko” that created a new user, access key and group.
Hunting for IAM user account creation, access key creation and group creation
Query filters: CreateUser, CreateAccessKey, CreateGroup
AWSCloudTrail
| where UserIdentityUserName == 'Jacko'
| where EventName in ("CreateUser","CreateAccessKey", "CreateGroup") and isempty(ErrorMessage)
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
Conclusion
Using adversary emulation generates useful data, which can shorten the gap of the skills needed to effectively monitor cloud assets for defenders. Using hunting queries can expose suspicious activities in the generated logs and can serve as a good guide in building detections.
For SOC analysts managing cloud SEIM assets, alert on new IAM users created. To investigate, look for any suspicious activity leading up to account creation. An attacker can create a lot of noise running automated tools within a short period of time. Alert on access key creation as many IAM users do not need or have programmatic keys to interact with AWS resources. Investigate group creation and attached polices that may elevate privileges.
SOC analysts should use adversary simulations to signal on important events for cloud, which could help tune false positives. Additionally, work through some incidents and investigations specific to the cloud to build metrics to grow from over a course of time. Using these metrics can add context for defining priorities that will help drive down false positives.