Emulations

SWAT (Simple Workspace ATT&CK Tool) is a modular command-line tool that not only supports the execution of various commands but also offers the ability to emulate adversarial behaviors in the Google Workspace environment. This guide dives into the structure and creation of SWAT emulations.

Prerequisites

Before you dive into creating or understanding emulations in SWAT, ensure you have:

  • Familiarity with the argparse module in Python.

  • Understanding of the SWAT architecture, especially base_emulation.py.

  • Necessary API credentials or configurations for any external service your emulation will be integrating with.

Understanding the BaseEmulation Class

The BaseEmulation class is the foundational component for all SWAT emulations. It ensures:

  • Consistency: Every emulation inherits the same set of base properties and methods.

  • Emulation Inheritance: Allows emulations to inherit from the BaseEmulation class and leverage its functionalities.

  • BaseCommand Inheritance: Allows emulations to inherit from the BaseCommand class and leverage its functionalities via the obj object.

  • Argparse configurations: Allows emulations to define and parse command-line arguments.

  • Sets up an artifacts folder: Ensures a directory for storing artifacts generated by the emulation.

  • Logging capabilities: Provides a uniform logging format for all emulations via the elogger object.

  • (Any other functionality provided by the BaseEmulation class that might be relevant).

BaseEmulation Class

This class stands as SWAT’s emulation core. Every new emulation should extend from this class. Key attributes and methods include:

  • Initialization: Sets up attributes like logging, emulation configuration, and ATT&CK data.

  • execute method: Needs to be implemented in each emulation for defining logic.

  • get_attack method: For extracting tactics and techniques from class path.

  • exec_str method: Gives a uniform format for logging emulation activities.

  • help method: Provides a user-friendly help content.

  • load_parser method: Utility to fetch a custom parser.

  • load_emulation_config method: Loads a YAML configuration for the emulation.

  • setup_artifacts_folder method: Ensures a directory for artifacts.

BaseEmulation Class
class BaseEmulation:
    ...

Emulation Structure

BaseEmulation Inheritance

All emulations in SWAT inherit from the BaseEmulation class, guaranteeing a consistent interface and shared functionalities across different emulations:

class Emulation(BaseEmulation):
    ...

Techniques and Metadata

Every emulation is associated with one or more MITRE ATT&CK techniques. Additionally, each emulation has a name, scopes, and services associated with it:

techniques = ['T1552.004']
name = 'Access Stored Keys and Tokens in Drive'
scopes = ['drive.file','drive.readonly','drive']
services = ['drive']

Initialization Method

Emulations generally require an initialization method, where they set up services, assign values to the emulation, and parse any provided arguments:

def __init__(self, **kwargs) -> None:
    super().__init__(**kwargs)
    ...

Argparse in Emulations

Emulations leverage the argparse module to accept necessary parameters:

parser = BaseEmulation.load_parser(description='Description here')
parser.add_argument('argument_name', help='Argument description')
...

Execute Method

Every emulation must implement the execute method, which defines the logic for the emulation and is called by the emulate command:

def execute(self) -> None:
    ...
...

Dynamic Loading

Emulations, like commands, are dynamically loaded from their respective directory in SWAT, which allows for runtime importation and execution. This is achieved by using the within emulate.py file/command where load_emulation_class() is called to load the emulation class and execute() is called to run the emulation.

Error Handling and Logging

Just like commands, emulations inherit logging capabilities. When developing your emulation:

  • Log any crucial steps, errors, or exceptions.

  • Use the elogger object to log errors and exceptions.

  • Handle exceptions with try-except blocks to ensure stability.

  • Set the logging levels appropriately.

Adding a New Emulation

One of SWAT’s unique offerings is the ability to perform emulations, which help simulate adversarial behaviors in Google Workspace. In this guide, we’ll walk you through the process of adding a new emulation, called hello_world_email, which sends a “Hello World” email to a specified user via the Gmail API.

Full emulation code example
from googleapiclient.discovery import build
from ..emulations.base_emulation import BaseEmulation
from ..misc import validate_args
import base64

class Emulation(BaseEmulation):

    parser = BaseEmulation.load_parser(description='Send a Hello World email to specified user.')
    parser.add_argument('session-key', type=str, help='Validated authentication session from Credential Store')
    parser.add_argument('--recipient', type=str, help='Email address of the recipient')

    techniques = ['T1566.001']  # Phishing technique from MITRE ATT&CK
    name = 'Send Hello World Email'
    scopes = ['gmail.send']
    services = ['gmail']

    def __init__(self, **kwargs) -> None:
        super().__init__(**kwargs)
        self.args = validate_args(self.parser, self.args)
        self.session = self.obj.cred_store.store[self.args.session_key].session
        self.service = build('gmail', 'v1', credentials=self.session)

    def send_hello_email(self):
        '''Send a Hello World email to the specified recipient.'''
        raw_email = self.create_raw_email()
        result = self.service.users().messages().send(userId='me', body={'raw': raw_email}).execute()
        self.elogger.info(f"Email sent to {self.args.recipient} with message Id: {result['id']}")

    def create_raw_email(self):
        '''Generate the raw email content.'''
        message = f"Subject: Hello from SWAT\n\nHello World!"
        return base64.urlsafe_b64encode(message.encode()).decode()

    def execute(self) -> None:
        '''Main execution method.'''
        self.send_hello_email()

Example Walkthrough:

  1. Create a new file: In the SWAT directory, create a file named hello_world_email.py inside the swat/emulations/initial_access/ directory.

    touch swat/emulations/initial_access/hello_world_email.py
    
  2. Add necessary imports: Include the essential modules and classes at the beginning of the hello_world_email.py file.

    from googleapiclient.discovery import build
    from ..emulations.base_emulation import BaseEmulation
    from ..misc import validate_args
    import base64
    
  3. Define the Emulation Class: Begin by defining the Emulation(BaseEmulation) class.

    class Emulation(BaseEmulation):
        ...
    
  4. Argparse Configuration: Set up argparse to accept the recipient’s email address.

    parser = BaseEmulation.load_parser(description='Send a Hello World email to specified user.')
    parser.add_argument('session', type=str, help='Validated authentication session from Credential Store')
    parser.add_argument('recipient', type=str, help='Email address of the recipient')
    ...
    
  5. Techniques and Metadata: Define the techniques, name, scopes, and services associated with the emulation.

    techniques = ['T1566.001']
    name = 'Send Hello World Email'
    scopes = ['gmail.send']
    services = ['gmail']
    ...
    
  6. Initialization Method: Add the __init__ method, inherit properties from BaseEmulation, and set up the Gmail API service.

    def __init__(self, **kwargs) -> None:
        ...
    
  7. Execution Method: Implement the execute() method, which calls the send_hello_email() method.

    def execute(self) -> None:
        ...
    
  8. Implement Emulation Logic: Write methods that handle email creation and sending.

    def send_hello_email(self):
        ...
    
    def create_raw_email(self):
        ...
    
  9. Test Your Emulation: Start SWAT and run your new emulation to ensure it behaves as expected. Remember that you’ll need to provide a valid session key and recipient email address. Visit Authentication with GCP for more information on authentication/authorization.

    emulate hello_world_email default <recipient_email>
    

Recommendations for Enhanced Emulations

  1. Emulation Context: Expand the AttackData dataclass to include details like adversary groups or related software/tools.

  2. Enhanced Error Handling: Add comprehensive error handling, especially where ATT&CK data is involved.

  3. Configuration Management: Allow dynamic settings or thresholds with the load_emulation_config method.

  4. Post-Execution Clean-up: Add cleanup methods post-execution, if required.

  5. Document & Comment: Maintain comprehensive documentation for every function and method.

  6. Testing: Ensure robust tests for the base class since it’s foundational.

Conclusion

Emulations are instrumental in emulating adversarial behaviors in a controlled environment. They provide real-world insights into potential threats, assisting cybersecurity professionals in understanding, analyzing, and fortifying their defenses.