Skip to content

Commit

Permalink
small QoL fixes
Browse files Browse the repository at this point in the history
new commands `config` and `shell_config`
  • Loading branch information
its-a-feature committed Aug 5, 2024
1 parent b541e63 commit a6f5156
Show file tree
Hide file tree
Showing 17 changed files with 283 additions and 70 deletions.
9 changes: 9 additions & 0 deletions Payload_Type/poseidon/poseidon/agent_code/CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## 2.1.2 - 2024-08-05

### Changed

- Adjusted the args parsing for `run` to not have env get auto populated
- Adjusted the `pty` command to not automatically spawn an extra port on the Mythic server
- Adjusted the `sudo` command to allow for parameters
- Added new `shell_config` command to allow changing the shell used for `shell` commands
- Added `config` command to view basic host config again dynamically pulled
## 2.1.2 - 2024-07-11

### Changed
Expand Down
34 changes: 34 additions & 0 deletions Payload_Type/poseidon/poseidon/agent_code/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package config

import (
// Poseidon

"encoding/json"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/functions"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/structs"
)

// Run - Function that executes the shell command
func Run(task structs.Task) {
msg := task.NewResponse()
hostConfig := map[string]interface{}{
"elevated": functions.IsElevated(),
"arch": functions.GetArchitecture(),
"domain": functions.GetDomain(),
"os": functions.GetOS(),
"process_name": functions.GetProcessName(),
"user": functions.GetUser(),
"pid": functions.GetPID(),
"host": functions.GetHostname(),
"ips": functions.GetCurrentIPAddress(),
}
hostConfigBytes, err := json.Marshal(hostConfig)
if err != nil {
msg.SetError(err.Error())
} else {
msg.UserOutput = string(hostConfigBytes)
}
msg.Completed = true
task.Job.SendResponses <- msg
return
}
6 changes: 5 additions & 1 deletion Payload_Type/poseidon/poseidon/agent_code/ls/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ func Run(task structs.Task) {
e.Files = fileEntries
}
msg.Completed = true
tmpData := e
msg.FileBrowser = &e
temp, _ := json.Marshal(msg.FileBrowser)
if !tmpData.IsFile {
tmpData.Filename = "."
}
temp, _ := json.Marshal(tmpData)
msg.UserOutput = string(temp)
task.Job.SendResponses <- msg
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/cd"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/clipboard"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/clipboard_monitor"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/config"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/cp"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/curl"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/download"
Expand Down Expand Up @@ -184,6 +185,10 @@ func listenForNewTask() {
go link_webshell.Run(task)
case "unlink_webshell":
go unlink_webshell.Run(task)
case "shell_config":
go shell.RunConfig(task)
case "config":
go config.Run(task)
default:
// No tasks, do nothing
break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package functions

/*
#include <unistd.h>;
#include <unistd.h>
int UpdateEUID();
int UpdateEUID(){
uid_t euid = geteuid();
Expand Down
35 changes: 25 additions & 10 deletions Payload_Type/poseidon/poseidon/agent_code/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package shell

import (
"bufio"
"encoding/json"
"fmt"
"os"
"os/exec"
Expand All @@ -13,20 +14,13 @@ import (
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/structs"
)

var shellBin = "/bin/bash"

// Run - Function that executes the shell command
func Run(task structs.Task) {
msg := task.NewResponse()
shellBin := "/bin/bash"
if _, err := os.Stat(shellBin); err != nil {
if _, err = os.Stat("/bin/sh"); err != nil {
msg.SetError("Could not find /bin/bash or /bin/sh")
task.Job.SendResponses <- msg
return
} else {
shellBin = "/bin/sh"
}
}
command := exec.Command(shellBin)

command.Stdin = strings.NewReader(task.Params)
command.Env = os.Environ()

Expand Down Expand Up @@ -120,3 +114,24 @@ func Run(task structs.Task) {
}
return
}

type Arguments struct {
Shell string `json:"shell"`
}

func RunConfig(task structs.Task) {
msg := task.NewResponse()
args := Arguments{}
err := json.Unmarshal([]byte(task.Params), &args)
if err != nil {
msg.SetError(err.Error())
task.Job.SendResponses <- msg
return
}
shellBin = args.Shell
msg.Completed = true
msg.UserOutput = fmt.Sprintf("Shell updated")

task.Job.SendResponses <- msg
return
}
11 changes: 6 additions & 5 deletions Payload_Type/poseidon/poseidon/agent_code/sudo/sudo.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import (
)

type Arguments struct {
Username string `json:"username"`
Password string `json:"password"`
PromptText string `json:"prompt_text"`
PromptIconPath string `json:"prompt_icon_path"`
Command string `json:"command"`
Username string `json:"username"`
Password string `json:"password"`
Args []string `json:"args"`
PromptText string `json:"prompt_text"`
PromptIconPath string `json:"prompt_icon_path"`
Command string `json:"command"`
}

func Run(task structs.Task) {
Expand Down
16 changes: 15 additions & 1 deletion Payload_Type/poseidon/poseidon/agent_code/sudo/sudo_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,22 @@ func sudoWithPromptOption(task structs.Task, args Arguments) {
defer C.free(unsafe.Pointer(cPromptIconPath))
cCommand := C.CString(args.Command)
defer C.free(unsafe.Pointer(cCommand))
cArgs := make([]*C.char, len(args.Args)+1)
for i := range cArgs {
cArgs[i] = nil
}
//cArgs[0] = C.CString(args.Command)
for i, arg := range args.Args {
cArgs[i] = C.CString(arg)
}
cArgv := (**C.char)(unsafe.Pointer(&cArgs[0]))
for i := range cArgs {
if cArgs[i] != nil {
defer C.free(unsafe.Pointer(cArgs[i]))
}
}
cFD := C.int(0)
contents := C.sudo_poseidon(cUsername, cPassword, cPromptText, cPromptIconPath, cCommand, &cFD)
contents := C.sudo_poseidon(cUsername, cPassword, cPromptText, cPromptIconPath, cCommand, cArgv, &cFD)
fd := int(cFD)
if fd > 0 {
newFD := os.NewFile(uintptr(cFD), "pipe")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#import <Foundation/Foundation.h>
#import <Security/Security.h>
extern const char* sudo_poseidon(char* username, char* password, char* promptText, char* promptIcon, char* command, int* fd);
extern const char* sudo_poseidon(char* username, char* password, char* promptText, char* promptIcon, char* command, char** args, int* fd);
4 changes: 2 additions & 2 deletions Payload_Type/poseidon/poseidon/agent_code/sudo/sudo_darwin.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#import "sudo_darwin.h"


const char* sudo_poseidon(char* username, char* password, char* promptText, char* promptIcon, char* command, int* fd){
const char* sudo_poseidon(char* username, char* password, char* promptText, char* promptIcon, char* command, char** args, int* fd){
AuthorizationRef authRef = 0;
OSStatus status = 0;
char* rightName = "allow";
Expand Down Expand Up @@ -48,7 +48,7 @@
}
return [[[NSString alloc] initWithFormat:@"Error: %d. Cannot copy authorization reference.", status] UTF8String];
}
char *args[] = {NULL};
//char *args[] = {NULL};
FILE *pipe = NULL;

status = AuthorizationExecuteWithPrivileges(authRef, command, kAuthorizationFlagDefaults, args, &pipe);
Expand Down
2 changes: 1 addition & 1 deletion Payload_Type/poseidon/poseidon/agentfunctions/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"time"
)

const version = "2.1.2"
const version = "2.1.3"

type sleepInfoStruct struct {
Interval int `json:"interval"`
Expand Down
25 changes: 25 additions & 0 deletions Payload_Type/poseidon/poseidon/agentfunctions/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package agentfunctions

import (
agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
)

var config = agentstructs.Command{
Name: "config",
Description: "View current config and host information",
MitreAttackMappings: []string{},
TaskFunctionCreateTasking: configCreateTasking,
Version: 1,
}

func init() {
agentstructs.AllPayloadData.Get("poseidon").AddCommand(config)
}

func configCreateTasking(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse {
response := agentstructs.PTTaskCreateTaskingMessageResponse{
Success: true,
TaskID: taskData.Task.ID,
}
return response
}
53 changes: 38 additions & 15 deletions Payload_Type/poseidon/poseidon/agentfunctions/pty.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ var pty = agentstructs.Command{
Description: "What program to spawn with a PTY",
DefaultValue: "/bin/bash",
},
{
Name: "open_port",
CLIName: "openPort",
ModalDisplayName: "Open Port",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_BOOLEAN,
Description: "Whether to open a local port for additional PTY access",
DefaultValue: false,
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
},
},
},
},
TaskCompletionFunctions: map[string]agentstructs.PTTaskCompletionFunction{
"close_ports": func(taskData *agentstructs.PTTaskMessageAllData, subtaskData *agentstructs.PTTaskMessageAllData, subtaskName *agentstructs.SubtaskGroupName) agentstructs.PTTaskCompletionFunctionMessageResponse {
Expand Down Expand Up @@ -71,32 +84,42 @@ func ptyCreateTasking(taskData *agentstructs.PTTaskMessageAllData) agentstructs.
response.Success = false
return response
}
if _, err := mythicrpc.SendMythicRPCArtifactCreate(mythicrpc.MythicRPCArtifactCreateMessage{
_, err = mythicrpc.SendMythicRPCArtifactCreate(mythicrpc.MythicRPCArtifactCreateMessage{
BaseArtifactType: "ProcessCreate",
ArtifactMessage: programPath,
TaskID: taskData.Task.ID,
}); err != nil {
})
if err != nil {
logging.LogError(err, "Failed to send mythicrpc artifact create")
}
if socksResponse, err := mythicrpc.SendMythicRPCProxyStart(mythicrpc.MythicRPCProxyStartMessage{
PortType: rabbitmq.CALLBACK_PORT_TYPE_INTERACTIVE,
LocalPort: 0,
TaskID: taskData.Task.ID,
}); err != nil {
logging.LogError(err, "Failed to start socks")
openPort, err := taskData.Args.GetBooleanArg("open_port")
if err != nil {
response.Error = err.Error()
response.Success = false
return response
} else if !socksResponse.Success {
response.Error = socksResponse.Error
response.Success = false
return response
} else {
}
if openPort {
socksResponse, err := mythicrpc.SendMythicRPCProxyStart(mythicrpc.MythicRPCProxyStartMessage{
PortType: rabbitmq.CALLBACK_PORT_TYPE_INTERACTIVE,
LocalPort: 0,
TaskID: taskData.Task.ID,
})
if err != nil {
logging.LogError(err, "Failed to start socks")
response.Error = err.Error()
response.Success = false
return response
}
if !socksResponse.Success {
response.Error = socksResponse.Error
response.Success = false
return response
}
stdout := fmt.Sprintf("Opened port: %d\n", socksResponse.LocalPort)
response.Stdout = &stdout
completionName := "close_ports"
response.CompletionFunctionName = &completionName
response.DisplayParams = &programPath
return response
}
response.DisplayParams = &programPath
return response
}
16 changes: 15 additions & 1 deletion Payload_Type/poseidon/poseidon/agentfunctions/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package agentfunctions

import (
"errors"
"fmt"
"github.com/MythicMeta/MythicContainer/logging"
"strings"

agentstructs "github.com/MythicMeta/MythicContainer/agent_structs"
)
Expand Down Expand Up @@ -64,14 +66,26 @@ func init() {
Success: true,
TaskID: taskData.Task.ID,
}
if path, err := taskData.Args.GetStringArg("path"); err != nil {
path, err := taskData.Args.GetStringArg("path")
if err != nil {
logging.LogError(err, "Failed to get path argument")
response.Success = false
response.Error = err.Error()
return response
}
runArgs, err := taskData.Args.GetArrayArg("args")
if err != nil {
response.Success = false
response.Error = err.Error()
return response
}
if len(runArgs) > 0 {
displayParams := fmt.Sprintf("%s %s", path, strings.Join(runArgs, " "))
response.DisplayParams = &displayParams
} else {
response.DisplayParams = &path
}

return response
},
TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error {
Expand Down
Loading

0 comments on commit a6f5156

Please sign in to comment.