Somebody I know was in need of web visitors; this was about 3 years ago (maybe 5). I thought I'd help her out by writing a web client that would keep connecting to her site in a loop, and submitting a "GET / HTTP" at the end of each loop; the command to get the default web page. After 50 iterations of the GET loop, I decided she should have more visitors then just me. I visited http://packetstormsecurity.org and downloaded a web client that spoofed ip addresses. After visiting her web site 100 times I thought I should give her a call too see if she was OK with this ethically questionable technique. I was immediately rebuked and was asked to cease and desist.
I've always heard that web activity takes about 3 months to be reflected in a web search; i.e., if a bunch of people visit your website it won't improve your web search standings for about 3 months. I thought I'd test this out by sending a hit to my web site every second for 24 hours; see how long it took to make me rise up in a web search. I went back to http://packetstormsecurity.org to download that spoofing client again; I didn't find it. I did a search on the word "spoof" (a site search) and came up with an interesting article on how to spoof your ip address when visiting a website; viewable at http://examples.oreilly.de/english_examples/9780596510305/tools/blind-spoof.html
This article gets into the nitty grity about how you actually connect to a web server. I found this fascinating because I used to write application servers for a living. A client program would connect to my server by (1) create a socket - a file that you transfer data through when communicating to the server (2) Connect to the server's socket (3) issue commands to the server; e.g., a GET command. The socket would be of type "tcp"; the connect command required this. Here's an example of a client (from the web):
Please note that you have to connect to the server with the "connect" command. The "connect" command is required for tcp communication, and tcp communication is required for surfing the net. However, tcp sockets don't allow you to spoof your ip address; you have to connect with your real ip address. To spoof your ip address you need a raw socket, but there is no connect command for raw sockets. So how do you visit somebody's webpage with a spoofed ip address? You visit with a raw socket and perform the steps by hand that a connect command does!
If you go back to the blind-spoof.html frame above (2 frames above) you'll see the following code:
Packet 1: Client -> Server flags: SYN ("I want to initiate a connection") SEQ : clientnr Packet 2: Server -> Client flags: SYN, ACK (ACK: The request is being acknowledged) SEQ : servernr ACK : clientnr+1 Packet 3: Client -> Server flags: ACK
... and that is the connection. So what we need to make a connection with a raw socket is a knowledge of how the web server (or an application server) generates sequence numbers. This isn't cut and dried. Web servers used to use rules for generating sequence numbers that were easy to predict. E.g., previous to version 3.2, AIX web servers assigned a sequence number that was calculated as an offset from the time of the packet transaction. VAX/VMS had an extremely secure file system, files 11, but used a web server sequence number generation that was easy to predict. Today's web servers use random number generators to calculate sequence number; much more secure then a time offset
It's still possible to spoof today's servers, but you need to analyze the sequence numbers they generate too formulate an algorithm for predicting their sequence numbers. Aside: take a look at eriu.c You can find this program on the Internet; it's on packetstormsecurity.org eriu.c will show you how to use raw sockets. There are similar examples you can find on the Internet. So the next thing you need to do is create a program that prints out the sequence numbers coming out of port 80 (port 80 is used for HTTP communication - the communication protocol of e web). You can write a program in the C programming language that can access web packets directly from the network adapter, but you need to incorporate the WinPcap library; http://winpcap.org
After going to http://winpcap.org you need to download the developer's version of WinPcap; the version that has the includes and libraries you need to call. After installing the developer's version you need to download and install the regular version; i.e., the version that is available by clicking on the download button on the WinPcap home page; the version that contains winpcap.dll - the run time stuff (late binding routines). While your on the home page, click on the documents button; look at WinPcap manual http://www.winpcap.org/docs/docs_412/html/main.html The "owner's guide" will show you how to use WinPcap, but if you still have problems compiling, take a look at http://www.rhyous.com/2011/11/12/how-to-compile-winpcap-with-visual-studio-2010/
I compiled one of the examples supplied with the developer's version; basic_dump.c It compiled the first time I tried it, so this is great code. It didn't produce any sequence numbers, so I made some modifications to basic_dump by adding some code I found at http://www.binarytides.com/code-a-packet-sniffer-in-c-with-winpcap/ and voila, sequence numbers! Here's the code:
#include<stdafx.h> #include <pcap.h> //I added the WinPCap include directory to the project includes #include "winsock2.h" //need this for the ntohs and ntohl functions #pragma comment(lib, "ws2_32.lib") //I added the wpcap.lib library in the project settings but I wasn't sure about how too add this //so I'm adding the library for winsock here, the old fashioned way using namespace System; /* prototype of the packet handler */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data); int main() { pcap_if_t *alldevs; pcap_if_t *d; int inum; int i=0; pcap_t *adhandle; char errbuf[PCAP_ERRBUF_SIZE]; /* Retrieve the device list */ if(pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf); exit(1); } /* Print the list */ for(d=alldevs; d; d=d->next) { printf("%d. %s", ++i, d->name); if (d->description) printf(" (%s)\n", d->description); else printf(" (No description available)\n"); } if(i==0) { printf("\nNo interfaces found! Make sure WinPcap is installed.\n"); return -1; } printf("Enter the interface number (1-%d):",i); scanf("%d", &inum); if(inum < 1 || inum > i) { printf("\nInterface number out of range.\n"); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } /* Jump to the selected adapter */ for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); /* Open the device */ /* Open the adapter */ if ((adhandle= pcap_open_live(d->name, // name of the device 65536, // portion of the packet to capture. // 65536 grants that the whole packet will be captured on all the MACs. 1, // promiscuous mode (nonzero means promiscuous) 1000, // read timeout errbuf // error buffer )) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name); /* Free the device list */ pcap_freealldevs(alldevs); return -1; } printf("\nlistening on %s...\n", d->description); /* At this point, we don't need any more the device list. Free it */ pcap_freealldevs(alldevs); /* start the capture */ pcap_loop(adhandle, 0, packet_handler, NULL); pcap_close(adhandle); return 0; } /* Callback function invoked by libpcap for every incoming packet */ void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) { struct tm *ltime; char timestr[16]; time_t local_tv_sec; typedef struct tcp_header { unsigned short source_port; // source port unsigned short dest_port; // destination port unsigned int sequence; // sequence number - 32 bits unsigned int acknowledge; // acknowledgement number - 32 bits unsigned char ns :1; //Nonce Sum Flag Added in RFC 3540. unsigned char reserved_part1:3; //according to rfc unsigned char data_offset:4; /*The number of 32-bit words in the TCP header. This indicates where the data begins. The length of the TCP header is always a multiple of 32 bits.*/ unsigned char fin :1; //Finish Flag unsigned char syn :1; //Synchronise Flag unsigned char rst :1; //Reset Flag unsigned char psh :1; //Push Flag unsigned char ack :1; //Acknowledgement Flag unsigned char urg :1; //Urgent Flag unsigned char ecn :1; //ECN-Echo Flag unsigned char cwr :1; //Congestion Window Reduced Flag unsigned short window; // window unsigned short checksum; // checksum unsigned short urgent_pointer; // urgent pointer } TCP_HDR; /* Ip header (v4) */ typedef struct ip_hdr { unsigned char ip_header_len:4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also) unsigned char ip_version :4; // 4-bit IPv4 version unsigned char ip_tos; // IP type of service unsigned short ip_total_length; // Total length unsigned short ip_id; // Unique identifier unsigned char ip_frag_offset :5; // Fragment offset field unsigned char ip_more_fragment :1; unsigned char ip_dont_fragment :1; unsigned char ip_reserved_zero :1; unsigned char ip_frag_offset1; //fragment offset unsigned char ip_ttl; // Time to live unsigned char ip_protocol; // Protocol(TCP,UDP etc) unsigned short ip_checksum; // IP checksum unsigned int ip_srcaddr; // Source address unsigned int ip_destaddr; // Source address } IPV4_HDR; /* Ethernet Header */ typedef struct ethernet_header { UCHAR dest[6]; UCHAR source[6]; USHORT type; } ETHER_HDR; ETHER_HDR *ethhdr; IPV4_HDR *iphdr; TCP_HDR *tcpheader; unsigned char iphdrlen = 0; unsigned int sequence = 0; unsigned int ack = 0; unsigned short dest_port = 0; unsigned short source_port = 0; /* * unused parameter */ (VOID)(param); /* Get the sequence number from pkt_data */ iphdr = (IPV4_HDR *) (pkt_data + sizeof(ETHER_HDR)); iphdrlen = iphdr->ip_header_len*4; tcpheader = (TCP_HDR*) (pkt_data +iphdrlen + sizeof(ETHER_HDR)); if (tcpheader != NULL) { sequence = ntohl(tcpheader->sequence); ack = ntohl(tcpheader->acknowledge);; source_port = ntohs(tcpheader->source_port); dest_port = ntohs(tcpheader->dest_port); } else { sequence = -1; ack = -1; source_port = 80; dest_port = 80; } /* convert the timestamp to readable format */ local_tv_sec = header->ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); //I just want info from web connections - filtering for port 80 if ((dest_port == 80) || (source_port == 80)) { printf("%s,%.6d len:%d, seqnbr:%u, acknbr:%u, source_port:%u, dest_port:%u\n", timestr, header->ts.tv_usec, header->len, sequence, ack, source_port, dest_port); } }
Getting back to the title of this article; improving your search standings. Run this program on the system where your web server runs; in my case, Serval. You need to write a spoofing client that lets you enter sequence numbers by hand during the handshake (connect) process; in my case on Caprica. Adding, say 100 web hits/day this way is quite possible, and can significantly improve the ranking of a personal home page.