Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override IP in HTTP Request

Tags:

c++

c#

wininet

Looking for a way to issue an HTTPwebrequest, or use the browser control, or winhttp to make a request to a URL, but override the IP address it connects to from the DNS lookup to a specific one.

Trying to do something similar to the HOSTS file, but programatically without having to modify this file. It can be C# or C+

Why I need it, the host i am sending the request has multiple IPs, and their Domain servers are doing load balancing accross the different IPs. Trying to force the request to a particular IP, but I need the host in the http request to be still the original host. I need this programatically because changing the host file every time i need to run this test is too time consuming.

like image 712
httpresearcher Avatar asked Jan 09 '10 14:01

httpresearcher


People also ask

Can you get IP address from HTTP request?

You can use RemoteAddr to get the remote client's IP address and port (the format is "IP:port"), which is the address of the original requestor or the last proxy (for example a load balancer which lives in front of your server). This is all you have for sure. This is because internally http. Header.

Can you cURL to an IP address?

...will force cURL to use "127.0. 0.1" as the IP address when requesting "www.example.com" over port 80 (HTTP). ...which will force cURL to use "127.0. 0.1" as the IP address for requests to "www.example.com" over ports 80 (HTTP and 443 (HTTPS).

Can request IP be spoofed?

If an application trusts an HTTP request header like X-Forwarded-For to accurately specify the remote IP address of the connecting client, then malicious clients can spoof their IP address.


3 Answers

All you had to do was this:

var request = (HttpWebRequest) WebRequest.Create("http://192.168.1.1");
request.Host = "news.bbc.co.uk";
like image 187
Kayode Leonard Avatar answered Sep 27 '22 19:09

Kayode Leonard


If I understand correctly you have to make an http request to a web server using virtualhosts but the DNS isn't setup yet so you have to specify the ip address in the url but send something else in the Host: header.

If that's the case you may be able to do so..

In C# using WebProxy:

See Kayode Leonard's answer for .NET 4 and up.

Here's the code I would use if I have my server running on 67.223.227.171:8888 but I need to have www.example.com in the Host: header.

System.Net.WebRequest r = System.Net.WebRequest.Create("http://www.example.com");
r.Proxy = new WebProxy("http://67.223.227.171:8888");

See this link

In C++ using WinHttp:

Using WinHttp you can simply set the Host: header with WinHttpAddRequestHeaders.

So once again if I have my server running on 67.223.227.171:8888 but I need to have www.example.com in the Host: header:

#include <windows.h>
#include <winhttp.h>
#include <assert.h>

int main() {
  HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", 
                                    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                    WINHTTP_NO_PROXY_NAME, 
                                    WINHTTP_NO_PROXY_BYPASS, 0);

  assert(hSession != NULL);


  // Use WinHttpConnect to specify an HTTP server.
  HINTERNET hConnect = WinHttpConnect( hSession,
                             L"67.223.227.171",
                             8888,
                             0 );

  assert(hConnect != NULL);

  // Open and Send a Request Header.
  HINTERNET  hRequest = WinHttpOpenRequest( hConnect,
                                 L"GET", 
                                 L"/downloads/samples/internet/winhttp/retoptions/redirect.asp", 
                                 NULL,
                                 WINHTTP_NO_REFERER,
                                 WINHTTP_DEFAULT_ACCEPT_TYPES,
                                 0 );

    assert(hRequest != NULL);

   BOOL httpResult = WinHttpAddRequestHeaders(
                                  hRequest,
                                  L"Host: www.example.com",
                                  -1L,
                                  0);

   assert(httpResult);

  httpResult = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 
                                   0,
                                   WINHTTP_NO_REQUEST_DATA,
                                   0,
                                   0,
                                   0 );

  assert(httpResult);

  httpResult = WinHttpReceiveResponse( hRequest, NULL );

  assert(httpResult);
}

Edited: The class name is WebProxy. Added C# sample code. Added C++ sample code.

like image 29
Alex Jasmin Avatar answered Sep 27 '22 18:09

Alex Jasmin


[Note, further to Kayode Leonard's answer: A Host property was added to the request in .Net 4.0, making this answer obsolete]

I think you are saying that you want to be able to override the ip address for a given host, without changing the host header.

For example, news.bbc.co.uk maps to IP address 212.58.226.139, but you want to be able to map this to another ip address, while still presenting the same news.bbc.co.uk "Host" http header to the overriden address. This is what you'd acheive by overriding the HOSTS file as you say, which is slightly different to Jason's answer as his won't present the original "Host" http header.

I don't believe you can do this easily (although I'm about to experiment to find out!). Certainly you can't do the following:

var request = (HttpWebRequest) WebRequest.Create("http://192.168.1.1");
request.Headers["Host"] = "news.bbc.co.uk";

as this will fail with an error saying you can't modify the "Host" header.

You probably can do it if your are willing to go down a level below the HttpWebRequest and deal at a more TCP level, but I'm not sure how you'd approach it without going down to that level.

[Edit]: Having played around with various approaches of overriding HttpWebRequest and WebHeaderCollection, I'm pretty sure it can't be done this way. However, Alexandre Jasmin's answer seems to be the solution.

like image 21
Rob Levine Avatar answered Sep 27 '22 18:09

Rob Levine