Exemple #1
0
        // Complete the forward proxy connection if a proxy is configured and also
        // send any buffered data from the client to the server.
        void FinishConnection(Byte[] extraData, UInt32 offset, UInt32 length)
        {
            if (AppLayerProxy.ForwardProxy != null)
            {
                serverSocket.Blocking = true;
                BufStruct buf = default(BufStruct);
                AppLayerProxy.ForwardProxy.ProxyConnectTcp(serverSocket, ref serverEndPointForProxy,
                                                           isConnect ? 0 : ProxyConnectOptions.ContentIsRawHttp, ref buf);
                if (buf.contentLength > 0)
                {
                    throw new NotImplementedException("The proxy connection left over some data from the server, this is not currently being handled");
                }
            }
            if (isConnect)
            {
                clientSocket.Send(HttpVars.ConnectionEstablishedAsBytes);
            }
            if (length > 0)
            {
                if (AppLayerProxy.Logger != null)
                {
                    AppLayerProxy.Logger.WriteLine("{0} > {1} {2} bytes{3}",
                                                   clientLogString, serverLogString, length,
                                                   (clientBuffer != null && extraData == clientBuffer.bytes) ? " (buffered)" : "");
                }

                // The clientBuffer should have already been setup then
                serverSocket.Send(extraData, (int)clientBuffer.contentLength, SocketFlags.None);
            }
        }
        void Connect()
        {
            Console.WriteLine("[Connecting to {0}...]", serverHost);

            BufStruct bufStruct = default(BufStruct);

            serverHost.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref bufStruct);
            if (bufStruct.contentLength > 0)
            {
                throw new NotImplementedException();
            }

            Console.WriteLine("[Connected]");

            if (bufStruct.contentLength > 0)
            {
                if (messageLogger != null)
                {
                    messageLogger.Log("[RecvThread] Received {0} bytes", bufStruct.contentLength);
                }
                if (connectionLogger != null)
                {
                    connectionLogger.LogDataBToA(bufStruct.buf, 0, (int)bufStruct.contentLength);
                }
            }
        }
Exemple #3
0
        static void AcceptCallback(ref SelectControl control, Socket listenSock, Buf safeBuffer)
        {
            Socket newSock = listenSock.Accept();

            if (log != null)
            {
                log.WriteLine("Accepted new client {0}", newSock.SafeRemoteEndPointString());
            }

            Socket clientSideSocket = new Socket(server.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);

            BufStruct leftOver = new BufStruct(safeBuffer.array);

            clientSideSocket.Connect(server, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOver);
            if (leftOver.contentLength > 0)
            {
                newSock.Send(leftOver.buf, 0, (int)leftOver.contentLength, SocketFlags.None);
                if (pcapLogger != null)
                {
                    //pcapLogger.LogTcpData(leftOver.buf, 0, leftOver.contentLength);
                }
            }

            SelectSocketTunnel tunnel = new SelectSocketTunnel(newSock, clientSideSocket);

            control.AddReceiveSocket(newSock, tunnel.ReceiveCallback);
            control.AddReceiveSocket(clientSideSocket, tunnel.ReceiveCallback);
        }
Exemple #4
0
 public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                      ProxyConnectOptions options, ref BufStruct buf)
 {
     if ((options & ProxyConnectOptions.ContentIsRawHttp) == 0)
     {
         throw new NotImplementedException();
     }
 }
        public Socket ListenAndAccept(UInt16 port)
        {
            Byte[] bindRequest = new Byte[9];
            Byte[] replyBuffer = new Byte[8];

            bindRequest[0] = 4; // Version 4 of SOCKS protocol
            bindRequest[1] = 2; // Command 2 "BIND"

            bindRequest[2] = (byte)(port >> 8);
            bindRequest[3] = (byte)(port);

            bindRequest[4] = 174;
            bindRequest[5] = 34;
            bindRequest[6] = 174;
            bindRequest[7] = 4;

            bindRequest[8] = 0; // User ID

            //
            // Connect to the proxy server
            //
            Socket socket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);

            BufStruct dataLeftOverFromProxyReceive = default(BufStruct);

            host.Connect(socket, host.dnsPriorityQuery, ProxyConnectOptions.None, ref dataLeftOverFromProxyReceive);
            if (dataLeftOverFromProxyReceive.contentLength > 0)
            {
                throw new NotImplementedException("Data left over from proxy negotiation not implemented");
            }

            socket.Send(bindRequest);
            socket.ReadFullSize(replyBuffer, 0, 8);

            if (replyBuffer[0] != 0)
            {
                Console.WriteLine("WARNING: The first byte of the proxy response was expected to be 0 but it was {0}", replyBuffer[0]);
            }

            if (replyBuffer[1] != 90)
            {
                throw new Proxy4Exception(replyBuffer[1]);
            }

            UInt16 listenPort = (UInt16)(
                (0xFF00 & (replyBuffer[2] << 8)) |
                (0xFF & (replyBuffer[3]))
                );

            Byte[] ip = new Byte[4];
            ip[0] = replyBuffer[4];
            ip[1] = replyBuffer[5];
            ip[2] = replyBuffer[6];
            ip[3] = replyBuffer[7];
            Console.WriteLine("EndPoint {0}:{1}", new IPAddress(ip).ToString(), listenPort);

            return(socket);
        }
Exemple #6
0
        public static Socket NewSocketConnection(ref InternetHost host)
        {
            Socket    socket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);
            BufStruct dataLeftOverFromProxyConnect = default(BufStruct);

            host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref dataLeftOverFromProxyConnect);
            if (dataLeftOverFromProxyConnect.contentLength > 0)
            {
                throw new NotImplementedException();
            }
            return(socket);
        }
Exemple #7
0
 void Open(BufStruct buf)
 {
     if (socket == null || !socket.Connected)
     {
         if (proxy == null)
         {
             serverEndPoint.ForceIPResolution(DnsPriority.IPv4ThenIPv6);
             socket = new Socket(serverEndPoint.ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
             socket.Connect(serverEndPoint.ipEndPoint);
         }
         else
         {
             socket = new Socket(proxy.host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);
             proxy.ProxyConnectTcp(socket, ref serverEndPoint, ProxyConnectOptions.ContentIsRawHttp, ref buf);
         }
     }
 }
Exemple #8
0
        static Int32 Main(string[] args)
        {
            TelnetOptions optionsParser = new TelnetOptions();
            List <String> nonOptionArgs = optionsParser.Parse(args);

            if (nonOptionArgs.Count != 1)
            {
                Console.WriteLine("Expected 1 argument but got {0}", nonOptionArgs.Count);
                optionsParser.PrintUsage();
                return(-1);
            }

            InternetHost?serverHost;

            if (nonOptionArgs.Count == 1)
            {
                String connectorString = nonOptionArgs[0];
                Proxy  proxy;
                String ipOrHostOptionalPort = Proxy.StripAndParseProxies(connectorString, DnsPriority.IPv4ThenIPv6, out proxy);
                UInt16 port     = DefaultPort;
                String ipOrHost = EndPoints.SplitIPOrHostAndOptionalPort(ipOrHostOptionalPort, ref port);
                serverHost = new InternetHost(ipOrHost, port, DnsPriority.IPv4ThenIPv6, proxy);
            }
            else
            {
                serverHost = null;
            }

            TelnetClient client = new TelnetClient(optionsParser.wantServerEcho.set, !optionsParser.disableColorDecoding.set);

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            if (serverHost != null)
            {
                BufStruct leftOver = default(BufStruct);
                socket.Connect(serverHost.Value, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOver);
                if (leftOver.contentLength > 0)
                {
                    Console.WriteLine(Encoding.UTF8.GetString(leftOver.buf, 0, (int)leftOver.contentLength));
                }
            }

            client.Run(socket);

            return(0);
        }
Exemple #9
0
        public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
            ProxyConnectOptions options, ref BufStruct buf)
        {
            BufStruct forwardBufStruct = default(BufStruct);
            host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref forwardBufStruct);
            if (forwardBufStruct.contentLength > 0)
            {
                throw new NotImplementedException();
            }

            if (endPoint.stringIsAnIP)
            {
                ProxyConnectTcpUsingIP(socket, endPoint.ipEndPoint.Address, endPoint.port);
            }
            else
            {
                ProxyConnectTcpUsingHost(socket, endPoint.ipOrHost, endPoint.port);
            }
        }
Exemple #10
0
        /*
         * public String ConnectorString(StringEndPoint targetEndPoint)
         * {
         *  return String.Format("{0}:{1}:{2}%{3}", Type,
         *      ipOrHost, endPoint.Port, targetEndPoint);
         * }
         * public override String ToString()
         * {
         *  return String.Format("{0}:{1}:{2}", Type, ipOrHost, endPoint.Port);
         * }
         */

        // Design Note: The ProxyConnect method could also connect the socket, however,
        //              in some cases the socket will already be connected, so, this api
        //              doesn't wrap connecting the socket.  Note that this means typically
        //              this call will always follow immediately after calling socket.Connect()
        /// <summary>
        /// Setup the proxy connection. The given socket must already be connected.
        /// The endpoint should have been retrieved from the proxy's CreateEndpoint method.
        ///
        /// Once the method is done, any leftover data from the socket will be in the given buffer
        /// </summary>
        /// <param name="socket">A connected tcp socket</param>
        /// <param name="ipEndPoint">The final destination, retreived from calling proxy.CreateEndpoint(...).</param>
        public abstract void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                             ProxyConnectOptions options, ref BufStruct buf);
Exemple #11
0
 public override Boolean ProxyConnectAsyncTcp(Socket socket, ref StringEndPoint endPoint,
                                              ProxyConnectOptions options, ref BufStruct buf)
 {
     throw new NotImplementedException();
 }
Exemple #12
0
 public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                      ProxyConnectOptions options, ref BufStruct buf)
 {
     host.Connect(socket, DnsPriority.IPv4ThenIPv6, options, ref buf);
 }
Exemple #13
0
        public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                             ProxyConnectOptions options, ref BufStruct buf)
        {
            throw new NotImplementedException();

            /*
             * //
             * // Check if the proxy end point string is valid
             * //
             * socket.Send(Encoding.UTF8.GetBytes(String.Format(
             *  "CONNECT {0} HTTP/1.1\r\nHost: {0}:{1}\r\n\r\n",
             *  endpoint.unparsedIPOrHost, endpoint.port)));
             *
             * NetworkStream stream = new NetworkStream(socket);
             *
             * //
             * // Process first line
             * //
             * for (int i = 0; i < 9; i++)
             * {
             *  Int32 nextByte = stream.ReadByte();
             *  if ((nextByte & 0xFF) != nextByte) throw new SocketException();
             * }
             *
             * //
             * // Get response code
             * //
             * Char[] responseCodeChars = new Char[3];
             * responseCodeChars[0] = (Char)stream.ReadByte();
             * responseCodeChars[1] = (Char)stream.ReadByte();
             * responseCodeChars[2] = (Char)stream.ReadByte();
             * String responseCodeString = new String(responseCodeChars);
             *
             * Int32 responseCode;
             * if (!Int32.TryParse(responseCodeString, out responseCode))
             *  throw new InvalidOperationException(String.Format("First line of HTTP Connect response was not formatted correctly (Expected response code but got '{0}')", responseCodeString));
             *
             * if (responseCode != 200) throw new InvalidOperationException(String.Format("Expected response code 200 but got {0}", responseCode));
             *
             * //
             * // Read until end of response
             * //
             * Int32 lineLength = 12;
             *
             * while (true)
             * {
             *  Int32 nextByte = stream.ReadByte();
             *  //Console.WriteLine("[HttpsProxyDebug] Got Char '{0}'", (Char)nextByte);
             *  if ((nextByte & 0xFF) != nextByte) throw new SocketException();
             *
             *  if (nextByte != '\r')
             *  {
             *      lineLength++;
             *  }
             *  else
             *  {
             *      nextByte = stream.ReadByte();
             *      if ((nextByte & 0xFF) != nextByte) throw new SocketException();
             *      if (nextByte != '\n') throw new InvalidOperationException(String.Format(
             *           "Received '\\r' and expected '\\n' next but got (Char)'{0}' (Int32)'{1}'",
             *           (Char)nextByte, nextByte));
             *
             *
             *      if (lineLength <= 0) break;
             *
             *      lineLength = 0;
             *  }
             * }
             */
        }
Exemple #14
0
 public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                      ProxyConnectOptions options, ref BufStruct buf)
 {
     endPoint.ForceIPResolution(DnsPriority.IPv4ThenIPv6);
     socket.Connect(endPoint.ipEndPoint);
 }
Exemple #15
0
 public abstract Boolean ProxyConnectAsyncTcp(Socket socket, ref StringEndPoint endPoint,
                                              ProxyConnectOptions options, ref BufStruct buf);
Exemple #16
0
        public override void ProxyConnectTcp(Socket socket, ref StringEndPoint endPoint,
                                             ProxyConnectOptions options, ref BufStruct forwardBufStruct)
        {
            host.Connect(socket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref forwardBufStruct);
            if (forwardBufStruct.contentLength > 0)
            {
                throw new NotImplementedException();
            }

            if ((options & ProxyConnectOptions.ContentIsRawHttp) != 0)
            {
                // do nothing
            }
            else
            {
                // send an HTTP CONNECT method
                unsafe
                {
                    AsciiPartsBuilder builder = new AsciiPartsBuilder(CONNECT_REQUEST_PARTS,
                                                                      endPoint.ipOrHost, endPoint.ipOrHost, endPoint.port.ToString());
                    UInt32 contentLength = builder.PrecalculateLength();
                    Byte[] buffer        = new Byte[(int)contentLength];
                    builder.BuildInto(buffer);

                    /*
                     * Console.Write("Request\n--------------------------\n");
                     * Console.Write(Encoding.ASCII.GetString(buffer));
                     * Console.Write("\n--------------------------\n");
                     */

                    socket.SendFullSize(buffer);

                    ByteBuilder responseBuilder   = new ByteBuilder(200);
                    int         endOfHeadersIndex = 0;
                    while (true)
                    {
                        int lastReceived = socket.Receive(buffer);
                        if (lastReceived <= 0)
                        {
                            /*
                             * Console.Write("Response\n--------------------------\n");
                             * Console.Write(Encoding.ASCII.GetString(responseBuilder.bytes, 0, (int)responseBuilder.contentLength));
                             * Console.Write("\n--------------------------\n");
                             */
                            throw new InvalidOperationException(String.Format("socket Receive returned {0} (received {1} bytes total)",
                                                                              lastReceived, responseBuilder.contentLength));
                        }
                        responseBuilder.Append(buffer, 0, (uint)lastReceived);
                        bool foundEndOfHeaders = false;
                        for (; endOfHeadersIndex + 3 < responseBuilder.contentLength; endOfHeadersIndex++)
                        {
                            if (responseBuilder.bytes[endOfHeadersIndex] == '\r' &&
                                responseBuilder.bytes[endOfHeadersIndex + 1] == '\n' &&
                                responseBuilder.bytes[endOfHeadersIndex + 2] == '\r' &&
                                responseBuilder.bytes[endOfHeadersIndex + 3] == '\n')
                            {
                                endOfHeadersIndex += 4;
                                foundEndOfHeaders  = true;
                                break;
                            }
                        }
                        if (foundEndOfHeaders)
                        {
                            break;
                        }
                        // rewind 3 characters in case we got a partial double newline
                        if (endOfHeadersIndex >= 3)
                        {
                            endOfHeadersIndex -= 3;
                        }
                    }

                    if (!responseBuilder.bytes.Equals(0, HTTP_VERSION_RESPONSE, 0, (uint)HTTP_VERSION_RESPONSE.Length))
                    {
                        throw new InvalidOperationException(String.Format(
                                                                "invalid HTTP response header (starts with \"{0}\")",
                                                                Encoding.ASCII.GetString(responseBuilder.bytes, 0,
                                                                                         (HTTP_VERSION_RESPONSE.Length <= responseBuilder.contentLength) ? HTTP_VERSION_RESPONSE.Length : (int)responseBuilder.contentLength)));
                    }
                    if (HTTP_VERSION_RESPONSE.Length + 3 > responseBuilder.contentLength)
                    {
                        throw new InvalidOperationException("invalid HTTP response header (it's too short)");
                    }
                    ResponseCode responseCode;
                    responseCode.a = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 0];
                    responseCode.b = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 1];
                    responseCode.c = (char)responseBuilder.bytes[HTTP_VERSION_RESPONSE.Length + 2];
                    if (responseCode.a != '2' && responseCode.b != '0' && responseCode.c != '0')
                    {
                        throw new InvalidOperationException(String.Format("expected response code 200 but got {0}{1}{2}",
                                                                          responseCode.a, responseCode.b, responseCode.c));
                    }

                    // TODO: receive the entire response if there is a content length!!
                    Console.Write("Response\n--------------------------\n");
                    Console.Write(Encoding.ASCII.GetString(responseBuilder.bytes, 0, (int)responseBuilder.contentLength));
                    Console.Write("\n--------------------------\n");
                    throw new NotImplementedException();
                }
            }
        }
Exemple #17
0
 public void Connect(Socket socket, PriorityQuery <IPAddress> dnsPriorityQuery, ProxyConnectOptions proxyOptions, ref BufStruct buf)
 {
     if (proxy == null)
     {
         targetEndPoint.ForceIPResolution(dnsPriorityQuery);
         socket.Connect(targetEndPoint.ipEndPoint);
     }
     else
     {
         proxy.ProxyConnectTcp(socket, ref targetEndPoint, proxyOptions, ref buf);
     }
 }
Exemple #18
0
    static Int32 Main(string[] args)
    {
        Options options = new Options();

        if (args.Length == 0)
        {
            options.PrintUsage();
            return(0);
        }

        List <String> nonOptionArgs = options.Parse(args);

        socketToConsoleBuffer = new Byte[options.bufferSizes.ArgValue];
        consoleToSocketBuffer = new Byte[options.bufferSizes.ArgValue];

        if (options.listenMode.set)
        {
            IPAddress localAddress = EndPoints.ParseIPOrResolveHost(options.localHost.ArgValue, DnsPriority.IPv4ThenIPv6);

            Socket listenSocket = new Socket(localAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            listenSocket.Bind(new IPEndPoint(localAddress, options.localPort.ArgValue));
            listenSocket.Listen(1);

            dataSocket = listenSocket.Accept();
        }
        else if (nonOptionArgs.Count != 2)
        {
            if (nonOptionArgs.Count == 0)
            {
                options.PrintUsage();
                return(0);
            }
            return(options.ErrorAndUsage("In client/connect mode there should be 2 non-option command line arguments but got {0}", nonOptionArgs.Count));
        }
        else
        {
            String connectorString = nonOptionArgs[0];

            String portString = nonOptionArgs[1];
            UInt16 port       = UInt16.Parse(portString);

            InternetHost host;
            {
                Proxy  proxy;
                String ipOrHost = Proxy.StripAndParseProxies(connectorString, DnsPriority.IPv4ThenIPv6, out proxy);
                host = new InternetHost(ipOrHost, port, DnsPriority.IPv4ThenIPv6, proxy);
            }

            dataSocket = new Socket(host.GetAddressFamilyForTcp(), SocketType.Stream, ProtocolType.Tcp);

            if (options.localPort.set)
            {
                dataSocket.Bind(new IPEndPoint(IPAddress.Any, options.localPort.ArgValue));
            }

            BufStruct leftOverData = new BufStruct(socketToConsoleBuffer);
            host.Connect(dataSocket, DnsPriority.IPv4ThenIPv6, ProxyConnectOptions.None, ref leftOverData);
            if (leftOverData.contentLength > 0)
            {
                PrepareConsole();
                consoleOutputStream.Write(leftOverData.buf, 0, (int)leftOverData.contentLength);
            }
        }

        // Note: I'm not sure these options are actually working
        if (options.tcpSendWindow.ArgValue != 0)
        {
            dataSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer, options.tcpSendWindow.ArgValue);
        }
        if (options.tcpReceiveWindow.ArgValue != 0)
        {
            dataSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, options.tcpReceiveWindow.ArgValue);
        }

        PrepareConsole();

        Thread consoleReadThread = new Thread(ConsoleReceiveThread);

        consoleReadThread.Name = "Console Read Thread";

        // Don't know how to cancel a console input stream read, so I have to
        // put the console read thread as a background thread so it doesn't keep
        // the program running.
        consoleReadThread.IsBackground = true;

        consoleReadThread.Start();

        try
        {
            while (true)
            {
                Int32 bytesRead = dataSocket.Receive(socketToConsoleBuffer, socketToConsoleBuffer.Length, SocketFlags.None);
                if (bytesRead <= 0)
                {
                    lock (typeof(NetCat))
                    {
                        if (!closed)
                        {
                            closed = true;
                        }
                    }
                    break;
                }
                consoleOutputStream.Write(socketToConsoleBuffer, 0, bytesRead);
            }
        }
        catch (SocketException e)
        {
        }
        finally
        {
            lock (typeof(NetCat))
            {
                if (!closed)
                {
                    consoleInputStream.Dispose();
                    closed = true;
                }
            }
            // Do not join other thread, just exit
        }

        return(0);
    }