Mythic Documentation
Version 3.3
Version 3.3
  • Mythic
  • Operators
  • Installation
    • Connecting
    • A note about containers
    • Offline Installation
    • Updating Mythic
  • Internal Documentation
  • Quick Usage
  • Operational Pieces
    • MITRE ATT&CK
    • Operations
    • Browser Scripts
    • Active Callbacks
    • Files
    • Search
    • File Browser
    • Socks Proxy
    • Credentials
    • Comments
    • Tags
    • Expanded Callbacks
    • Screenshots
    • Event Feed
    • Understanding Commands
      • Basic Information
      • Parameters
      • MITRE ATT&CK in Commands
    • Payload Types
      • Containers
    • C2 Profiles
      • C2 Server Utilities
      • Egress vs P2P
      • HTTP
      • dynamicHTTP
      • Save Parameters
    • API Tokens
  • Message Flow
    • Building Payloads
    • Agent Sends Message
    • File Upload Mythic->Agent
    • File Download Agent->Mythic
    • P2P Messages
    • Operator Submits Tasking
  • Database Schema
  • Reporting
    • Artifacts
    • MITRE ATT&CK
    • Reports
  • Scripting
  • Presentations / Webinars
  • Common Errors
  • MythicTips
  • Customizing
    • Customizing Public Agent
    • Hooking Features
      • Actions
      • Linking Agents
        • P2P Connections
      • Process Browser
      • Artifacts
      • Credentials
      • File Downloads (Agent -> Mythic)
      • File Uploads (Mythic -> Agent)
      • Screenshots
      • Add / Remove Commands
      • Keylog
      • File Browser
      • Tokens
      • Alerts
      • SOCKS
      • RPFWD
      • Interactive Tasking
      • Task Status
      • OnContainerStart
    • 1. Payload Type Development
      • 2. Payload Type Definition
        • Container Syncing
        • Turning a VM into a Container
      • 3. Adding Commands
        • Commands
      • 4. Create Tasking & Comms Format
        • Agent Messages
          • 1. Agent Message Format
          • 2. Checkin
          • 3. Get Tasking
          • 4. Submitting Responses
          • 5. SOCKS
          • 6. Reverse Port Forward
          • 7. Peer-to-peer messages
          • 8. Interactive Tasking
      • 5. MythicRPC
      • 6. Browser Scripting
      • 7. Dynamic Parameter Values
      • 8. Sub-tasking / Task Callbacks
      • 9. OPSEC Checking
      • 10. Translation Containers
      • 11. Process Response
      • 12 TypedArray Parse Function
      • 13. SOCKS
      • 14. Reverse PortFwd
      • 15. Interactive Tasking
    • 2. C2 Development
      • Docker & Server Config
        • 1. Docker Containers
        • 2. Configuration Files
        • 3. OPSEC Checks
        • 4. Configuration Checks
        • 5. Sample Message
        • 6. File Hosting
        • 7. Redirect Rules
        • 8. Get IOC
        • 9. Push C2
    • 3. Consuming Containers
      • Webhooks
      • Logging
      • Eventing
        • Operator Context (run_as)
        • Workflow Triggers
        • Steps
      • Auth
    • 4. Extending Agent Commands
    • Mythic UI Development
  • Common Questions and Answers
    • FAQ / Troubleshooting Tips
    • Change Log
    • Tip of the Week
  • Updating
    • Mythic 2.1 -> 2.2 Updates
      • Agents 2.1.* -> 2.2.8
        • MythicRPC
    • Mythic 2.2 -> 2.3 Updates
      • Agents 2.2 -> 2.3
    • Mythic 2.3 -> 3.0 Updates
      • Agents 2.3 -> 3.0
    • Mythic 3.2->3.3 Updates
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Customizing
  2. 3. Consuming Containers

Logging

PreviousWebhooksNextEventing

Last updated 10 months ago

Was this helpful?

Logging Structure

Many organizations that use Mythic have a need for the logs generated from it, either for tracking user actions, deconflictions, or as part of operations (such as purple teaming). Different teams also have different levels of detail needed from logs, different formats, and even different output styles (stdout, files, direct to a SIEM, etc). Because of this, Mythic outsources most of its logs to logging containers that can subscribe to various events and then do whatever they want with the data. The nice thing about having this as part of a container that's hooked up to Mythic is that you can get the initial logging message and then turn around and use MythicRPC and Mythic's Scripting to augment that data with more context that you might need before shipping it off.

type LoggingDefinition struct {
	Name                     string
	Description              string
	LogToFilePath            string
	LogLevel                 string
	LogMaxSizeInMB           int
	LogMaxBackups            int
	NewCallbackFunction      func(input NewCallbackLog)
	NewCredentialFunction    func(input NewCredentialLog)
	NewKeylogFunction        func(input NewKeylogLog)
	NewFileFunction          func(input NewFileLog)
	NewPayloadFunction       func(input NewPayloadLog)
	NewArtifactFunction      func(input NewArtifactLog)
	NewTaskFunction          func(input NewTaskLog)
	NewResponseFunction      func(input NewResponseLog)
	Subscriptions            []string
	OnContainerStartFunction func(sharedStructs.ContainerOnStartMessage) sharedStructs.ContainerOnStartMessageResponse
}

and creating it:

myLoggerName := "my_logger"
myLogger := loggingstructs.LoggingDefinition{
    NewCallbackFunction: func(input loggingstructs.NewCallbackLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input)
    },
    NewTaskFunction: func(input loggingstructs.NewTaskLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
    NewPayloadFunction: func(input loggingstructs.NewPayloadLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
    NewKeylogFunction: func(input loggingstructs.NewKeylogLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
    NewCredentialFunction: func(input loggingstructs.NewCredentialLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
    NewArtifactFunction: func(input loggingstructs.NewArtifactLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
    NewFileFunction: func(input loggingstructs.NewFileLog) {
       loggingstructs.AllLoggingData.Get(myLoggerName).LogInfo(input.Action, "data", input.Data)
    },
}
loggingstructs.AllLoggingData.Get(myLoggerName).AddLoggingDefinition(myLogger)

In this example we're just using the built-in logger and writing to stdout.

Most of these fields in the definition are pretty self explanatory. You don't need to fill out subscriptions though - that is auto populated based on which functions you provide and is used to update the MythicUI to indicate what logs you're collecting. In the Go example above and screenshot below, we didn't register a function for new responses, so in the UI you can see that the "test" button for new responses is disabled.