zacbre/Socks5

No Reply From Target

zharris6 opened this issue · 16 comments

Hello -

I have implemented the Socks5Client instance and connected with no issue.

Once the client is connected, I send a couple of byes and wait for a reply (like below)

I am doing a TCPDump on the target server, and i see the bytes getting sent fine...However, No matter what i do, the response is always null.

Am I doing something wrong?

               byte[] sendBuf = System.Text.ASCIIEncoding.ASCII.GetBytes("GET \n");

                byte[] recvBuf = new byte[1024];

                client.Client.Send(sendBuf, 0, sendBuf.Length);            

                int receivedDataLength = client.Client.Receive(recvBuf, 0, recvBuf.Length);

Hey zharris6,

I realize I don't have any documentation on any of this, especially the socks5 client. Here's some insights on how to use it:

https://github.com/ThrDev/Socks5/blob/master/socks5/socks5/Socks5Client/Socks5Client.cs

You should be able to add handlers for callbacks, such as:

...
client.OnDataReceived += Client_onDataReceived;
client.ReceiveAsync();
...

void Client_onDataReceived(object sender, Socks5ClientDataArgs e) {
     // The data should be located in e.Buffer
}

Now, this assumes where your example says

client.Client.Send(....)

Is "client" the Socks5Client or is "Client" the Socks5Client?

The example above assumes "client" is an instance of the Socks5Client.

The Socks5Client.Client property is for raw access to the sockets. If you just replace "client.Client" with "client", you should be able to use your code again properly (if you aren't looking to use event handlers).

Lastly, I would check and make sure that the socket is actually connected.

if(client.Connected) {
     // Do your send and recv here.
}

Thank you ThrDev for the quick reply. I am having a hell of a time trying to wire up a Socks5 proxy to my FTP client and this may help.

I really appreciate it!!

Not a problem! Glad to be a help! If you have any more questions or you can't figure it out, definitely let me know and I'll take a look back through my code and see if anything may be giving you trouble.

Well I really did that as a test, just to see if I get anything back.

I am really trying to wire up your package with this:

https://github.com/hgupta9/FluentFTP

The connection keeps closing and every reply is null.

That is the real crux of my issues :).

Thanks again for your support.

I may be missing something. I wired it up like you suggested and the callback never fires. Here is my code.

I can confirm via a TCPDump on the target, that the request is in fact getting there and it is returning a response. It is just not getting picked up by the CallBack.

EDIT: I also confirmed via Wireshark that the proxy is in fact sending a response back

 private void Client_onDataReceived(object sender, Socks5ClientDataArgs e)
        {
            var test = e.Buffer;
        }

        private void Proxy()
        {
            Socks5Client client = new Socks5Client(ProxyHost, 8437, TargetIp, TargetPort, ProxyUser, ProxyPass);
            client.OnDataReceived += Client_onDataReceived;

            client.Connect();

            if (client.Connected)
            {
                byte[] myRequest = Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n\r\n");

                byte[] recvBuf = new byte[1024];

                client.ReceiveAsync();
                client.Send(myRequest, 0, myRequest.Length);

                Console.Out.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(recvBuf));
            }

Hey again,

That was my bad. I thought you were talking about HTTP requests before you posted about connecting to an FTP server.

It seems as if the connect() function is not working as intended. To alleviate this problem, ConnectAsync() should work.

...
private static void Client_onDataReceived(object sender, Socks5ClientDataArgs e)
{
    Console.WriteLine (System.Text.ASCIIEncoding.ASCII.GetString (e.Buffer));
}

private static void Client_onConnected(object sender, Socks5ClientArgs e)
{
        Console.WriteLine("Connected.");

        client.ReceiveAsync ();

        byte[] myRequest = System.Text.Encoding.ASCII.GetBytes ("GET \n");
        client.Send (myRequest, 0, myRequest.Length);
}

private static void Proxy()
{
    Socks5Client client = new Socks5Client ("localhost", 20202, "localhost", 21);
    client.OnDataReceived += Client_onDataReceived;
    client.OnConnected += Client_onConnected;
    client.ConnectAsync();
}
...

Or, if you prefer lambdas, you can declare OnConnected like the following:

client.OnConnected += (object sender, Socks5ClientArgs e) => {
    Console.WriteLine("Connected.");
    client.ReceiveAsync ();
    byte[] myRequest = System.Text.Encoding.ASCII.GetBytes ("GET \n");
    client.Send (myRequest, 0, myRequest.Length);
};

I hope this helps! I tested this and got the following output:

localhost:21
Connected.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 10:10. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.

Also note, as I missed before, you should call e.Client.ReceiveAsync() after you do what you need in Client_onDataReceived(..) - This assures that it will attempt to receive again, and it won't fire the event until there is data waiting to be received.

Thanks for taking the time to write examples.

EDIT:

I normally write synchronous applications, so bare with me if I am missing some key principles.

The client is in fact connecting, and sending the packet to the target (conformed via a TCPDump on the target)

However, As soon as this request sent, the onClientDisconnected call back in instantly running.

I am suspecting that is why i never get any action in the onDataReceived method.

Here is my code in case your curious


        private static void Client_onDataReceived(object sender, Socks5ClientDataArgs e)
        {
            Console.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(e.Buffer));
        }


        private void Proxy()
        {

                Socks5Client client = new Socks5Client(ProxyHost, 8437, TargetIp, TargetPort, ProxyUser, ProxyPass);


                client.OnDataReceived += Client_onDataReceived;
                client.OnConnected += (object sender, Socks5ClientArgs e) =>
                {
                    Console.WriteLine("Connected.");
                    isconnected = true;
                    client.ReceiveAsync();
                    byte[] myRequest = System.Text.Encoding.ASCII.GetBytes("GET \n");
                    client.Send(myRequest, 0, myRequest.Length);

                };
                client.ConnectAsync();
                while (!endcall)
                {
                }


        }

Hey again zharris6,

Could you do me a favor and check the Socks5ClientArgs variable named Status?

In your OnConnected Code:

...
client.OnConnected += (object sender, Socks5ClientArgs e) =>
{
     if(e.Status == SocksError.Failure) {
          Console.WriteLine("Failed to connect.");
     }
     else {
          Console.WriteLine("Connected.");
          isconnected = true;
          client.ReceiveAsync();
          byte[] myRequest = System.Text.Encoding.ASCII.GetBytes("GET \n");
          client.Send(myRequest, 0, myRequest.Length);
     }
};
...

I just added your code, The Console Writes “Connected” and never hits the Failed To Connect Line.

Same issues as before, It connects fine, Sends the data (confirmed via a TCP Dump on Target), then the OnClientDisconnect callback instantly fires (before the data can be received, confirmed I get data back via wireshark).

I've added some changes to Socks5Client.cs. If there are any errors, they will now be thrown. If you are using Visual Studio, there should be an option under the Debug menu called "Exceptions". If you could select .net exceptions "throw" or something to that effect, it should show you any thrown exceptions.

I don't have Visual Studio in front of me so I don't remember exactly what the items were called.

ThrDev - Thanks for your continued support.

I Pulled Your changes, and Made sure my debug window was showing thrown exceptions, and there is nothing :(

The program starts, Connects, Sends the packet, Then instantly disconnects.

I even added the ManualResetEvent instance to make sure the program is in fact pausing and waiting for a response.

It gets through the connection and send packet events fine, It waits for a response for the onDataReceived event, but it never gets anything.

The client still instantly disconnects after the packet is sent.

Here is my Debug Window Output (i hid all the initialization stuff)

The thread 0x6428 has exited with code 0 (0x0).
The thread 0x5db4 has exited with code 0 (0x0).

I wonder if the FTP server is closing your connection... That's interesting. Is there any other possible way you could try attempting to connect to a different FTP server?

I tried a windows based FileZilla server and its the same result. However i am noticing something weird in the Wireshark dump.

Right after the GET packet is sent, a Red packet is sent back. Which tells me the client sent an ABORT or RESET packet (i think)

Does the FTP server have authentication turned on? As far as I know, I would think that you would have to send some type of authentication even if it's anonymous.

Lastly, try changing 'GET' to 'ls', maybe that would help. I think GET requires an argument.
https://www.cs.colostate.edu/helpdocs/ftp.html

I solved the problem!!!

Thank you 100X for all your support. If there is anything I can help you with, and return the favor, please let me know.

For the record, all it was, that the FTP firewall wasn't allowing my proxy IP through to connect.

Sometimes the answer is right in front of you :(

At least i learned alot!!

Cheers m8!