email info@BC-Security.org

Top Categories

Spotlight

todayOctober 10, 2024

Offensive Security Tools Cx01N

Not Your Grandfather’s Empire

Not Your Grandfather’s Empire I’ve wanted to put this blog together since returning home from DEFCON. Anytime we ran into someone who recognized our swag, they mentioned how much they loved Empire back in the day and didn’t realize it was being actively maintained. This made me reflect on all [...]


Get Organized with Starkiller’s Tagging Feature

Offensive Security Tools Vincent Rose todayJuly 10, 2023 492 1

Background
share close

Forget about feeling overwhelmed with a mess of data. With tags in Starkiller, you have more control over keeping everything organized. You can assign tags to various objects – Listeners, Agents, Agent Tasks, Plugin Tasks, Downloads, and Credentials. This means you can categorize and organize your engagements in a way that makes sense to you. 

Tags are for you. Come up with your own system of organizing and color-coding your engagement data. Tags help you quickly identify and access the information you need without any hassle. When writing your reports, make tracking down key moments of your engagement easier by tagging the important agent tasks.

Tags are for your team. Use tags to communicate metadata about an object to your team, such as adding a tag to a credential indicating that it’s been successfully used. By assigning relevant tags to shared objects, you can make sure your whole team is on the same page. Everyone can easily find and work with the resources they need. Most of the objects that support tagging also support using those tags as filters on their data table pages.

Tags are for plugins. Do you have a custom plugin that executes tasks on agents automatically? Have it add a tag to those tasks to indicate where they came from to create clear associations and context. Have a plugin that should only execute on a set number of agents? Add a hook to the tag creation event for a new way to trigger plugins. Creating and updating tags trigger an event that plugins can listen to.

Let’s look at a very simple example plugin. We will call it the Preplanned Task Plugin for lack of a better name. This plugin will work based on the “hooks” feature added to Empire. See the Empire Wiki for more info on how that works.

This is the most basic code needed to execute our plugin. We will leave the execute function empty because we don’t actually need to manually trigger anything. It will all be based on the events. In the onLoad block, we register our hook function for the AFTER_TAG_CREATED event. When a tag gets created, we will log a message.

import logging

from empire.server.common.empire import MainMenu
from empire.server.common.plugins import Plugin
from empire.server.core.hooks import hooks

log = logging.getLogger(__name__)


class Plugin(Plugin):
    def onLoad(self):
        self.info = {
            "Name": "preplanned_tasks",
            # List of one or more authors for the plugin
            "Authors": [
                {
                    "Name": "Vince Rose",
                    "Handle": "@vinnybod",
                    "Link": "https://github.com/vinnybod",
                }
            ],
            "Description": (""),
            "Software": "SXXXX",
            "Techniques": ["TXXXX", "TXXXX"],
            "Comments": [],
        }
        self.options = {}

        hooks.register_hook(hooks.AFTER_TAG_CREATED_HOOK, 'preplanned_tasks', self.tag_created)

    def register(self, mainMenu):
        self.installPath = mainMenu.installPath
        self.main_menu: MainMenu = mainMenu

    def tag_created(self, db, tag, taggable):
        taggable_type = type(taggable).__name__
        log.info(f"Tag created: {tag.name}:{tag.value} on {taggable_type}")

    def execute(self, command):
        return True

    def shutdown(self):
        pass

Okay, now let’s enhance this a bit. When the tag event occurs on an agent, let’s execute a couple of tasks. We will execute pwd & whoami commands and a module.


    def register(self, mainMenu):
        self.installPath = mainMenu.installPath
        self.main_menu: MainMenu = mainMenu
        self.agent_task_service: AgentTaskService = self.main_menu.agenttasksv2
        self.module_service: ModuleService = self.main_menu.modulesv2

    def tag_created(self, db, tag, taggable):
        taggable_type = type(taggable).__name__
        log.info(f"Tag created: {tag.name}:{tag.value} on {taggable_type}")

        if not isinstance(taggable, models.Agent):
            return

        log.info(f"Tag is on an agent: {taggable.name}")

        if not tag.name == "preplanned_task":
            return

        log.info(f"Tag is a preplanned task: {tag.value}")

        self.agent_task_service.create_task_shell(db, taggable, 'pwd')
        self.agent_task_service.create_task_shell(db, taggable, 'whoami')
        if 'windows' in taggable.os_details.lower():
            module_req = ModulePostRequest(
                module_id='powershell_collection_prompt',
                options={'MsgTxt': 'Lost contact with the Domain Controller.'}
            )
            self.agent_task_service.create_task_module(db, taggable, module_req)

Since these tasks are generated by the plugin and not a human operator, let’s make that more clear by adding a tag to each of these tasks.

    def register(self, mainMenu):
        self.installPath = mainMenu.installPath
        self.main_menu: MainMenu = mainMenu
        self.agent_task_service: AgentTaskService = self.main_menu.agenttasksv2
        self.module_service: ModuleService = self.main_menu.modulesv2
        self.tag_service: TagService = self.main_menu.tagsv2

    def tag_created(self, db, tag, taggable):
        taggable_type = type(taggable).__name__
        log.info(f"Tag created: {tag.name}:{tag.value} on {taggable_type}")

        if not isinstance(taggable, models.Agent):
            return

        log.info(f"Tag is on an agent: {taggable.name}")

        if not tag.name == "preplanned_task":
            return

        log.info(f"Tag is a preplanned task: {tag.value}")

        tag_req = TagRequest(name='plugin', value='preplanned')

        task, _ = self.agent_task_service.create_task_shell(db, taggable, 'pwd')
        self.tag_service.add_tag(db, task, tag_req)

        task, _ = self.agent_task_service.create_task_shell(db, taggable, 'whoami')
        self.tag_service.add_tag(db, task, tag_req)

        if 'windows' in taggable.os_details.lower():
            plugin_task.output += f"Agent {taggable.name} is a windows agent\n"
            module_req = ModulePostRequest(
                module_id='powershell_collection_prompt',
                options={'MsgTxt': 'Lost contact with the Domain Controller.'}
            )
            task, _ = self.agent_task_service.create_task_module(db, taggable, module_req, user_id=1)
            self.tag_service.add_tag(db, task, tag_req)
Adding a tag to the agent triggers the plugin to automatically run some tasks

This is looking pretty good. Let’s add one more thing. Empire 5.2 added “Plugin Tasks”. This means that plugins have their own tasks that we can go back and look at. We will create a Plugin Task any time this plugin is triggered and executed.

    def tag_created(self, db, tag, taggable):
        taggable_type = type(taggable).__name__
        log.info(f"Tag created: {tag.name}:{tag.value} on {taggable_type}")

        if not isinstance(taggable, models.Agent):
            return

        log.info(f"Tag is on an agent: {taggable.name}")

        if not tag.name == "preplanned_task":
            return

        log.info(f"Tag is a preplanned task: {tag.value}")

        plugin_task = models.PluginTask(
            plugin_id='preplanned_tasks',
            input=f'Executing preplanned task plugin on agent {taggable.name}',
            input_full=f'Executing preplanned task plugin on agent {taggable.name}',
            output = '',
            status=PluginTaskStatus.completed
        )
        tag_req = TagRequest(name='plugin', value='preplanned')

        task, _ = self.agent_task_service.create_task_shell(db, taggable, 'pwd')
        self.tag_service.add_tag(db, task, tag_req)
        plugin_task.output += f"Executed pwd on agent {taggable.name}\n"

        task, _ = self.agent_task_service.create_task_shell(db, taggable, 'whoami')
        self.tag_service.add_tag(db, task, tag_req)
        plugin_task.output += f"Executed whoami on agent {taggable.name}\n"

        if 'windows' in taggable.os_details.lower():
            plugin_task.output += f"Agent {taggable.name} is a windows agent\n"
            module_req = ModulePostRequest(
                module_id='powershell_collection_prompt',
                options={'MsgTxt': 'Lost contact with the Domain Controller.'}
            )
            task, _ = self.agent_task_service.create_task_module(db, taggable, module_req)
            self.tag_service.add_tag(db, task, tag_req)
            plugin_task.output += f"Executed powershell_collection_prompt on agent {taggable.name}\n"

        db.add(plugin_task)
A plugin task shows the execution

So there you have it! Starkiller’s tagging feature is here to help get your data organized and to enhance the possibilities of plugins and automation. If you’d like to learn about using Empire and Starkiller for Adversary Emulation, then check out our Advanced Threat Emulation: Red Teams course at Blackhat.

The code for this example plugin can be found at https://github.com/vinnybod/preplanned-task-plugin

Written by: Vincent Rose

Tagged as: .

Rate it

Previous post