Question, I've been trying to find information for setting the X-Forwarded-For header in C programs, or basically how spoofing it works. I've seen how to do this in ruby, python, and even with curl. I tried searching Google for it, but have came up empty handed. Any links, examples or advice much appreciated.
Try searching Google "x-forwarded-for socket C"
sent from my HTC smartphone
The best I could do with "x-forwarded-for socket C" in Google was finding someone's re-write of Stunnel. While better than anything I've found so far, it didn't show how to manually set an ip for your x-forwarded-for header. Maybe its possible to end that code that way. Or maybe I'm not seeing something else?
If you're writing for CGI, headers in C are no different than in any other language -- they're just text. In some ways they're simpler, since C doesn't try to "take control" of them the way PHP does, etc.
#include <stdio.h>
int main(void) {
// Read any POST data from stdin via fgets or other stdio calls
// Server variables are in the environment, available via getenv, etc
printf("Content-Type: raw/text-only\n");
printf("X-Forwarded-For: ...\n");
printf("\n");
printf("Actual Document Content\n");
return(0);
}
Thank you Corona688. I meant to reply sooner, but the week got away from me. However, I'm unsure if I explained myself correctly. I'm not trying to find how to read the X-Forwarded-For from incoming requests, but more or less looking for information on how to spoof the X-Forwarded-For with outgoing requests in C. I know in Python it would be done with something like this:
import urllib2,cookielib
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
opener.addheaders = [('X-Forwarded-For','1.2.3.4'),]
resp=opener.open('http://example.com/logIP.php')
While in ruby it would be done like this:
require "net/http"
require "uri"
url = URI.parse("http://www.whatismyip.com/automation/n09230945.asp")
req = Net::HTTP::Get.new(url.path)
req.add_field("X-Forwarded-For", "0.0.0.0")
res = Net::HTTP.new(url.host, url.port).start do |http|
http.request(req)
end
puts res.body
I haven't been able to find much information with doing this in C though.
Python in particular suffers from library-itis. If there's something which can be done, there's not just one but several conflicting libraries preinstalled for you.
C is more of a "do it yourself" language. It doesn't really lend itself to one-liners. But it gives you a level of control scripting languages don't.
Do you have wget?
#include <stdio.h>
int main(void) {
const char *ip="1.2.3.4";
printf("X-Forwarded-For: %s\n", ip);
printf("Content-Type: text/html\n");
printf("\n");
// Turn over to external wget utility
// execl never returns, your program "becomes" the command you told it to run.
execlp("wget", "http://website.com/whatever.php", "-q" "-O" "-", NULL);
// ...unless it can't find wget, in which case it returns an error, and so should we.
return(1);
}
I'm not aware of a "standard" CGI library for C which everyone already has, but a quick look finds cgic: cgic: an ANSI C library for CGI Programming
You might also consider running a complete proxy such as tinyproxy.
It seems that tinyproxy would allow for changing the X-Forwarded-For header. However, it seemed that would stop other proxies from being used. Say someone was to use proxychains to spoof the original ip of a C program running through another proxy running on port 10000, a connection would need to be made to port 10000 after hitting 8888 or whatever port tinyport is running on.
I tried finding ways for spoofing X-Forwarded-For within proxychains itself before posting here, but came up empty handed with this as well. Would you know of a good way to pass tinyproxy traffic to proxychains, another port, or proxy?
EDIT: Forgot to mention, I do have wget and know how to use X-Forwared-For with Curl already. Looking for others ways to do this with C binaries that don't use these utilities though.
There's no "native" one-liners for HTTP in C. C doesn't handle files natively, let alone HTTP. This lack of dependencies is why you can write kernels in it -- and write entire languages like ruby, python, perl, and pretty much everything you run on your computer -- but it means you have to write out what you want long-form, or install a library.
There's definitely C libraries for it, in fact you've already heard of one -- curl. Here's some source code examples for it.
I had used libcurl once, but that link is an awesome reference! I looked through some of these while searching for one to set the header. It looks like this one is the closest example:
libcurl example - httpcustomheader.c
I suppose someone could take this part:
/* Add a header with "blank" contents to the right of the colon. Note that
we're then using a semicolon in the string we pass to curl! */
chunk = curl_slist_append(chunk, "X-silly-header;");
And change it to something like this?:
/* Add a header with "blank" contents to the right of the colon. Note that
we're then using a semicolon in the string we pass to curl! */
chunk = curl_slist_append(chunk, "X-Forwarded-For: 1.2.3.4;");
Not sure if I'm on the right track?
I do think you're on the right track, or a right track, there being more than one way to skin a cat.
Sorry, I got turned around. curl handles the outgoing request, not the incoming one. You'd still be doing printf("header: value\n"); and using libcurl to retrieve the data since wget wasn't sufficient.
Well, I was actually looking for outgoing requests for this, not incoming. I did a little bit of experiementing with tcpdump and could see this being set:
$ tcpdump -vvvs 1024 -l -A | grep -i x-forward
tcpdump: listening on wlan0, link-type EN10MB (Ethernet), capture size 1024 bytes
X-Forwarded-For: 1.2.3.4;
So it appears to be working. I'm all ears if anyone thinks this is incorrect. Here is the code I modified from the previous link:
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/* <DESC>
* HTTP request with custom modified, removed and added headers
* </DESC>
*/
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
struct curl_slist *chunk = NULL;
/* Remove a header curl would otherwise add by itself */
chunk = curl_slist_append(chunk, "Accept:");
/* Add a custom header */
chunk = curl_slist_append(chunk, "Another: yes");
/* Modify a header curl otherwise adds differently */
chunk = curl_slist_append(chunk, "Host: www.google.com");
/* Add a header with "blank" contents to the right of the colon. Note that
we're then using a semicolon in the string we pass to curl! */
chunk = curl_slist_append(chunk, "X-Forwarded-For: 1.2.3.4;");
/* set our custom set of headers */
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_URL, "http://google.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
/* free the custom headers */
curl_slist_free_all(chunk);
}
return 0;
}
Appeciated the help Corona688. Much thanks!