コード例 #1
0
        public static void NotifyConnection(String target, String status)
        {
            if (ServerComms.IsVerboseOn())
            {
                ServerComms.LogMessage($"Message has arrived back for {target}");
            }

            if (!mapTargetIdToSocksInstance.ContainsKey(target))
            {
                ServerComms.LogError($"Target {target} not found in Socks instance");
                return;
            }
            var socksInstance = mapTargetIdToSocksInstance[target];

            if (status.ToLower() == "open")
            {
                socksInstance._open = true;
            }
            else
            {
                socksInstance._open = false;
            }

            socksInstance.status         = status;
            socksInstance.LastUpdateTime = DateTime.Now;

            if (socksInstance._waitOnConnect)
            {
                socksInstance.SocksTimeout.Set();
            }
        }
コード例 #2
0
        void WriteResponseBackToClient(List <byte> payload)
        {
            _dataRecv += payload.Count();

            if (_tc.Connected)
            {
                try
                {
                    var stream = _tc.GetStream();
                    stream.Write(payload.ToArray(), 0, payload.Count);
                    stream.Flush();
                    ServerComms.LogMessage($"Recieved payload back from Implant (size: {payload.Count} for {_targetId} writing to client");
                    if (ServerComms.IsVerboseOn())
                    {
                        ServerComms.LogMessage($"Wrote {payload.Count} ");
                    }
                    if (!_tc.Connected)
                    {
                        ShutdownClient();
                    }
                }
                catch (Exception ex)
                {
                    ServerComms.LogMessage($"ERROR Writing data back to {ex.Message}");
                    ShutdownClient();
                }
            }
            else
            {
                ShutdownClient();
            }
        }
コード例 #3
0
        void StartCommsWithProxyAndImplant(NetworkStream stream)
        {
            var          timeoutd = false;
            IAsyncResult result   = null;
            var          buf      = new byte[1];

            try
            {
                var asyncBufferState = new AsyncBufferState()
                {
                    Buffer = new Byte[HEADERLIMIT], Stream = stream, RecvdData = new AutoResetEvent(false)
                };
                var dataRecvd = asyncBufferState.RecvdData;
                var ctr       = 0;
                while (!ShutdownRecieved)
                {
                    try
                    {
                        if (ShutdownRecieved)
                        {
                            return;
                        }

                        //Use peek to try and force an exception if the connection has closed
                        _tc.Client.Receive(buf, SocketFlags.Peek);
                        if (stream.CanRead && stream.DataAvailable)
                        {
                            result   = stream.BeginRead(asyncBufferState.Buffer, 0, HEADERLIMIT, ProxySocketReadCallback, asyncBufferState);
                            timeoutd = !dataRecvd.WaitOne((int)TOTALSOCKETTIMEOUT);
                            ctr      = 0;
                        }
                        else
                        {
                            TimeoutEvent.WaitOne(50);
                        }
                    }
                    catch (Exception ex)
                    {
                        ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped: {ex.Message}");
                        ShutdownClient();
                        return;
                    }

                    if (ctr++ >= ((int)TOTALSOCKETTIMEOUT / 100))
                    {
                        stream.Close();
                        //Time out trying to read may as well shutdown the socket
                        ServerComms.LogError($"Connection closed to {_targetHost}:{_targetPort} after ({TOTALSOCKETTIMEOUT / 1000}s) idle. {_targetId}");
                        ShutdownClient();
                        return;
                    }
                }
            }
            catch (Exception ex)
            {
                ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped: {ex.Message}");
                ShutdownClient();
            }
        }
コード例 #4
0
        public static bool ReturnDataCallback(String target, List <byte> payload)
        {
            if (!mapTargetIdToSocksInstance.ContainsKey(target))
            {
                ServerComms.LogError($"Target {target} not found in Socks instance");
                return(false);
            }

            var socksInstance = mapTargetIdToSocksInstance[target];

            socksInstance.WriteResponseBackToClient(payload);
            return(true);
        }
コード例 #5
0
        void CreateImplantSocksRequest()
        {
            ServerComms.LogMessage($"SOCKS Request to open {_targetHost}:{_targetPort}");
            status         = "opening";
            LastUpdateTime = DateTime.Now;

            _targetId = SocketComms.CreateNewConnectionTarget(_targetHost, _targetPort);
            var thisptr = this;

            if (null == thisptr)
            {
                ServerComms.LogError("This pointer is NULL something wrong here");
            }

            mapTargetIdToSocksInstance.TryAdd(_targetId, thisptr);
        }
コード例 #6
0
 void WriteResponseBackToClient(List <byte> payload)
 {
     _dataRecv += payload.Count();
     ServerComms.LogMessage($"Recieved payload back from Implant (size: {payload.Count} for {_targetId} writing to client");
     if (_tc.Connected)
     {
         var stream = _tc.GetStream();
         stream.Write(payload.ToArray(), 0, payload.Count);
         stream.Flush();
         StartCommsWithProxyAndImplant(stream);
     }
     else
     {
         ShutdownClient();
     }
 }
コード例 #7
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}");
                }
            });
        }
コード例 #8
0
        void AcceptTcpClient(IAsyncResult iar)
        {
            var tcs = (TcpListener)iar.AsyncState;

            TcpClient tc = null;

            try
            {
                tc = tcs.EndAcceptTcpClient(iar);
            }
            catch (Exception ex)
            {
                if (_serverComms.IsVerboseOn())
                {
                    _serverComms.LogError($"Initial SOCKS Read failed for endpoint {tcs.LocalEndpoint.ToString()} {ex.Message}".Trim());
                }
                return;
            }
            Task.Factory.StartNew(() =>
            {
                try
                {
                    if (ServerComms.IsVerboseOn())
                    {
                        ServerComms.LogMessage($"Message arrived {tcs.LocalEndpoint.ToString()} from {tc.Client.RemoteEndPoint.ToString()}".Trim());
                    }
                    (new SocksProxy()
                    {
                        TOTALSOCKETTIMEOUT = SocketTimeout
                    }).ProcessRequest(tc, WaitOnConnect);
                }
                catch (Exception ex)
                {
                    ServerComms.LogError($"Error occured on EndPoint {tcs.LocalEndpoint.ToString()} shutting down cause of {ex.Message}".Trim());
                    if (tc.Connected)
                    {
                        tc.Close();
                    }
                    return;
                }
            });

            tcs.BeginAcceptTcpClient(AcceptTcpClient, tcs);
        }
コード例 #9
0
        bool StartSocksInternal(String ipToListen, ushort localPort)
        {
            TcpListener tcs = null;

            try
            {
                var socksIp = ("*" == ipToListen) ? IPAddress.Any : IPAddress.Parse(ipToListen);
                tcs = new TcpListener(socksIp, localPort);
                _listeners.Add(localPort, tcs);
                tcs.Start();
                ServerComms.LogMessage($"Socks proxy listening started on {socksIp.ToString()}:{localPort}");
            }
            catch (Exception ex)
            {
                ServerComms.LogError($"StartSocks {ex.Message}");
                return(false);
            }
            tcs.BeginAcceptTcpClient(AcceptTcpClient, tcs);
            return(true);
        }
コード例 #10
0
        void ShutdownClient(bool implantNotified = false)
        {
            status         = (implantNotified) ? "closing (implant called close)" : "closing (SOCKS timeout)";
            LastUpdateTime = DateTime.Now;
            _open          = false;
            if (!ShutdownRecieved)
            {
                lock (_shutdownLocker)
                {
                    if (!ShutdownRecieved)
                    {
                        ShutdownRecieved = true;
                        if (null != _tc && _tc.Connected)
                        {
                            _tc.Close();
                        }

                        if (!String.IsNullOrWhiteSpace(_targetId) && !implantNotified)
                        {
                            SocketComms.CloseTargetConnection(_targetId);
                        }
                    }
                }
            }
            if (mapTargetIdToSocksInstance.ContainsKey(_targetId))
            {
                if (!mapTargetIdToSocksInstance.TryRemove(_targetId, out SocksProxy scks))
                {
                    ServerComms.LogError($"Couldn't mark {_targetId} as an invalid session");
                }
            }

            if (null == TimeoutEvent)
            {
                TimeoutEvent.Close();
                TimeoutEvent = null;
            }
        }
コード例 #11
0
        public bool StartSocks(String ipToListen, ushort localPort, IServiceController controller, ManualResetEvent cmdChannelRunning = null)
        {
            _controller = controller;
            var onOff = (WaitOnConnect) ? "on" : "off";

            ServerComms.LogMessage($"Wait for Implant TCP Connect before SOCKS Proxy response is {onOff}");

            if (null != cmdChannelRunning)
            {
                Task.Factory.StartNew(() =>
                {
                    ServerComms.LogMessage($"Waiting for command channel before starting SOCKS proxy");
                    cmdChannelRunning.WaitOne();
                    StartSocksInternal(ipToListen, localPort);
                });
            }
            else
            {
                return(StartSocksInternal(ipToListen, localPort));
            }

            return(true);
        }
コード例 #12
0
        byte ProcessSocks4Headers(List <byte> buffer)
        {
            if (9 > buffer.Count || 256 < buffer.Count)
            {
                ServerComms.LogError($"Socks server: buffer size {buffer.Count} is not valid, must be between 9 & 256");
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
            }

            byte commandCode = buffer.Skip(1).Take(1).First();

            BitConverter.ToUInt16(buffer.Skip(2).Take(2).ToArray(), 0);
            BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0);
            _targetPort = BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0);
            var dstIp = buffer.Skip(4).Take(4).ToArray();

            var tailBuffer = buffer.Skip(8);
            var endUserIdx = tailBuffer.ToList().IndexOf(0x0) + 1;

            if (-1 == endUserIdx)
            {
                ServerComms.LogError($"User id is invalid rejecting connection request");
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
            }
            var userId = UTF8Encoding.UTF8.GetString(tailBuffer.Take(endUserIdx).ToArray());

            //Check if SOCKS 4a and domain name specified
            //If the domain name is to follow the IP will be in the format 0.0.0.x
            if (0 == dstIp[0] && 0 == dstIp[1] && 0 == dstIp[2] && 0 != dstIp[3])
            {
                var endHostIdx = tailBuffer.Skip(endUserIdx).ToList().IndexOf(0x0);
                var arrayHost  = tailBuffer.Skip(endUserIdx).Take(endHostIdx).ToArray();
                if (arrayHost.Length == 0)
                {
                    ServerComms.LogError($"Host name is empty rejecting connection request");
                    return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                }
                var dnsHost = UTF8Encoding.UTF8.GetString(arrayHost);
                if (UriHostNameType.Unknown == Uri.CheckHostName(dnsHost))
                {
                    ServerComms.LogError($"Host name {dnsHost} is invalid rejecting connection request");
                    return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                }
                _targetHost = dnsHost;
            }
            else
            {
                _targetHost = new IPAddress(BitConverter.ToUInt32(dstIp, 0)).ToString();
            }

            CreateImplantSocksRequest();

            SocksTimeout.WaitOne(SOCKSCONNECTIONTOOPENTIMEOUT);
            if (!_open)
            {
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
            }
            else
            {
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_GRANTED);
            }
        }
コード例 #13
0
        List <byte> ProcessSocks5Headers(List <byte> buffer, NetworkStream stream, out bool success)
        {
            success = false;
            var authCount = (int)buffer.Skip(1).Take(1).First();
            var authTypes = new List <byte>();

            for (var i = 0; i < authCount; i++)
            {
                authTypes.Add(buffer.Skip(2 + i).Take(1).First());
            }

            //Don't need any auth just send back 0x0 for 'NO AUTH REQUIRED'
            stream.WriteByte(Socks5Headers.Version);
            stream.WriteByte((byte)Socks5Headers.Socks5RequestAuthType.NoneRequired);
            stream.Flush();

            var lstBuffer = readFromStream(stream);
            var response  = new List <byte>();

            if (9 > lstBuffer.Count || 260 < lstBuffer.Count)
            {
                ServerComms.LogError($"Socks server: buffer size {buffer.Count} is not valid, must be between 9 & 256");
                return(SOCKS5FAILEDRESPONSE);
            }

            /*Second Packet
             * o VER protocol version: X'05'
             * o CMD
             * o RSV    RESERVED
             * o ATYP address type of following address
             * o DST.ADDR desired destination address
             * o DST.PORT desired destination port in network octet order
             */

            var cmd = (Socks5Headers.Socks5RequestCommand)lstBuffer.Skip(1).Take(1).First();

            //Only connect supported at the moment
            if (cmd != Socks5Headers.Socks5RequestCommand.CONNECT)
            {
                ServerComms.LogError($"SOCKS5 Command Type {Enum.GetName(typeof(Socks5Headers.Socks5RequestCommand), cmd)} is not supported");
                response.AddRange(SOCKS5FAILEDRESPONSE);
                response[1] = (byte)Socks5Headers.Socks5ResponseReplyStatus.commandNotSuppported;
                return(response);
            }

            IEnumerable <byte> portByts = null;
            var ATYP = (Socks5Headers.Socks5RequestAddressType)lstBuffer.Skip(3).Take(1).First();

            switch (ATYP)
            {
            case Socks5Headers.Socks5RequestAddressType.IPV4:                     //IP Address
                var dstIp = lstBuffer.Skip(4).Take(4).ToArray();
                _targetHost = new IPAddress(BitConverter.ToUInt32(dstIp, 0)).ToString();
                portByts    = lstBuffer.Skip(8).Take(2);
                _targetPort = BitConverter.ToUInt16(portByts.Reverse().ToArray(), 0);
                response.AddRange(SOCKS5SUCCESSRESPONSE);
                response.Add((byte)Socks5Headers.Socks5RequestAddressType.IPV4);
                response.AddRange(dstIp);
                response.AddRange(portByts);
                break;

            case Socks5Headers.Socks5RequestAddressType.DOMAINNAME:                     //Domain Name
                var endHostIdx = lstBuffer.Skip(4).Take(1).First();
                var arrayHost  = lstBuffer.Skip(5).Take(endHostIdx).ToArray();
                if (arrayHost.Length == 0)
                {
                    ServerComms.LogError($"Host name is empty rejecting connection request");
                    response.AddRange(SOCKS5FAILEDRESPONSE);
                    response[1] = (byte)Socks5Headers.Socks5ResponseReplyStatus.hostUnreachable;
                    response.Add((byte)Socks5Headers.Socks5RequestAddressType.DOMAINNAME);
                    return(response);
                }
                var dnsHost = UTF8Encoding.UTF8.GetString(arrayHost);
                if (UriHostNameType.Unknown == Uri.CheckHostName(dnsHost))
                {
                    ServerComms.LogError($"Host name {dnsHost} is invalid rejecting connection request");
                    response.AddRange(SOCKS5FAILEDRESPONSE);
                    response[1] = (byte)Socks5Headers.Socks5ResponseReplyStatus.hostUnreachable;
                    response.Add((byte)Socks5Headers.Socks5RequestAddressType.DOMAINNAME);
                    return(response);
                }
                _targetHost = dnsHost;

                portByts    = lstBuffer.Skip(endHostIdx + 5).Take(2);
                _targetPort = BitConverter.ToUInt16(portByts.Reverse().ToArray(), 0);
                response.AddRange(SOCKS5SUCCESSRESPONSE);
                response.Add((byte)Socks5Headers.Socks5RequestAddressType.IPV4);
                response.AddRange(new List <byte>()
                {
                    0x0, 0x0, 0x0, 0x0, 0x0, 0x0
                });

                /*response.Add(endHostIdx);
                 * response.AddRange(arrayHost);
                 * response.AddRange(portByts);*/
                break;
            }
            CreateImplantSocksRequest();
            SocksTimeout.WaitOne(SOCKSCONNECTIONTOOPENTIMEOUT);
            if (!(success = _open))
            {
                response[1] = (byte)Socks5Headers.Socks5ResponseReplyStatus.networkUnreachable;
            }
            return(response);
        }
コード例 #14
0
        void ProxySocketReadCallback(IAsyncResult iar)
        {
            var asyncState = (AsyncBufferState)iar.AsyncState;

            try
            {
                var stream    = asyncState.Stream;
                int bytesRead = stream.EndRead(iar);
                if (ShutdownRecieved || null == _tc)
                {
                    return;
                }

                if (!_tc.Connected)
                {
                    ShutdownClient();
                    try
                    {
                        if (_tc.Client != null)
                        {
                            ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} closed");
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} closed");
                    }
                    return;
                }
                if (bytesRead > 0)
                {
                    var payload = new List <byte>();
                    payload.AddRange(asyncState.Buffer.Take(bytesRead));
                    while (stream.CanRead && stream.DataAvailable)
                    {
                        if ((bytesRead = stream.Read(asyncState.Buffer, 0, HEADERLIMIT)) > 0)
                        {
                            payload.AddRange(asyncState.Buffer.Take(bytesRead));
                        }
                    }

                    SocketComms.SendDataToTarget(_targetId, payload);
                    ServerComms.LogMessage($"Client sent data (size: {payload.Count}) {_targetId} writing to Implant");
                    _dataSent += payload.Count;
                }
            }
            catch (Exception ex)
            {
                try
                {
                    if (_tc.Client != null)
                    {
                        ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} has dropped cause {ex.Message}");
                    }
                }
                catch (ObjectDisposedException)
                {
                    ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped cause {ex.Message}");
                }
                ShutdownClient();
            }
            finally
            {
                asyncState.RecvdData.Set();
            }
        }
コード例 #15
0
        public void ProcessRequest(TcpClient tc, bool waitOnConnect = false)
        {
            _tc = tc;
            var stream = _tc.GetStream();

            _waitOnConnect = waitOnConnect;

            if (!stream.CanRead)
            {
                if (tc.Client.RemoteEndPoint is IPEndPoint enp)
                {
                    ServerComms.LogError($"Failed reading SOCKS Connection from {IPAddress.Parse(enp.Address.ToString())}:{enp.Port.ToString()}");
                }
                return;
            }

            try
            {
                var bytesRead   = 0;
                var lstBuffer   = new List <byte>();
                var arrayBuffer = new byte[512000];

                bytesRead = stream.Read(arrayBuffer, 0, 512000);
                lstBuffer.AddRange(arrayBuffer.Take(bytesRead));

                while (stream.CanRead && stream.DataAvailable)
                {
                    bytesRead = stream.Read(arrayBuffer, 0, 512000);
                    lstBuffer.AddRange(arrayBuffer.Take(bytesRead));
                }

                List <byte> responsePacket = null;
                byte        procResult = 0x0, version = 0x0;
                bool        socks5success = false;
                if (lstBuffer.Count == 0)
                {
                    ServerComms.LogError($"Socks server: buffer size {lstBuffer.Count} is not valid, must be between 9 & 256");
                    responsePacket = BuildSocks4Response(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                }
                else
                {
                    version = lstBuffer[0];
                    if (version == 0x4)
                    {
                        procResult     = ProcessSocks4Headers(lstBuffer.ToList());
                        responsePacket = BuildSocks4Response(procResult);
                    }
                    else if (version == 0x5)
                    {
                        responsePacket = ProcessSocks5Headers(lstBuffer.ToList(), stream, out socks5success);
                    }
                }

                stream.Write(responsePacket.ToArray(), 0, responsePacket.Count);
                stream.Flush();

                if (Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_GRANTED == procResult || socks5success)
                {
                    System.Threading.Tasks.Task.Factory.StartNew(() => StartCommsWithProxyAndImplant(stream));
                }
                else
                {
                    _tc.Close();
                }
                return;
            }
            catch
            {
                if (tc.Client.RemoteEndPoint is IPEndPoint enp)
                {
                    ServerComms.LogError($"Failed reading SOCKS Connection from {IPAddress.Parse(enp.Address.ToString())}:{enp.Port.ToString()}");
                }
            }
        }
コード例 #16
0
ファイル: SocksProxy.cs プロジェクト: y35uishere/SharpSocks
        public void ProcessRequest(TcpClient tc, bool waitOnConnect = false)
        {
            _tc = tc;
            var  stream     = _tc.GetStream();
            var  timeout    = 0;
            var  timeoutCtr = 0;
            bool timedOut   = false;

            _waitOnConnect = waitOnConnect;

            if (!stream.CanRead)
            {
                if (ServerComms.IsVerboseOn())
                {
                    ServerComms.LogError($"Something attempted to connect but can't read from the stream");
                }
            }

            while (!timedOut)
            {
                if (!stream.DataAvailable)
                {
                    if (1 == timeoutCtr)
                    {
                        timeout += TIMEBETWEENREADS;
                    }

                    TimeoutEvent.WaitOne(timeout);

                    if (timeoutCtr > (SOCKSCONNECTIONTOREADTIMEOUT / TIMEBETWEENREADS))
                    {
                        //Time out trying to read may as well shutdown the socket
                        ServerComms.LogError($"Timed out ({SOCKSCONNECTIONTOREADTIMEOUT / 1000}s) trying to read from SOCKS conection");
                        status         = "closing (SOCKS time out)";
                        LastUpdateTime = DateTime.Now;
                        return;
                    }
                    timeoutCtr++;
                }
                else
                {
                    var bytesRead   = 0;
                    var lstBuffer   = new List <byte>();
                    var arrayBuffer = new byte[tc.Available];

                    bytesRead = stream.Read(arrayBuffer, 0, tc.Available);
                    lstBuffer.AddRange(arrayBuffer);

                    while (bytesRead > 0 && stream.DataAvailable)
                    {
                        arrayBuffer = new byte[tc.Available];
                        bytesRead  += stream.Read(arrayBuffer, 0, tc.Available);
                        lstBuffer.AddRange(arrayBuffer);
                    }

                    var procResult     = ProcessSocksHeaders(lstBuffer.ToList());
                    var responsePacket = BuildSocks4Response(procResult);

                    stream.Write(responsePacket.ToArray(), 0, responsePacket.Count);
                    stream.Flush();

                    if (Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_GRANTED == procResult)
                    {
                        StartCommsWithProxyAndImplant(stream);
                    }
                    else
                    {
                        _tc.Close();
                    }

                    return;
                }
            }
        }
コード例 #17
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}");
            }
        }
コード例 #18
0
ファイル: SocksProxy.cs プロジェクト: y35uishere/SharpSocks
        byte ProcessSocksHeaders(List <byte> buffer)
        {
            if (9 > buffer.Count || 256 < buffer.Count)
            {
                ServerComms.LogError($"Socks server: buffer size {buffer.Count} is not valid, must be between 9 & 256");
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
            }
            byte version = buffer[0];

            if (version == 0x4)
            {
                byte commandCode = buffer.Skip(1).Take(1).First();
                BitConverter.ToUInt16(buffer.Skip(2).Take(2).ToArray(), 0);
                BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0);
                _targetPort = BitConverter.ToUInt16(buffer.Skip(2).Take(2).Reverse().ToArray(), 0);
                var dstIp = buffer.Skip(4).Take(4).ToArray();

                var tailBuffer = buffer.Skip(8);
                var endUserIdx = tailBuffer.ToList().IndexOf(0x0) + 1;
                if (-1 == endUserIdx)
                {
                    ServerComms.LogError($"User id is invalid rejecting connection request");
                    return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                }
                var userId = UTF8Encoding.UTF8.GetString(tailBuffer.Take(endUserIdx).ToArray());

                //Check if SOCKS 4a and domain name specified
                //If the domain name is to follow the IP will be in the format 0.0.0.x
                if (0 == dstIp[0] && 0 == dstIp[1] && 0 == dstIp[2] && 0 != dstIp[3])
                {
                    var endHostIdx = tailBuffer.Skip(endUserIdx).ToList().IndexOf(0x0);
                    var arrayHost  = tailBuffer.Skip(endUserIdx).Take(endHostIdx).ToArray();
                    if (arrayHost.Length == 0)
                    {
                        ServerComms.LogError($"Host name is empty rejecting connection request");
                        return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                    }
                    var dnsHost = UTF8Encoding.UTF8.GetString(arrayHost);
                    if (UriHostNameType.Unknown == Uri.CheckHostName(dnsHost))
                    {
                        ServerComms.LogError($"Host name {dnsHost} is invalid rejecting connection request");
                        return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                    }
                    _targetHost = dnsHost;
                }
                else
                {
                    _targetHost = new IPAddress(BitConverter.ToUInt32(dstIp, 0)).ToString();
                }

                ServerComms.LogMessage($"SOCKS Request to open {_targetHost}:{_targetPort}");
                status         = "opening";
                LastUpdateTime = DateTime.Now;

                _targetId = SocketComms.CreateNewConnectionTarget(_targetHost, _targetPort);
                var thisptr = this;
                if (null == thisptr)
                {
                    ServerComms.LogError("This pointer is NULL something wrong here");
                }

                mapTargetIdToSocksInstance.Add(_targetId, thisptr);

                if (_waitOnConnect)
                {
                    SocksTimeout.WaitOne(SOCKSCONNECTIONTOOPENTIMEOUT);
                    if (!_open)
                    {
                        return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
                    }
                }
            }
            else
            {
                return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_REJECTED_OR_FAILED);
            }

            ServerComms.LogMessage($"Opened SOCKS port {_targetHost}:{_targetPort} targetid {_targetId}");
            return(Socks4ClientHeader.Socks4ClientHeaderStatus.REQUEST_GRANTED);
        }
コード例 #19
0
ファイル: SocksProxy.cs プロジェクト: y35uishere/SharpSocks
        void ProxySocketReadCallback(IAsyncResult iar)
        {
            var asyncState = (AsyncBufferState)iar.AsyncState;
            var stream     = asyncState.Stream;
            int bytesRead  = 0;

            if (ShutdownRecieved || null == _tc)
            {
                return;
            }

            if (!_tc.Connected)
            {
                ShutdownClient();
                try
                {
                    if (_tc.Client != null)
                    {
                        ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} closed");
                    }
                }
                catch (ObjectDisposedException)
                {
                    ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} closed");
                }
                return;
            }
            try
            {
                bytesRead  = stream.EndRead(iar);
                _dataSent += bytesRead;

                if (bytesRead > 0)
                {
                    var payload = new List <byte>();
                    payload.AddRange(asyncState.Buffer.Take(bytesRead));
                    Array.Clear(asyncState.Buffer, 0, asyncState.Buffer.Length);
                    while (stream.CanRead && stream.DataAvailable && (bytesRead = stream.Read(asyncState.Buffer, 0, HEADERLIMIT)) > 0)
                    {
                        payload.AddRange(asyncState.Buffer.Take(bytesRead));
                        Array.Clear(asyncState.Buffer, 0, asyncState.Buffer.Length);
                    }
                    //Not currently reading now so if anything comes in fair play
                    Interlocked.Decrement(ref CurrentlyReading);
                    ServerComms.LogMessage($"Client sent data (size: {payload.Count}) {_targetId} writing to Implant");
                    SocketComms.SendDataToTarget(_targetId, payload);
                    StartCommsWithProxyAndImplant(asyncState.Stream);
                }
                else
                {
                    //No bytes have been read from the connection
                    //Try again and start the thread timeout cycle
                    Interlocked.Decrement(ref CurrentlyReading);
                    TimeoutEvent.WaitOne(timeout);
                    StartCommsWithProxyAndImplant(asyncState.Stream);
                }
            }
            catch (Exception ex)
            {
                try
                {
                    if (_tc.Client != null)
                    {
                        ServerComms.LogError($"Connection to {_tc.Client.RemoteEndPoint.ToString()} has dropped cause {ex.Message}");
                    }
                }
                catch (ObjectDisposedException)
                {
                    ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped cause {ex.Message}");
                }
                ShutdownClient();
            }
        }
コード例 #20
0
ファイル: SocksProxy.cs プロジェクト: y35uishere/SharpSocks
        void StartCommsWithProxyAndImplant(NetworkStream stream)
        {
            //Check the currently flag as we multiple threads can hit this
            //Interlocked uses an atomic. If there is a thread already reading just bang out here
            if ((Interlocked.CompareExchange(ref CurrentlyReading, 1, 0) == 1))
            {
                return;
            }

            var timeout    = 0;
            var timeoutCtr = 0;
            var wait       = new AutoResetEvent(false);

            //Shutdown has been recieved on another thread we outta here
            while (!ShutdownRecieved)
            {
                if (!stream.DataAvailable)
                {
                    if (1 == timeoutCtr)
                    {
                        timeout += TIMEBETWEENREADS;
                    }

                    TimeoutEvent.WaitOne(timeout);
                }
                else
                {
                    if (!stream.CanRead || !_tc.Connected)
                    {
                        ShutdownClient();
                        ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped before data sent");
                        return;
                    }
                    try
                    {
                        //Quick check here just in case....
                        if (ShutdownRecieved)
                        {
                            return;
                        }
                        var asyncBufferState = new AsyncBufferState()
                        {
                            Stream = stream, RecvdData = wait
                        };
                        stream.BeginRead(asyncBufferState.Buffer, 0, HEADERLIMIT, ProxySocketReadCallback, asyncBufferState);
                        wait.WaitOne(-1);
                    }
                    catch (Exception ex)
                    {
                        ServerComms.LogError($"Connection to {_targetHost}:{_targetPort} has dropped: {ex.Message}");
                        ShutdownClient();
                    }
                }

                if (timeoutCtr > (TOTALSOCKETTIMEOUT / TIMEBETWEENREADS))
                {
                    //Time out trying to read may as well shutdown the socket
                    ServerComms.LogError($"Connection closed to {_targetHost}:{_targetPort} after ({TOTALSOCKETTIMEOUT / 1000}s) idle. {_targetId}");

                    ShutdownClient();
                    return;
                }
                timeoutCtr++;
            }
        }