From 6f671c8ae57ab0c836268a8baaaeb770c8ccf5b6 Mon Sep 17 00:00:00 2001 From: irabva Date: Mon, 27 Oct 2025 14:22:57 -0400 Subject: [PATCH 1/3] Add nslookup command for DNS name resolving --- .../poseidon/agent_code/nslookup/nslookup.go | 63 +++++++++++++++++ .../agent_code/pkg/tasks/newTasking.go | 3 + .../poseidon/agentfunctions/nslookup.go | 67 +++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go create mode 100644 Payload_Type/poseidon/poseidon/agentfunctions/nslookup.go diff --git a/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go b/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go new file mode 100644 index 00000000..23797dd2 --- /dev/null +++ b/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go @@ -0,0 +1,63 @@ +package nslookup + +import ( + // Standard + "encoding/json" + "errors" + "net" + + // Poseidon + "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/structs" +) + +// важно начинать название с большой буквы - public member +type Arguments struct { + Type string `json:"type"` + Address string `json:"address"` +} + +// называние функции обязательно такое и с такими аргументами +func Run(task structs.Task) { + msg := task.NewResponse() + var args Arguments + + // тут нам падают аргументы. их нужно распарсить в структуру, которую мы ожидаем из от оператора + err := json.Unmarshal([]byte(task.Params), &args) + if err != nil { + msg.SetError(err.Error()) + task.Job.SendResponses <- msg // если не распарсилось - возвращаем ошибку на сервак + return + } + address := args.Address + reqType := args.Type + + //result of resolving + var result any + + // resolve + if reqType == "A" { + result, err = net.LookupHost(address) + } else if reqType == "PTR" { + result, err = net.LookupAddr(address) + } else if reqType == "TXT" { + result, err = net.LookupTXT(address) + } else if reqType == "MX" { + result, err = net.LookupMX(address) + } else if reqType == "CNAME" { + result, err = net.LookupCNAME(address) + } else if reqType == "NS" { + result, err = net.LookupNS(address) + } else { + err = errors.New("invalid request type") + } + + // send the result + if err != nil { + msg.SetError(err.Error()) + } else { + data, _ := json.Marshal(result) + msg.UserOutput = string(data) + msg.Completed = true + } + task.Job.SendResponses <- msg +} diff --git a/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go b/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go index 49f780a3..ed70c89a 100644 --- a/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go +++ b/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go @@ -30,6 +30,7 @@ import ( "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/ls" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/mkdir" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/mv" + "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/nslookup" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/persist_launchd" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/persist_loginitem" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/runtimeMainThread" @@ -198,6 +199,8 @@ func listenForNewTask() { go ifconfig.Run(task) case "caffeinate": go caffeinate.Run(task) + case "nslookup": + go nslookup.Run(task) default: // No tasks, do nothing break diff --git a/Payload_Type/poseidon/poseidon/agentfunctions/nslookup.go b/Payload_Type/poseidon/poseidon/agentfunctions/nslookup.go new file mode 100644 index 00000000..e1d3c443 --- /dev/null +++ b/Payload_Type/poseidon/poseidon/agentfunctions/nslookup.go @@ -0,0 +1,67 @@ +package agentfunctions + +import ( + "errors" + + agentstructs "github.com/MythicMeta/MythicContainer/agent_structs" +) + +func init() { + agentstructs.AllPayloadData.Get("poseidon").AddCommand(agentstructs.Command{ + Name: "nslookup", + Description: "resolve using the local resolver", + HelpString: "nslookup A domain.local", + Version: 1, + Author: "", + MitreAttackMappings: []string{}, + SupportedUIFeatures: []string{}, + CommandAttributes: agentstructs.CommandAttribute{ + SupportedOS: []string{}, + }, + CommandParameters: []agentstructs.CommandParameter{ + { + Name: "address", + ModalDisplayName: "Hostname or address to resolve", + ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_STRING, + ParameterGroupInformation: []agentstructs.ParameterGroupInfo{ + { + ParameterIsRequired: true, + UIModalPosition: 1, + }, + }, + Description: "Hostname or address to resolve", + }, + { + Name: "type", + DefaultValue: "A", + ModalDisplayName: "Type of request", + ParameterType: agentstructs.COMMAND_PARAMETER_TYPE_CHOOSE_ONE, + Choices: []string{"A", "PTR", "MX", "TXT", "CNAME", "NS"}, + ParameterGroupInformation: []agentstructs.ParameterGroupInfo{ + { + ParameterIsRequired: false, + UIModalPosition: 2, + }, + }, + Description: "Type of request", + }, + }, + TaskFunctionCreateTasking: func(taskData *agentstructs.PTTaskMessageAllData) agentstructs.PTTaskCreateTaskingMessageResponse { + response := agentstructs.PTTaskCreateTaskingMessageResponse{ + Success: true, + TaskID: taskData.Task.ID, + } + return response + }, + TaskFunctionParseArgDictionary: func(args *agentstructs.PTTaskMessageArgsData, input map[string]interface{}) error { + return args.LoadArgsFromDictionary(input) + }, + TaskFunctionParseArgString: func(args *agentstructs.PTTaskMessageArgsData, input string) error { + if len(input) > 0 { + return args.LoadArgsFromJSONString(input) + } else { + return errors.New("Must supply arguments") + } + }, + }) +} From 3696170ce101b3e78b7f62fd0c00d216077dec54 Mon Sep 17 00:00:00 2001 From: irabva Date: Mon, 27 Oct 2025 21:27:38 +0300 Subject: [PATCH 2/3] Update newTasking.go --- .../poseidon/poseidon/agent_code/pkg/tasks/newTasking.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go b/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go index ed70c89a..5a5f3807 100644 --- a/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go +++ b/Payload_Type/poseidon/poseidon/agent_code/pkg/tasks/newTasking.go @@ -30,7 +30,7 @@ import ( "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/ls" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/mkdir" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/mv" - "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/nslookup" + "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/nslookup" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/persist_launchd" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/persist_loginitem" "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/runtimeMainThread" @@ -199,8 +199,8 @@ func listenForNewTask() { go ifconfig.Run(task) case "caffeinate": go caffeinate.Run(task) - case "nslookup": - go nslookup.Run(task) + case "nslookup": + go nslookup.Run(task) default: // No tasks, do nothing break From add5c965be13c997978151d4f04a56fafba8c883 Mon Sep 17 00:00:00 2001 From: irabva Date: Mon, 27 Oct 2025 14:34:59 -0400 Subject: [PATCH 3/3] Update nslookup.go --- .../poseidon/poseidon/agent_code/nslookup/nslookup.go | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go b/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go index 23797dd2..80534815 100644 --- a/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go +++ b/Payload_Type/poseidon/poseidon/agent_code/nslookup/nslookup.go @@ -1,40 +1,32 @@ package nslookup import ( - // Standard "encoding/json" "errors" "net" - - // Poseidon "github.com/MythicAgents/poseidon/Payload_Type/poseidon/agent_code/pkg/utils/structs" ) -// важно начинать название с большой буквы - public member type Arguments struct { Type string `json:"type"` Address string `json:"address"` } -// называние функции обязательно такое и с такими аргументами func Run(task structs.Task) { msg := task.NewResponse() var args Arguments - // тут нам падают аргументы. их нужно распарсить в структуру, которую мы ожидаем из от оператора err := json.Unmarshal([]byte(task.Params), &args) if err != nil { msg.SetError(err.Error()) - task.Job.SendResponses <- msg // если не распарсилось - возвращаем ошибку на сервак + task.Job.SendResponses <- msg return } address := args.Address reqType := args.Type - //result of resolving var result any - // resolve if reqType == "A" { result, err = net.LookupHost(address) } else if reqType == "PTR" { @@ -51,7 +43,6 @@ func Run(task structs.Task) { err = errors.New("invalid request type") } - // send the result if err != nil { msg.SetError(err.Error()) } else {