Skip to content

Commit

Permalink
bug fixes for sudo, prompt, and clipboard_monitor
Browse files Browse the repository at this point in the history
  • Loading branch information
its-a-feature committed Feb 15, 2024
1 parent 65bae8e commit 988f2e2
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 52 deletions.
8 changes: 4 additions & 4 deletions Payload_Type/poseidon/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ require (
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/grpc v1.61.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions Payload_Type/poseidon/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,28 @@ golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 h1:FSL3lRCkhaPFxqi0s9o+V4UI2WTzAVOvkgbd4kVV4Wg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014/go.mod h1:SaPjaZGWb0lPqs6Ittu0spdfrOArqji4ZdeP5IC/9N4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 h1:hZB7eLIaYlW9qXRfCq/qDaPdbeY3757uARz5Vvfv+cY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:YUWgXUFRPfoYK1IHMuxH5K6nPEXSCzIMljnQ59lLRCk=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0=
Expand Down
8 changes: 8 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,14 @@ 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.0.22 - 2024-02-15

### Changed

- Fixed an issue with prompt command not releasing the prompt window on successful input
- Fixed an issue with the clipboard_monitor crashing when it couldn't find the window name
- Fixed an issue with the sudo command on macOS not respecting and changing the new process's UID/GID

## 2.0.20 - 2024-01-10

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,22 @@ -(id) init {
}
-(void)updateFrontmost:(NSNotification *)notification
{
self.frontmost = [[[[notification userInfo] objectForKey:NSWorkspaceApplicationKey] localizedName] UTF8String];
NSDictionary *UserInfo = [notification userInfo];
if (UserInfo != nil ){
NSString* app = [UserInfo objectForKey:NSWorkspaceApplicationKey];
if(app != nil ){
NSString* localizedName = [app localizedName];
if(localizedName != nil){
self.frontmost = [localizedName UTF8String];
} else {
self.frontmost = [app UTF8String];
}
//NSLog(@"Self.frontmost updated to: %s", self.frontmost);
return;
}
}
self.frontmost = "UNKNOWN";
//self.frontmost = [[[[notification userInfo] objectForKey:NSWorkspaceApplicationKey] localizedName] UTF8String];
//NSLog(@"Self.frontmost updated to: %s", self.frontmost);
//NSLog(@"Reacting to notification %@ from object %@ with userInfo %@", notification, notification.object, notification.userInfo);
}
Expand Down Expand Up @@ -61,7 +76,7 @@ long getClipboardCount(){
myNotifications = [[ActivateNotifications alloc] init];
}
if( [myNotifications getFrontmostName] != NULL){
return [[myNotifications getFrontmostName] UTF8String];
return [myNotifications getFrontmostName];
} else {
return "";
}
Expand All @@ -73,5 +88,6 @@ void waitForTime(){
value:1
toDate:now
options:NSCalendarMatchNextTime];
[[NSRunLoop mainRunLoop] runUntilDate:nowPlusOneSecond];
//[[NSRunLoop mainRunLoop] runUntilDate:nowPlusOneSecond];
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.1f]];
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ var (
)
var (
// HandleInboundMythicMessageFromEgressChannel processes messages from egress
HandleInboundMythicMessageFromEgressChannel = make(chan structs.MythicMessageResponse, 10)
HandleInboundMythicMessageFromEgressChannel = make(chan structs.MythicMessageResponse, 100)
// FromMythicSocksChannel gets SOCKS messages from Mythic
FromMythicSocksChannel = make(chan structs.SocksMsg, 100)
FromMythicSocksChannel = make(chan structs.SocksMsg, 2000)
// FromMythicRpfwdChannel gets RPFWD messages from Mythic
FromMythicRpfwdChannel = make(chan structs.SocksMsg, 100)
FromMythicRpfwdChannel = make(chan structs.SocksMsg, 2000)
// InterceptToMythicSocksChannel gets SOCKS messages from agent and determines if they should be held or passed to Push C2 immediately
InterceptToMythicSocksChannel = make(chan structs.SocksMsg, 100)
InterceptToMythicSocksChannel = make(chan structs.SocksMsg, 2000)
// toMythicSocksChannel gets SOCKS messages queued up waiting for the agent to check back in with Mythic again
toMythicSocksChannel = make(chan structs.SocksMsg, 100)
toMythicSocksChannel = make(chan structs.SocksMsg, 2000)
// InterceptToMythicRpfwdChannel gets SOCKS messages from agent and determines if they should be held or passed to Push C2 immediately
InterceptToMythicRpfwdChannel = make(chan structs.SocksMsg, 100)
InterceptToMythicRpfwdChannel = make(chan structs.SocksMsg, 2000)
// toMythicRpfwdChannel gets SOCKS messages queued up waiting for the agent to check back in with Mythic again
toMythicRpfwdChannel = make(chan structs.SocksMsg, 100)
toMythicRpfwdChannel = make(chan structs.SocksMsg, 2000)
)

// listenForDelegateMessagesToMythic gathers the delegate messages (NewDelegatesToMythicChannel) that need to go out the egress channel into a central location
Expand Down Expand Up @@ -182,15 +182,15 @@ func listenForSocksTrafficToMythic(getProfilesPushChannelFunc func() chan struct
Socks: &[]structs.SocksMsg{response},
}:
case <-time.After(1 * time.Second):
utils.PrintDebug(fmt.Sprintf("dropping data because channel is full"))
utils.PrintDebug(fmt.Sprintf("dropping push socks data because channel is full, %d", len(pushChan)))
}

} else {
// if there's no push channel, forward it along like normal for somebody else to get it
select {
case toMythicSocksChannel <- response:
case <-time.After(1 * time.Second):
utils.PrintDebug(fmt.Sprintf("dropping data because channel is full"))
utils.PrintDebug(fmt.Sprintf("dropping data because channel is full, %d", len(toMythicSocksChannel)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import <Foundation/Foundation.h>

const char* nsstring2cstring(NSString*);
const NSString* GetOSVersion();
const NSString* GetOSVersion();
int UpdateEUID();
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#import "foundation_darwin.h"
#include <unistd.h>

const char*
nsstring2cstring(NSString *s) {
if (s == NULL) { return NULL; }
Expand All @@ -10,4 +12,19 @@
const NSString* GetOSVersion(){
NSString * operatingSystemVersionString = [[NSProcessInfo processInfo] operatingSystemVersionString];
return operatingSystemVersionString;
}

int UpdateEUID(){
uid_t euid = geteuid();
uid_t uid = getuid();
if(euid != uid){
setuid(euid);
}
gid_t egid = getegid();
gid_t gid = getgid();
if(egid != gid){
setgid(egid);
}
uid_t finalUID = getuid();
return finalUID;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@ import (
"os"
"os/user"
"runtime"
"strconv"
"strings"
"unicode/utf16"
)

func cstring(s *C.NSString) *C.char { return C.nsstring2cstring(s) }
func gostring(s *C.NSString) string { return C.GoString(cstring(s)) }
func isElevated() bool {
currentUser, err := user.Current()
if err != nil {
return false
}
return currentUser.Uid == "0"
uid := C.UpdateEUID()
return uid == 0
}
func getArchitecture() string {
return runtime.GOARCH
Expand Down Expand Up @@ -62,7 +60,9 @@ func getOS() string {
//return runtime.GOOS
}
func getUser() string {
currentUser, err := user.Current()
uid := C.UpdateEUID()
currentUser, err := user.LookupId(strconv.Itoa(int(uid)))
//currentUser, err := user.Current()
if err != nil {
return ""
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
// +build linux
//go:build linux

package functions

/*
#include <unistd.h>;
int UpdateEUID();
int UpdateEUID(){
uid_t euid = geteuid();
uid_t uid = getuid();
if(euid != uid){
setuid(euid);
}
gid_t egid = getegid();
gid_t gid = getgid();
if(egid != gid){
setgid(egid);
}
uid_t finalUID = getuid();
return finalUID;
}
*/
import "C"
import (
"fmt"
"os"
"os/user"
"runtime"
"strconv"
"unicode/utf16"

"golang.org/x/sys/unix"
)

func isElevated() bool {
currentUser, _ := user.Current()
return currentUser.Uid == "0"
uid := C.UpdateEUID()
return uid == 0
}
func getArchitecture() string {
return runtime.GOARCH
Expand Down Expand Up @@ -43,11 +63,16 @@ func getStringFromBytes(data [65]byte) string {
}
func getOS() string {
u := unix.Utsname{}
unix.Uname(&u)
err := unix.Uname(&u)
if err != nil {
return fmt.Sprintf("Unknown Error: %v", err)
}
return getStringFromBytes(u.Sysname) + "\n" + getStringFromBytes(u.Nodename) + "\n" + getStringFromBytes(u.Release) + "\n" + getStringFromBytes(u.Version) + "\n" + getStringFromBytes(u.Machine)
}
func getUser() string {
currentUser, err := user.Current()
uid := C.UpdateEUID()
currentUser, err := user.LookupId(strconv.Itoa(int(uid)))
//currentUser, err := user.Current()
if err != nil {
return ""
} else {
Expand Down Expand Up @@ -82,7 +107,8 @@ func UINT32ByteCountDecimal(b uint32) string {
}

// Helper function to convert LARGE_INTEGER byte
// counts to human readable sizes.
//
// counts to human readable sizes.
func UINT64ByteCountDecimal(b uint64) string {
const unit = 1024
if b < unit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ - (void)runWithMessageText:(NSString *)messageText informativeText:(NSString *)i
NSModalResponse response = [alertView runModal];
if (response == NSModalResponseOK && [self verifyPassword:passwordField.stringValue]) {
self.successHandler(passwordField.stringValue);
}else {
self.failureHandler(response, passwordField.stringValue);
}
self.failureHandler(response, passwordField.stringValue);

}

- (BOOL)verifyPassword:(NSString *)password {
Expand All @@ -83,6 +85,7 @@ - (BOOL)verifyPassword:(NSString *)password {
__block bool reprompt = false;
__block int currentTry = 1;
agent.successHandler = ^(NSString *password) {
reprompt = false;
userText = [[NSString alloc] initWithString:password];
};

Expand Down Expand Up @@ -114,5 +117,6 @@ - (BOOL)verifyPassword:(NSString *)password {
}

}
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
return [[[NSString alloc] initWithFormat:@"Failed Inputs:\n%@\nSuccessful Input:%@\n", failedText, userText] UTF8String];
}
6 changes: 2 additions & 4 deletions Payload_Type/poseidon/poseidon/agent_code/socks/socks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import (
"encoding/json"
"fmt"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/responses"
"github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/structs"
"io"
"net"
"strconv"
"strings"
"time"

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

// ****** The following is from https://github.com/armon/go-socks5 *****
Expand Down Expand Up @@ -156,7 +154,7 @@ func handleMutexMapModifications() {
// got a message from mythic, we know of that serverID, send the data along
select {
case channelMap[msg.ServerId].Channel <- msg:
case <-time.After(1 * time.Second):
default:
//fmt.Printf("dropping data because channel is full")
}
} else if !msg.Exit {
Expand Down
28 changes: 17 additions & 11 deletions Payload_Type/poseidon/poseidon/agent_code/sudo/sudo_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,27 @@ func sudoWithPromptOption(task structs.Task, args Arguments) {
}
defer newFD.Close()
data := make([]byte, 1024)
n, err := newFD.Read(data)
if err != nil && n == 0 {
if err == io.EOF {
msg.Completed = true
msg.Status = "completed"
for {
n, err := newFD.Read(data)
if err != nil {
if err == io.EOF {
msg.Completed = true
msg.UserOutput = ""
msg.Status = "completed"
task.Job.SendResponses <- msg
return
}
msg.SetError(err.Error())
task.Job.SendResponses <- msg
return
}
msg.SetError(err.Error())
task.Job.SendResponses <- msg
return
if n > 0 {
msg.UserOutput = string(data[0:n])
task.Job.SendResponses <- msg
n = 0
}
}
msg.UserOutput = string(data[0:n])
msg.Completed = true
task.Job.SendResponses <- msg

} else {
msg.SetError(C.GoString(contents))
task.Job.SendResponses <- msg
Expand Down
Loading

0 comments on commit 988f2e2

Please sign in to comment.