Latest News: Binary Defense Launches “MDR Plus” — A New Holistic Approach to Advanced Threat Management

Get Informed

Search

Threat Hunting AWS CloudTrail with Sentinel: Part 3

Detecting Backdoor Attacks

By Sean Fernandez | Threat Researcher | Binary Defense

In part 3 of the blog series, Threat Hunting AWS CloudTrail with Sentinel, we simulated a series of adversary attacks focusing on persistence with backdoor access to a secondary access key and temporary security credentials. The attacks were deployed on our test AWS environment that emulated a small organization with a set of users, roles, groups, and policies. We utilized 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 Ssentinel and most importantly the way we can detect threat activity with KQL queries, which can be applied in your own threat hunts.

Attack 01: Attacker Creates a Secondary Access Key for an IAM User

In this scenario, the threat actor has valid credentials and has authenticated via the AWS CLI as the ‘AWSCloudAdmin’ user. The attack commands will operate within the AWScloudAdmin context. Next, the actor will enumerate the account for users and access keys. The actor then targets the ‘BackupAdmin’ and lists the active keys for the user. After determining that the ‘BackupAdmin’ has one active primary access key, a secondary set is created.

Prereq:

Before initiating the attack, the AWS CLI must be installed and configured with the AWS default profile using:

 ~$ aws configure

Attack Commands:

// enumerate IAM users
~# sudo aws iam list-users --AWSCloudAdmin 
 class=
// enumerate active keys 
// Determine if the target has one or two active keys
~$ sudo aws iam list-access-keys --user-name BackupAdmin --profile AWSCloudAdmin
 class=
Displays the user has one access key

// Create a new access key for the target user 
~$ sudo aws iam create-access-key --user-name BackupAdmin --profile AWSCloudAdmin
 class=
// Lists active keys
~$ sudo aws iam list-access-keys –user-name BackupAdmin –profile AWSCloudAdmin
 class=

The threat actor successfully created a secondary access key and now has a backdoor authentication method for the IAM ‘BackupAdmin’ account. This also provides a secondary option to authenticate if access was lost to the primary keys.

Attack 02: Backdoor Access and Privilege Escalation with Temporary Credentials

In this attack, the threat actor abuses an AWS AssumeRole policy that assigns temporary token credentials, which can also grant access to additional resources within the account.

The diagram below illustrates how the actor makes the API call to the Security Token Service (STS) and receives temporary, limited-privilege credentials.

 class=

For this attack, we leveraged the open-source AWS security-testing kit, Pacu from Rhino Security Labs.

Pacu was designed for offensive security testing against cloud environments and exploits configuration flaws within an AWS account.

Attack Commands:

// Launch Pacu 
~$ sudo python3 cli.py

// named the session
Pacu> backdoor
 class=
// Imports keys from the AWSCloudAdmin account 
// Any commands run within Pacu will operate within the AWScloudAdmin context 
Pacu> import_keys AWSCloudAdmin
 class=
Note: We utilized the commands detailed below to populate user information in Pacu. Otherwise, the information fields would show up empty.
Pacu> run iam__enum_users_roles_policies_groups
Pacu> run iam__enum_permissions
 class=
Pacu> whoami
 class=
Note: AWScloudAdmin user has the ‘AdministratorAccess’ policy
// Pacu iam_backdoor_assume_role module
// Attempts to locate a policy to backdoor 
Pacu> run iam_backdoor__assume_role
 class=
The ‘Admin’ and ‘Administrators’ role policies were located and successfully backdoored.
 class=
// lists the backdoored policies 
~$ sudo aws iam get-role --role-name Administrators --profile AWSCloudAdmin 
 class=

Successfully executed, the threat actor can call on the policy that will assign temporary security credentials as a means of backdoor access and privilege escalation.

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 access key creation

Query filters: CreateAccessKey and UserIdentityUserName
AWSCloudTrail 
| where EventName in ("CreateAccessKey", " UserIdentityUserName ")
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
 class=
 class=
Filertering on CreateAccessKey and UserIdentityUserName reveals that the IAM “AWSCloudAdmin” user created access keys for the BackupAdmin user.

Hunting for AWS account enumeration

Query filters: ListAccessKeys, ListUsers, ListGroups, ListRolePolicies

AWSCloudTrail 
| where EventName in ("ListAccessKeys", "ListUsers", "ListGroups", "ListRolePolicies", "GetCallerIdentity")
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
 class=
 class=
 class=
Filerting on ListAccessKeys, ListUsers, ListGroups, ListRolePolicies, revelaed that the enumeration commands were invoked on the IAM “AWSCloudAdmin” account.

Hunting for suspicious user agents

Query filters: “Kali”

AWSCloudTrail 
| where UserAgent has "kali"
| distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
| sort by TimeGenerated asc
 class=
 class=
Filtering on the “UserAgent” reveals that the attack came from a Kali Linux OS with the AWSCloudAdmin user.

Hunting for created roles

Query filters: CreateRole

// Investigate created roles and who created them  
AWSCloudTrail 
| where ReqeustParameters has “CreateRole” 
| sort by TimeGenerated asc 
 class=
 class=
Filter on “CreateRole” reveals that the AWSCloudAdmin created a role.

Hunting for a role added to an instance profile

Query filters: AssumeRole and UserIdentityUserName

// Investigate role added to the instance profile 
AWSCloudTrail 
| where UserIdentityUserName == "AWSCloudAdmin"
| where RequestParameters has "AssumeRole"
| sort by TimeGenerated asc 
 class=
 class=
Filtering on AssumeRole and UserIdentityUserName reveals that role was attached to the AWSCloudAdmin.

Hunting for a specific role

Query filters: UserIdentityUserName, GetRole, RequestParameters

// Investigating specific API activity  
AWSCloudTrail
| where UserIdentityUserName == "AWSCloudAdmin"
| where EventName has "GetRole"
| where RequestParameters has "Administrators"
| sort by TimeGenerated asc
 class=
 class=
Further investigation revealed that IAM user AWSCloudAdmin has the attached “Administrators” role. 

Conclusion

SOC analysts managing cloud SEIM assets should set detections on enumeration commands, which create a lot of noise during the threat actor’s information harvesting phase. Additional malicious indicators can include accounts created from unrecognized IPs, different city/state, country from admin(s) and abnormal user hours. Detections can also monitor the threshold for allotted admins on an account.

In order to effectively detect these attacks, SOC Analysts can alert on the events we investigated and build custom detections for your environment.

The API actions logged in our simulation include: 

  • GetRole
  • AssumeRole
  • CreateRole
  • ListAccessKeys
  • CreateAccess
  • ListUsers
  • ListGroups
  • ListRolePolicies

Utilizing test environments to run adversary simulations can generate useful data, which can be further analyzed through hunting queries that can expose suspicious activities. Mitigating found flaws and incidents can provide metrics for prioritizing event logs in cloud. Build baselines and tune false positives to more effectively monitor cloud assets.

In our next blog, we’ll look at Atomic Red Team Attacks with “Atomics” built specifically for AWS.