Skip to main content

与 Mythic C2 框架实例交互

项目描述

神话脚本界面

mythic包创建了一种以编程方式交互和控制 Mythic 实例的方法。Mythic 是 Red Teaming 的命令和控制 (C2) 框架。代码在 GitHub ( https://github.com/its-a-feature/Mythic ) 上,Mythic 项目的文档在 GitBooks ( https://docs.mythic-c2.net ) 上。

安装

您可以从 PyPI 安装神秘的脚本界面:

pip install mythic

如何使用

该软件包的 0.0.13mythic版本支持 Mythic 项目的 2.1.* 版本。

该软件包的 0.0.15mythic版本支持 Mythic 项目的 2.2.1 版本。

mythic软件包的 0.0.20 版本支持 Mythic 项目的 2.2.6 版本(报告为版本“3”)。

包的 0.0.21-25mythic版本支持 Mythic 项目的 2.2.8+ 版本(报告为版本“3”)。

包的 0.0.26mythic版本支持 Mythic 项目的 2.3+ 版本(报告为版本“3”)。

mythic软件包的 0.0.29-0.0.36 版本支持使用新 GraphQL 端点的 Mythic 项目的 2.3+ 版本,并报告为版本“3”。这将是支持旧的mythic_rest 接口的最后一个版本。从版本 0.1.0 开始,mythicPyPi 包将仅支持新的 GraphQL 接口,并将报告为版本“4”。

新的 GraphQL 接口

除了旧的 RESTful 接口和 websockets,这个版本还包括一组 GraphQL 特性的测试版。

import asyncio
from time import time

from mythic import mythic, mythic_classes


async def main():
    mythic_instance = await mythic.login(
        username="mythic_admin",
        password="mythic_password",
        server_ip="192.168.53.139",
        server_port=7443,
        timeout=-1
    )

    # ################ Registering a file with Mythic for use in Tasking ################

    """ resp = await mythic.register_file(
       mythic=mythic_instance, filename="test.txt", contents=b"this is a test"
    )
    print(f"registered file UUID: {resp}")
    status = await mythic.issue_task(
       mythic=mythic_instance,
       command_name="upload",
       parameters={"remote_path": "test.js", "new-file": resp},
       callback_id=20,
    )
    print(f"Issued a task: {status}") """

    # ################ Issue Task and Wait for completion or timeout ################
    """
    try:
        status = await mythic.issue_task(
            mythic=mythic_instance,
            command_name="shell",
            parameters={"command": "whoami"},
            callback_id=0,
            timeout=20,
            return_on_status=mythic_classes.MythicStatus.Completed,
        )
        print(f"Issued a task: {status}")
    except Exception as e:
        print(f"Got exception trying to issue task: {str(e)}")
    """

    # ################ Issue Task against all active callbacks ################

    """status = await mythic.issue_task_all_active_callbacks(
        mythic=mythic_instance, command_name="shell", parameters="whoami"
    )
    print(f"Got the following list back: {status}")"""

    # ################ Issue Task and wait for output ################

    """ status = await mythic.issue_task_and_waitfor_task_output(
        mythic=mythic_instance,
        command_name="shell",
        parameters="whoami",
        callback_id=156,
        timeout=60,
        return_on_status=mythic_classes.MythicStatus.Completed,
    )
    print(f"Got the following output: {status}\n")

    task = await mythic.issue_task(
        mythic=mythic_instance,
        command_name="shell",
        parameters="whoami",
        callback_id=156,
        timeout=60,
        return_on_status=mythic_classes.MythicStatus.Completed,
    )
    output = await mythic.waitfor_for_task_output(
        mythic=mythic_instance, task_id=task["id"], timeout=60
    )
    print(f"Got the following output the 2nd time: {output}\n") """

    # ################ Wait for Multiple Subscriptions ################
    """await asyncio.gather(
        new_callbacks(mythic_instance=mythic_instance),
        new_tasks(mythic_instance=mythic_instance),
        all_tasks(mythic_instance=mythic_instance),
        all_tasks_by_callback(mythic_instance=mythic_instance, callback_id=156),
    )"""

    # ################ Adding MITRE ATT&CK Techniques To Task ################

    """ await mythic.add_mitre_attack_to_task(
        mythic=mythic_instance, task_id=1, mitre_attack_numbers=["T1033"]
    ) """

    # ################ Create a Payload ################
    """ await mythic.create_payload(
        mythic=mythic_instance,
        payload_type_name="poseidon",
        filename="test.bin",
        operating_system="macOS",
        commands=[],
        c2_profiles=[
            {
                "c2_profile": "http",
                "c2_profile_parameters": {
                    "callback_host": "http://192.168.53.139",
                    "callback_port": "80",
                },
            }
        ],
        build_parameters=[{"name": "mode", "value": "default"}],
        return_on_complete=True,
    )
    await mythic.create_payload(
        mythic=mythic_instance,
        payload_type_name="apfell",
        filename="apfell_test.js",
        operating_system="macOS",
        c2_profiles=[
            {
                "c2_profile": "http",
                "c2_profile_parameters": {
                    "callback_host": "http://192.168.53.139",
                    "callback_port": "80",
                },
            }
        ],
    ) """

    # ################ Add User to Operation ################
    """ try:
        await mythic.add_operator_to_operation(
            mythic=mythic_instance,
            operation_name="Operation Chimera",
            operator_username="bob",
        )
    except Exception as e:
        print(f"Got exception adding user to operation: {e}") """

    # ################ Update Operator View Mode ################

    """ try:
        await mythic.update_operator_in_operation(
            mythic=mythic_instance,
            operation_name="Operation Chimera",
            operator_username="bob",
            view_mode="spectator",
        )
    except Exception as e:
        print(f"Got exception updating user in operation: {e}") """

    # ################ Update Operation ################

    """ try:
        await mythic.update_operation(
            mythic=mythic_instance,
            operation_name="Operation Chimera",
            webhook_message="test",
            lead_operator_username="bob",
        )
    except Exception as e:
        print(f"Got exception updating operation: {e}") """

    # ################ Remove User from Operation ################
    """ try:
        await mythic.remove_operator_from_operation(
            mythic=mythic_instance,
            operation_name="Operation Chimera",
            operator_username="bob",
        )
    except Exception as e:
        print(f"Got exception removing user from operation: {e}") """

    # ################ Get all Payloads #############
    """payloads = await mythic.get_all_payloads(mythic=mythic_instance)
    print(payloads)"""

    # ############### Download a Payload ############
    """payload_bytes = await mythic.download_payload(
        mythic=mythic_instance, payload_uuid="04467b89-dc46-42d1-b7c4-03aca84b194c"
    )
    print(payload_bytes)"""

    # ############## Update a callback #############
    """await mythic.update_callback(
        mythic=mythic_instance,
        description="test set",
        locked=True,
        callback_id=156,
        active=False,
    )"""

    # ########### Get latest Processes #######
    """processes = await mythic.get_latest_processes_on_host(
        mythic=mythic_instance, host="SPOOKY.LOCAL"
    )
    print(processes)"""

    # ########## Search Files and Add Comments ###########
    """ files = await mythic.search_files(mythic=mythic_instance, filename="apfe")
    for f in files:
        print(f["filename_text"])
        await mythic.update_file_comment(
            mythic=mythic_instance, file_uuid=f["agent_file_id"], comment="auto updated"
        ) """

    # ########## Get Compromised Hosts, Users, IP Addresses ###########
    hosts = await mythic.get_unique_compromised_hosts(mythic=mythic_instance)
    print(hosts)
    users = await mythic.get_unique_compromised_accounts(mythic=mythic_instance)
    print(users)
    ips = await mythic.get_unique_compromised_ips(mythic=mythic_instance)
    print(ips)


async def new_callbacks(mythic_instance: mythic_classes.Mythic):
    async for callback in mythic.subscribe_new_callbacks(mythic=mythic_instance):
        print(f"got new callback:\n{callback}")


async def new_tasks(mythic_instance: mythic_classes.Mythic):
    async for task in mythic.subscribe_new_tasks(mythic=mythic_instance, timeout=3):
        print(f"got new task: {task}")


async def all_tasks(mythic_instance: mythic_classes.Mythic):
    async for task in mythic.subscribe_all_tasks(mythic=mythic_instance):
        print(f"got new task: {task}")


async def all_tasks_by_callback(mythic_instance: mythic_classes.Mythic, callback_id: int):
    async for task in mythic.subscribe_all_tasks(
        mythic=mythic_instance, callback_id=callback_id
    ):
        print(f"got new task by callback {callback_id}: {task}")


async def all_filebrowser(mythic_instance: mythic_classes.Mythic):
    async for f in mythic.subscribe_all_filebrowser(mythic=mythic_instance):
        print(f"got all filebrowser obj: {f}")


asyncio.run(main())

自定义属性

要为许多函数提供您自己的自定义属性,您需要将每个属性放在自己的行中,如下所示:

custom_attributes = """
host
user
payload {
    id
    uuid
}
"""
results = await mythic.get_all_callbacks(
    mythic=mythic_instance, custom_return_attributes=custom_attributes
)

信息

Mythic 文档有一整节关于脚本示例 ( https://docs.mythic-c2.net/scripting ) 对如何利用这个包很有用。该mythic包利用异步 HTTP 请求和 WebSocket 连接,因此确保您的代码库异步运行非常重要。Mythic 文档脚本页面上有一个示例存根来帮助解决这个问题。

测试

要运行单元测试:

pip3 install pytest, gql[aiohttp,websockets], aiohttp, asyncio
make all_tests

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

mytic-0.0.38.tar.gz (38.2 kB 查看哈希)

已上传 source

内置分布

mytic-0.0.38-py3-none-any.whl (36.4 kB 查看哈希)

已上传 py3