Exemple #1
0
        private APIModels.GruntTaskingMessage GetGruntTaskingMessage(APIModels.GruntTasking tasking, APIModels.DotNetVersion version)
        {
            string Message = "";

            switch (tasking.Type)
            {
            case APIModels.GruntTaskingType.Assembly:
                switch (version)
                {
                case APIModels.DotNetVersion.Net35:
                    Message = Convert.ToBase64String(this.GetCompressedILAssembly35(tasking.GruntTask.Name));
                    if (tasking.Parameters.Any())
                    {
                        Message += "," + String.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                    }
                    break;

                case APIModels.DotNetVersion.Net40:
                    Message = Convert.ToBase64String(this.GetCompressedILAssembly40(tasking.GruntTask.Name));
                    if (tasking.Parameters.Any())
                    {
                        Message += "," + String.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                    }
                    break;
                }
                break;

            case APIModels.GruntTaskingType.SetOption:
                if (tasking.Parameters.Count >= 2)
                {
                    Message = tasking.Parameters[0] + "," + tasking.Parameters[1];
                }
                break;

            case APIModels.GruntTaskingType.Connect:
                if (tasking.Parameters.Count >= 2)
                {
                    Message = tasking.Parameters[0] + "," + tasking.Parameters[1];
                }
                break;

            case APIModels.GruntTaskingType.Disconnect:
                if (tasking.Parameters.Count >= 1)
                {
                    Message = tasking.Parameters[0];
                }
                break;

            default:
                Message = string.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                break;
            }
            return(new APIModels.GruntTaskingMessage
            {
                Type = tasking.Type,
                Name = tasking.Name,
                Message = Message,
                Token = tasking.GruntTask == null ? false : tasking.GruntTask.TokenTask
            });
        }
Exemple #2
0
 private async Task <APIModels.GruntTasking> MarkTasked(APIModels.GruntTasking tasking)
 {
     if (tasking == null)
     {
         return(null);
     }
     tasking.Status      = APIModels.GruntTaskingStatus.Tasked;
     tasking.TaskingTime = DateTime.UtcNow;
     return(await _client.ApiTaskingsPutAsync(tasking));
 }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the GruntCommand class.
 /// </summary>
 public GruntCommand(string command, System.DateTime commandTime, int commandOutputId, string userId, int?id = default(int?), CommandOutput commandOutput = default(CommandOutput), CovenantUser user = default(CovenantUser), int?gruntTaskingId = default(int?), GruntTasking gruntTasking = default(GruntTasking), int?gruntId = default(int?))
 {
     Id              = id;
     Command         = command;
     CommandTime     = commandTime;
     CommandOutputId = commandOutputId;
     CommandOutput   = commandOutput;
     UserId          = userId;
     User            = user;
     GruntTaskingId  = gruntTaskingId;
     GruntTasking    = gruntTasking;
     GruntId         = gruntId;
     CustomInit();
 }
Exemple #4
0
 /// <summary>
 /// Validate the object.
 /// </summary>
 /// <exception cref="ValidationException">
 /// Thrown if validation fails
 /// </exception>
 public virtual void Validate()
 {
     if (Command == null)
     {
         throw new ValidationException(ValidationRules.CannotBeNull, "Command");
     }
     if (UserId == null)
     {
         throw new ValidationException(ValidationRules.CannotBeNull, "UserId");
     }
     if (CommandOutput != null)
     {
         CommandOutput.Validate();
     }
     if (GruntTasking != null)
     {
         GruntTasking.Validate();
     }
 }
Exemple #5
0
 private int GetTaskingHashCode(APIModels.GruntTasking tasking)
 {
     if (tasking != null)
     {
         int code = tasking.Id ?? default;
         code ^= tasking.GruntId;
         code ^= tasking.GruntTaskId ?? default;
         code ^= tasking.GruntCommandId;
         foreach (char c in tasking.Name)
         {
             code ^= c;
         }
         foreach (char c in tasking.GruntCommand.CommandTime.ToString())
         {
             code ^= c;
         }
         return(code);
     }
     return(Guid.NewGuid().GetHashCode());
 }
Exemple #6
0
        private async Task PostStage0(APIModels.Grunt egressGrunt, APIModels.Grunt targetGrunt, ModelUtilities.GruntEncryptedMessage gruntStage0Response, string guid)
        {
            if (targetGrunt == null || !gruntStage0Response.VerifyHMAC(Convert.FromBase64String(targetGrunt.GruntSharedSecretPassword)))
            {
                // Always return NotFound, don't give away unnecessary info
                this.PushCache(guid, new GruntMessageCacheInfo {
                    Status = GruntMessageCacheStatus.NotFound, Message = "", Tasking = null
                });
                return;
            }
            bool egressGruntExists = egressGrunt != null;

            if (targetGrunt.Status != APIModels.GruntStatus.Uninitialized)
            {
                // We create a new Grunt if this one is not uninitialized
                APIModels.Grunt tempModel = new APIModels.Grunt
                {
                    Id   = 0,
                    Name = Utilities.CreateShortGuid(),
                    Guid = guid,
                    OriginalServerGuid        = Utilities.CreateShortGuid(),
                    Status                    = APIModels.GruntStatus.Stage0,
                    ListenerId                = targetGrunt.ListenerId,
                    Listener                  = targetGrunt.Listener,
                    ImplantTemplateId         = targetGrunt.ImplantTemplateId,
                    ImplantTemplate           = targetGrunt.ImplantTemplate,
                    GruntSharedSecretPassword = targetGrunt.GruntSharedSecretPassword,
                    SmbPipeName               = targetGrunt.SmbPipeName,
                    Delay                  = targetGrunt.Delay,
                    JitterPercent          = targetGrunt.JitterPercent,
                    KillDate               = targetGrunt.KillDate,
                    ConnectAttempts        = targetGrunt.ConnectAttempts,
                    DotNetFrameworkVersion = targetGrunt.DotNetFrameworkVersion,
                    LastCheckIn            = DateTime.UtcNow
                };
                targetGrunt = await _client.ApiGruntsPostAsync(tempModel);
            }
            else
            {
                targetGrunt.Status      = APIModels.GruntStatus.Stage0;
                targetGrunt.Guid        = guid;
                targetGrunt.LastCheckIn = DateTime.UtcNow;
                targetGrunt             = await _client.ApiGruntsPutAsync(targetGrunt);
            }
            if (!egressGruntExists)
            {
                egressGrunt = targetGrunt;
            }

            // EncryptedMessage is the RSA Public Key
            targetGrunt.GruntRSAPublicKey = Convert.ToBase64String(EncryptUtilities.AesDecrypt(
                                                                       gruntStage0Response,
                                                                       Convert.FromBase64String(targetGrunt.GruntSharedSecretPassword)
                                                                       ));
            // Generate negotiated session key
            using (Aes newAesKey = Aes.Create())
            {
                newAesKey.GenerateKey();
                targetGrunt.GruntNegotiatedSessionKey = Convert.ToBase64String(newAesKey.Key);
                await _client.ApiGruntsPutAsync(targetGrunt);
            }

            if (egressGruntExists)
            {
                // Add this as Child grunt to Grunt that connects it
                List <APIModels.GruntTasking> taskings = _client.ApiTaskingsGet().ToList();
                // TODO: Finding the connectTasking this way could cause race conditions, should fix w/ guid of some sort?
                APIModels.GruntTasking connectTasking = taskings.Where(GT => GT.Type == APIModels.GruntTaskingType.Connect && GT.Status == APIModels.GruntTaskingStatus.Progressed).Reverse().FirstOrDefault();
                if (connectTasking == null)
                {
                    this.PushCache(guid, new GruntMessageCacheInfo {
                        Status = GruntMessageCacheStatus.NotFound, Message = "", Tasking = null
                    });
                    return;
                }
                APIModels.GruntTaskingMessage tmessage = this.GetGruntTaskingMessage(connectTasking, targetGrunt.DotNetFrameworkVersion);
                targetGrunt.Hostname = tmessage.Message.Split(",")[0];
                await _client.ApiGruntsPutAsync(targetGrunt);

                connectTasking.Status = APIModels.GruntTaskingStatus.Completed;
                await _client.ApiTaskingsPutAsync(connectTasking);
            }

            byte[] rsaEncryptedBytes = EncryptUtilities.GruntRSAEncrypt(targetGrunt, Convert.FromBase64String(targetGrunt.GruntNegotiatedSessionKey));
            ModelUtilities.GruntEncryptedMessage message = null;
            try
            {
                message = this.CreateMessageForGrunt(egressGrunt, targetGrunt, rsaEncryptedBytes);
            }
            catch (HttpOperationException)
            {
                this.PushCache(guid, new GruntMessageCacheInfo {
                    Status = GruntMessageCacheStatus.NotFound, Message = "", Tasking = null
                });
                return;
            }
            // Transform response
            // Stage0Response: "Id,Name,Base64(IV),Base64(AES(RSA(SessionKey))),Base64(HMAC)"
            string transformed = this._utilities.ProfileTransform(_transform, Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));

            this.PushCache(guid, new GruntMessageCacheInfo {
                Status = GruntMessageCacheStatus.Ok, Message = transformed, Tasking = null
            });
            return;
        }
Exemple #7
0
        private async Task InternalRead(string guid)
        {
            try
            {
                APIModels.Grunt grunt = await CheckInGrunt(await GetGruntForGuid(guid));

                if (grunt == null)
                {
                    // Invalid GUID. May not be legitimate Grunt request, respond Ok
                    this.PushCache(guid, new GruntMessageCacheInfo {
                        Status = GruntMessageCacheStatus.Ok, Message = ""
                    });
                }
                else
                {
                    IList <APIModels.GruntTasking> gruntTaskings = await _client.ApiGruntsByIdTaskingsSearchUninitializedGetAsync(grunt.Id ?? default);

                    if (gruntTaskings == null || gruntTaskings.Count == 0)
                    {
                        // No GruntTasking assigned. Respond with empty template
                        this.PushCache(guid, new GruntMessageCacheInfo {
                            Status = GruntMessageCacheStatus.Ok, Message = ""
                        });
                    }
                    else
                    {
                        foreach (APIModels.GruntTasking tasking in gruntTaskings)
                        {
                            APIModels.GruntTasking gruntTasking = tasking;
                            if (gruntTasking.Type == APIModels.GruntTaskingType.Assembly && gruntTasking.GruntTask == null)
                            {
                                // Can't find corresponding task. Should never reach this point. Will just respond NotFound.
                                this.PushCache(guid, new GruntMessageCacheInfo {
                                    Status = GruntMessageCacheStatus.NotFound, Message = "", Tasking = gruntTasking
                                });
                            }
                            else
                            {
                                gruntTasking.Grunt = gruntTasking.GruntId == grunt.Id ? grunt : await _client.ApiGruntsByIdGetAsync(gruntTasking.GruntId);

                                ModelUtilities.GruntEncryptedMessage message = null;
                                try
                                {
                                    message = this.CreateMessageForGrunt(grunt, gruntTasking.Grunt, this.GetGruntTaskingMessage(gruntTasking, gruntTasking.Grunt.DotNetFrameworkVersion));
                                    // Transform response
                                    string transformed = this._utilities.ProfileTransform(_transform, Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));
                                    this.PushCache(guid, new GruntMessageCacheInfo {
                                        Status = GruntMessageCacheStatus.Ok, Message = transformed, Tasking = gruntTasking
                                    });
                                }
                                catch (HttpOperationException)
                                {
                                    gruntTasking.Status = APIModels.GruntTaskingStatus.Aborted;
                                    await _client.ApiTaskingsPutAsync(gruntTasking);

                                    this.PushCache(guid, new GruntMessageCacheInfo {
                                        Status = GruntMessageCacheStatus.NotFound, Message = "", Tasking = null
                                    });
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                this.PushCache(guid, new GruntMessageCacheInfo {
                    Status = GruntMessageCacheStatus.NotFound, Message = ""
                });
            }
        }