/* sendto_spoof 0.1.2 by Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org This is a replacement of the sendto() function which enables the spoofing of the UDP packets in some existent tools or proof-of-concept codes. By default both source IP and port are something sequential/random. This is a good way for enabling spoofed packets in some proof-of-concept codes or other tools where is used sendto() and you don't need to watch the received packets and want the maximum anonimity. Implementing it in the programs is very simple, before re-compiling them you must do the following operations: - place the following line at the end of the #include list of your program: #include "sendto_spoof.h" - replace the sendto calls with sendto_spoof where you want. In the proof-of-concept usually is only one packet that tests a bug so must be replaced only the sendto() which sends that packet. - for Windows only: you NEED to remove or place a comment where is located #include in your program This code works on both Windows (on versions that support the RAW sockets like Windows XP) and other systems, and both little and big-endian architectures. If something doesn't work or the packet doesn't reach the target host means there is a firewall, your ISP blocks the spoofed packets, you don't have the needed permissions (root or administrator), your OS doesn't support the RAW sockets or simply you have added sendto_spoof() to a program where this is not possible (for example because it uses a sequence of packets signed with a unique ID sent by the server and so on). Is also possible to use this code for sending spoofed packets in a new program (so not only a sendto() replacement) since all you need to do is specifying and filling a sockaddr_in structure. You don't need to create the socket since it is already made by the sendto_spoof() function. CHECK THE FOLLOWING OPTIONS */ /* OPTIONS you can enable them here or at compilation time using the -D switch default is everything random */ //#define SRCDSTIP // source IP is equal to dest IP //#define SRCPORT 53 // use ever and only the source port SRCPORT //#define SRCIP "1.2.3.4" // use ever and only the source IP SRCIP // example at command-line: -DSRCIP=\"1.2.3.4\" #include #include #ifdef WIN32 // something better than a simple time(NULL) #include #define SENDTO_SPOOF_RAND GetTickCount() // 1000/s resolution #else #include #define SENDTO_SPOOF_RAND times(0) // 100/s resolution #endif #ifdef WIN32 #include #include #include #define in_addr_t uint32_t struct iphdr { uint32_t ihl:4; uint32_t version:4; uint8_t tos; uint16_t tot_len; uint16_t id; uint16_t frag_off; uint8_t ttl; uint8_t protocol; uint16_t check; uint32_t saddr; uint32_t daddr; }; struct udphdr { uint16_t source; uint16_t dest; uint16_t len; uint16_t check; }; #else #include #include #endif in_addr_t sendto_spoof_inet_addr(char *addr) { int i1, i2, i3, i4, i5, i6; u_char arr[sizeof(in_addr_t)]; sscanf(addr, "%u.%u.%u.%u.%u.%u", &i1, &i2, &i3, &i4, &i5, &i6); arr[0] = i1; arr[1] = i2; arr[2] = i3; arr[3] = i4; if(sizeof(in_addr_t) > 4) { arr[4] = i5; arr[5] = i6; } return(*(in_addr_t *)arr); // already htonled } uint16_t sendto_spoof_cksum(void *data, int len) { u_int sum = 0; int i = len >> 1, endian = 1; // big endian uint16_t crc, *p = (u_short *)data; if(*(char *)&endian) endian = 0; while(i--) sum += *p++; if(len & 1) sum += *p & (endian ? 0xff00 : 0xff); crc = sum = (sum >> 16) + (sum & 0xffff); if(sum >>= 16) crc += sum; if(!endian) crc = (crc >> 8) | (crc << 8); return(~crc); } int sendto_spoof( int s, const void *buf, int len, int flags, const struct sockaddr *to, int tolen) { struct pseudohdr { uint32_t saddr; uint32_t daddr; uint8_t zero; uint8_t protocol; uint16_t len; }; #define IPSZ sizeof(struct iphdr) #define UDPSZ sizeof(struct udphdr) #define PSEUDOSZ sizeof(struct pseudohdr) #define PCKSIZE (IPSZ + UDPSZ + len) #define PSSIZE (PSEUDOSZ + UDPSZ + len) struct iphdr *ip; struct udphdr *udp; struct pseudohdr *pseudo; in_addr_t src; int sd, ret, on = 1; u_char *buff, *data; buff = malloc(PCKSIZE); if(!buff) return(-1); // setuid(0); ip = (struct iphdr *)buff; udp = (struct udphdr *)(buff + IPSZ); data = (u_char *)(buff + IPSZ + UDPSZ); pseudo = (struct pseudohdr *)(buff + IPSZ - PSEUDOSZ); memcpy(data, buf, len); #if defined(SRCDSTIP) src = ((struct sockaddr_in *)to)->sin_addr.s_addr; #elif defined(SRCIP) src = sendto_spoof_inet_addr(SRCIP); #else src = (SENDTO_SPOOF_RAND * 0x343FDf) + 0x269EC3ff; // f ff #endif pseudo->saddr = src; pseudo->daddr = ((struct sockaddr_in *)to)->sin_addr.s_addr; pseudo->zero = 0; pseudo->protocol = IPPROTO_UDP; pseudo->len = htons(UDPSZ + len); #if defined(SRCPORT) udp->source = htons(SRCPORT); #else udp->source = htons((SENDTO_SPOOF_RAND * 0x343FD) + 0x269EC3); #endif udp->dest = ((struct sockaddr_in *)to)->sin_port; udp->check = 0; udp->len = pseudo->len; udp->check = htons(sendto_spoof_cksum(pseudo, PSSIZE)); ip->ihl = 5; ip->version = 4; ip->tos = 0x10; ip->tot_len = htons(PCKSIZE); ip->id = htons(1); ip->frag_off = htons(0); ip->ttl = 128; ip->protocol = IPPROTO_UDP; ip->check = 0; ip->saddr = src; ip->daddr = ((struct sockaddr_in *)to)->sin_addr.s_addr; ip->check = htons(sendto_spoof_cksum(ip, IPSZ)); sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if(sd < 0) { free(buff); return(sd); } ret = setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (void *)&on, sizeof(on)); if(!ret) { ret = sendto(sd, buff, PCKSIZE, 0, to, sizeof(struct sockaddr_in)); } close(sd); free(buff); return(ret); #undef IPSZ #undef UDPSZ #undef PSEUDOSZ #undef PCKSIZE #undef PSSIZE }