Exemple #1
0
        private bool DispatchRequest(Request request)
        {
            bool bRet = false;

            switch (request.Command)
            {
            case ConnectCommand:
                var        bind          = new AddrSpec();
                int        bindPort      = rnd.Next(65000, 65536);
                IPEndPoint localEndpoint = new IPEndPoint(localhostIPAddr, bindPort);
                bind.FQDN = "";
                bind.IP   = localhostIPAddr;
                bind.Port = bindPort;
                Socket target;
                try
                {
                    if (request.DestAddr.IP.AddressFamily == AddressFamily.InterNetwork)
                    {
                        target = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    }
                    else
                    {
                        target = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                    }
                }
                catch (Exception ex)
                {
                    throw new SocksException("Failed to create socket for address.", SocksError.ConnectionRefused);
                }
                //target.Bind(localEndpoint);

                //TcpClient target = new TcpClient(localEndpoint);
                try
                {
                    target.Connect(request.DestAddr.IP.ToString(), request.DestAddr.Port);
                }
                catch (Exception ex)
                {
                    throw new SocksException($"Failed on client connect to {request.DestAddr.IP.ToString()}", SocksError.HostUnreachable, ex);
                }
                bRet = true;
                //DebugWriteLine($"Successfully connected to {request.DestAddr.IP.ToString()}");
                ClientConnection = target;
                Bind             = bind;
                //var msgToSend = CreateFormattedMessageWithLength(SocksError.SuccessReply, bind, conn);
                //AddMythicMessageToQueue(msgToSend);
                //new Thread(() => conn.StartRelay()).Start();
                break;

            default:
                throw new SocksException($"Command not supported: {request.Command}", SocksError.CommandNotSupported);
            }
            return(bRet);
        }
Exemple #2
0
        private Request ParseAddrSpec(byte[] data)
        {
            int dataIndex   = 0;
            int headerIndex = 0;

            byte[]    header   = new byte[3];
            byte[]    address  = null;
            IPAddress targetIP = null;
            int       targetPort;
            AddrSpec  addrSpec = new AddrSpec()
            {
                FQDN = "", IP = null, Port = -1
            };
            SocksError errorResponse;

            if (data.Length <= 1)
            {
                throw new SocksException("Datagram was an invalid length.", SocksError.InvalidDatagram);
            }
            if (data.Length < 3)
            {
                throw new SocksException("Datagram was an invalid length.", SocksError.InvalidDatagram);
            }

            Array.Copy(data, header, 3);
            dataIndex += 3;
            // gonna assume this means fail to read header
            if (header[0] != socks5Version)
            {
                throw new SocksException($"Got header frame requesting invalid SOCKS version {header[0]}.", SocksError.CommandNotSupported);
            }
            AddressType ipType = (AddressType)data[dataIndex];

            dataIndex += 1;
            switch (ipType)
            {
            case AddressType.IPv4Address:
                address = new byte[4];
                Array.Copy(data, dataIndex, address, 0, 4);
                targetIP   = new IPAddress(address);
                dataIndex += 4;
                addrSpec   = new AddrSpec()
                {
                    FQDN = "",
                    IP   = targetIP
                };
                break;

            case AddressType.IPV6Address:
                address = new byte[16];
                Array.Copy(data, dataIndex, address, 0, 16);
                targetIP   = new IPAddress(address);
                dataIndex += 16;
                addrSpec   = new AddrSpec()
                {
                    FQDN = "",
                    IP   = targetIP,
                };
                break;

            case AddressType.FQDNAddress:
                int addrLength = data[dataIndex];
                dataIndex += 1;
                byte[] fqdnBytes = new byte[addrLength];
                Array.Copy(data, dataIndex, fqdnBytes, 0, addrLength);
                dataIndex += addrLength;
                string fqdn = Encoding.UTF8.GetString(fqdnBytes);
                try
                {
                    var ipEntry = Dns.GetHostEntry(fqdn);
                    if (ipEntry.AddressList.Length == 0)
                    {
                        break;
                    }
                    foreach (var ipaddr in ipEntry.AddressList)
                    {
                        if (ipaddr.ToString().Contains("."))
                        {
                            targetIP = ipaddr;
                            break;
                        }
                    }
                    if (targetIP == null)
                    {
                        targetIP = ipEntry.AddressList[0];
                    }
                    addrSpec = new AddrSpec()
                    {
                        FQDN = fqdn,
                        IP   = targetIP
                    };
                    break;
                }
                catch (Exception ex)
                {
                    //DebugWriteLine($"Error while resolving FQDN: {ex.Message}");
                    //if (ByteSequenceEquals(data, new byte[] { 5, 1, 0, 5}) || ByteSequenceEquals(data, new byte[] { 5,2,0,2}))
                    //{
                    //    var msg = new SocksDatagram()
                    //    {
                    //        server_id = conn.ServerID,
                    //        data = Convert.ToBase64String(new byte[] { 5, 0 })
                    //    };
                    //    AddMythicMessageToQueue(msg);
                    //}
                    //new Thread(() => RemoveProxyConnection(conn)).Start();
                    break;
                }

            default:
                //DebugWriteLine("AddrType was not IPv4, IPv6, or FQDN!");
                //if (ByteSequenceEquals(data, new byte[] { 5, 1, 0, 5 }) || ByteSequenceEquals(data, new byte[] { 5, 2, 0, 2 }))
                //{
                //    var msg = new SocksDatagram()
                //    {
                //        server_id = conn.ServerID,
                //        data = Convert.ToBase64String(new byte[] { 5, 0 })
                //    };
                //    AddMythicMessageToQueue(msg);
                //}
                //new Thread(() => RemoveProxyConnection(conn)).Start();
                break;
            }
            if (targetIP == null)
            {
                throw new SocksException(SocksError.AddrTypeNotSupported);
            }
            if (data.Length < (dataIndex + 2))
            {
                throw new SocksException(SocksError.ServerFailure);
            }

            byte[] portBytes = new byte[2];
            Array.Copy(data, dataIndex, portBytes, 0, 2);
            dataIndex    += 2;
            targetPort    = ((int)portBytes[0] << 8) | (int)portBytes[1];
            addrSpec.Port = targetPort;

            Request request = new Request()
            {
                Version  = socks5Version,
                Command  = header[1],
                DestAddr = addrSpec,
                //BufCon = conn
            };
            int      clientPort = rnd.Next(60000, 65536);
            AddrSpec clientAddr = new AddrSpec()
            {
                FQDN = "",
                IP   = System.Net.IPAddress.Parse("127.0.0.1"),
                Port = clientPort
            };

            request.RemoteAddr = clientAddr;
            IPAddress destIPAddr;

            if (request.DestAddr.FQDN != "")
            {
                if (request.DestAddr.IP == null)
                {
                    //DebugWriteLine("About to resolve FQDN");
                    var dnsEntry = Dns.GetHostEntry(request.DestAddr.FQDN);
                    if (dnsEntry.AddressList.Length == 0)
                    {
                        throw new SocksException(SocksError.HostUnreachable);
                    }
                    request.DestAddr.IP = dnsEntry.AddressList[0];
                }
            }

            return(request);
        }