Question

I am trying to develop a socks tunneling application in c# that is able to open a website by using add and modified header requests (something similar to Modify Header Firefox Addon) and tunnel the data through a proxy (socks preferable). Please can anyone specify any resources I might need for this? Or any alternative that can perform the same function, open source that I can build on maybe, etc. Thanks!

ps: the applications should also be able to open https and other common network protocols

Was it helpful?

Solution

One way is to use HttpSys and create a local proxy server to handle request on the loopback 127.0.0.1 address. You would be change the system proxy to this address/port and sit between client and server.

This would allow you to modify request/response packets & headers. There's an example here of this approach in C#, and I've amended this below to show how it would work.

public class MyProxy
{
    private readonly HttpListener listener;

    public MyProxy()
    {
        listener = new HttpListener();
    }

    public void Start()
    {
        listener.Prefixes.Add("http://*:8888/");
        listener.Prefixes.Add("https://*:8889/");
        listener.Start();
        Console.WriteLine("Proxy started, hit enter to stop");
        listener.BeginGetContext(GetContextCallback, null);
        Console.ReadLine();
        listener.Stop();
    }

    public void GetContextCallback(IAsyncResult result)
    {
        var context = listener.EndGetContext(result);
        listener.BeginGetContext(GetContextCallback, null);

        var request = context.Request;
        var response = context.Response;
        var url = request.Url;

        UriBuilder builder = new UriBuilder(url);
        builder.Port = url.Port == 8888 ? 80 : 443;
        url = builder.Uri;

        WebRequest webRequest = WebRequest.Create(url);

        webRequest.Proxy = GlobalProxySelection.GetEmptyWebProxy();
        WebResponse webResponse = webRequest.GetResponse();
        using (Stream reader = webResponse.GetResponseStream())
        {
            using (Stream writer = response.OutputStream)
            {
                reader.CopyTo(writer);
            }
        }
    }
}

The downside to this approach is it's quite low level, and affects all traffic on the user machine which may not be desirable. You would have to handle SSL requests, and it would also impact any existing configured proxies.

Another alternative approach is to use the Microsoft Internet Controls COM component and to extend the WebBrowser class. There's a SO question here that shows the approach. Unfortunately the version of WebBrowser in the .NET namespace does not implement the request response objects. The interesting bits are below.

public class ExtendedWebBrowser : WebBrowser
{
    ...

    void BeforeNavigate(object pDisp, ref object url, ref object flags,
                       ref object targetFrameName, ref object postData, 
                       ref object headers, ref bool cancel)
    {
         if (!headers.Contains("X-RequestFlag")
         {
             headers += "X-RequestFlag: true\r\n";

             // append custom header here

             // cancel current request
             cancel = true;

             // re-request with amended details
             Navigate((string)url, (string)targetFrameName, (byte[])postData, 
                      (string)headers);
         }
         else
         {
             base.BeforeNavigate(...);
         }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top