Skip to content

Instantly share code, notes, and snippets.

@olbat
Created September 19, 2011 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olbat/1226362 to your computer and use it in GitHub Desktop.
Save olbat/1226362 to your computer and use it in GitHub Desktop.
Share data spoofing them and bouncing on a specified server (data are stored in TCP ACK field, bouncing is done via TCP RST)
/*
* Copyright (C) 2006, 2007 Sarzyniec Luc <mail@olbat.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* see the COPYING file for more informations */
#include <linux/if_ether.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <stdlib.h>
#ifndef _I386_TYPES_H
#include <asm/types.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include "headers.h"
#define DATAGRAM_SIZE 4096
static char *datagram;
static struct ipv4_header *iph;
static struct tcp_header *tcph;
static __u16 sourceport,destport;
int read_seqdata(int fd,char *buff,__u32 *seqnum,int *num)
{
int end;
end = 1;
iph = (struct ipv4_header *) (datagram + sizeof(struct ethernet_header));
if (iph->proto == IPPROTO_TCP)
{
tcph = (struct tcp_header *) (datagram
+ sizeof(struct ethernet_header)
+ sizeof(struct ipv4_header));
if ((tcph->sourceport == sourceport)
&& (tcph->destport == destport) && (tcph->ack == 1))
{
if (num)
{
__u32 tmpu;
char tmpc[4];
tmpu = (ntohl(tcph->acknum) -1);
memcpy(tmpc,&tmpu,sizeof(__u32));
*num = *tmpc;
memcpy(seqnum,tmpc+sizeof(char),sizeof(__u32)-1);
}
else
{
/* -1 dues incrementation of the seqnum
* (TCP protocol)
*/
*seqnum = (ntohl(tcph->acknum) - 1);
}
/* printf("RECEIVED_DATA %#x\n",*seqnum); */
end = 0;
}
}
else
{
end = -1;
}
return end;
}
char *read_data(int fd,char *buffer,int size)
{
char *ptr;
__u32 wbuffer;
int num;
ptr = buffer;
while (((read(fd,datagram,DATAGRAM_SIZE) > 0) && (size > 0)))
{
if (!read_seqdata(fd,datagram,&wbuffer,&num))
{
memcpy(ptr+(num*(sizeof(__u32)-1)),&wbuffer,
sizeof(__u32)-1);
size = size - (sizeof(__u32) -1);
}
}
return buffer;
}
int main(int argc,char **argv)
{
if (argc > 3)
{
char end;
char *filebuffer;
__u32 seqnum;
int sockfd,fd,wdata;
sourceport = (__u16) htons(atoi(argv[3]));
destport = (__u16) htons(atoi(argv[2]));
datagram = (char *) malloc(DATAGRAM_SIZE * sizeof(char));
iph = (struct ipv4_header *) datagram;
tcph = (struct tcp_header *) (datagram
+ sizeof(struct ipv4_header));
memset(datagram,0,DATAGRAM_SIZE);
/* if ((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) < 0) */
if ((sockfd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL))) < 0)
{
perror("socket");
exit(1);
}
fputs("start listening ...\n",stdout);
end = 0;
while (!end)
{
if (read(sockfd,datagram,DATAGRAM_SIZE) < 0)
{
perror("read");
end = 1;
}
if (!read_seqdata(sockfd,datagram,&seqnum,0))
{
if (!seqnum)
{
fputs("----receiving data----\n",stdout);
fd = open(argv[1],O_CREAT|O_WRONLY);
read(sockfd,datagram,DATAGRAM_SIZE);
while (read_seqdata(sockfd,datagram,
&seqnum,0))
{
read(sockfd,datagram,
DATAGRAM_SIZE);
}
while (seqnum)
{
wdata = (int) seqnum;
filebuffer = (char *) malloc(
wdata * sizeof(char));
filebuffer = read_data(sockfd,
filebuffer,wdata);
fwrite(filebuffer,sizeof(char),
wdata,stdout);
write(fd,filebuffer,wdata);
while (read_seqdata(sockfd,
datagram,&seqnum,0))
{
read(sockfd,datagram,
DATAGRAM_SIZE);
}
free(filebuffer);
}
close(fd);
end = 1;
}
}
}
close(sockfd);
free(datagram);
fputs("----------------------\nfile received.\n",stdout);
}
else
{
fprintf(stdout, "usage : %s <output file name> <source port> "
"<destination port>\n"
"(use the same port source and destination as "
"the sender)\n",argv[0]);
}
return 0;
}
/*
* Copyright (C) 2006, 2007 Sarzyniec Luc <mail@olbat.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* see the COPYING file for more informations */
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#ifndef _I386_TYPES_H
#include <asm/types.h>
#endif
#include <fcntl.h>
#include <unistd.h>
#include "headers.h"
#define DATAGRAM_SIZE 4096
#define BUFFER_SIZE 1024
#define SEQMAX 256
#define DATA ""
/*
* If you have problems with transfert that dont finish,
* try to increase the delay
*
* packet structure :
* ----------------------------------------------------------------------
* | zero
* | size of first packet (bytes)
* | first packet data1 (1 byte for the num of the packet,
* 3 bytes for the data) ....
* | size of second packet
* | second packet data ....
* | ....
* |zero
* ----------------------------------------------------------------------
*
*/
static char *datagram;
static struct ipv4_header *iph;
static struct tcp_header *tcph;
static struct data *tcpd;
static __u8 seqno;
static struct sockaddr_in sain;
static __u32 *spooflist;
static int spooflistnb,freqnb;
static unsigned long int sdelay,sdelay_m;
/* network functions */
unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
char *set_checksums()
{
static char pbuffer[BUFFER_SIZE];
static struct pseudo_tcp_header pseudoth;
tcph->tcpchecksum = 0;
pseudoth.sourceaddr = iph->sourceaddr;
pseudoth.destaddr = iph->destaddr;
pseudoth.proto = iph->proto;
pseudoth.tcplen = htons(sizeof(struct tcp_header)+tcpd->len);
pseudoth.zero = 0;
memcpy(pbuffer,&pseudoth,sizeof(struct pseudo_tcp_header));
memcpy((pbuffer + sizeof(struct pseudo_tcp_header)),
tcph,sizeof(struct tcp_header));
memcpy((pbuffer + sizeof(struct pseudo_tcp_header)
+ sizeof(struct tcp_header)),tcpd->data,tcpd->len);
tcph->tcpchecksum = csum((unsigned short *)pbuffer,
(sizeof(struct pseudo_tcp_header)
+ sizeof(struct tcp_header)+tcpd->len));
iph->ipchecksum = csum((unsigned short *) datagram, iph->iphdrlen);
return pbuffer;
}
/* transfert functions */
void set_new_ip(struct ipv4_header *iph)
{
static int freq = 1;
if (!(freq++ % freqnb))
{
if (spooflistnb > 1)
{
iph->destaddr = (__u32) *(spooflist
+ ((int) (random() % spooflistnb)));
}
}
/*
struct in_addr tmp;
tmp.s_addr = iph->destaddr;
printf("IP_ADDR %s\n",inet_ntoa(tmp));
*/
}
int send_seqdata(int fd,__u32 data,char enableno)
{
int end;
end = 0;
set_new_ip(iph);
iph->id = htons(random());
if (enableno)
{
char tmpc[4];
__u32 tmpd;
*tmpc = seqno++;
memcpy(tmpc+sizeof(char),&data,sizeof(__u32)-1);
memcpy(&tmpd,tmpc,sizeof(__u32));
tmpd = htonl(tmpd);
memcpy(&tcph->seqnum,&tmpd,sizeof(__u32));
}
else
{
tcph->seqnum = htonl(data);
}
/* printf("SENT_DATA data %#x\n",tcph->seqnum); */
set_checksums();
end = sendto(fd, datagram,iph->totlen, 0,
(struct sockaddr *) &sain, sizeof (sain));
return end;
}
int send_data(int fd,char *data,int size)
{
int end;
static __u32 wbuffer;
static char rnd;
end = 0;
send_seqdata(fd,(__u32) size,0);
rnd = random() % 2;
if (rnd)
usleep(sdelay - ((int)(random() % sdelay_m)));
else
usleep(sdelay + ((int)(random() % sdelay_m)));
seqno = 0;
while ((size = size - (sizeof(__u32) -1)) > 0)
{
memcpy(&wbuffer,data,sizeof(__u32)-1);
send_seqdata(fd,wbuffer,1);
data = data + (sizeof(__u32) -1);
}
wbuffer = 0;
memcpy(&wbuffer,data,sizeof(__u32));
send_seqdata(fd,wbuffer,1);
return end;
}
int main(int argc,char **argv)
{
if (argc > 7)
{
char filebuffer[SEQMAX];
char *data;
__u16 sourceport,destport;
__u32 destip;
struct in_addr *tmpinaddr;
int sockfd,fd,rdata;
const int one = 1;
tmpinaddr = (struct in_addr *) malloc(sizeof(struct in_addr));
spooflist = (__u32 *) malloc((argc - 7) * sizeof(__u32));
freqnb = atoi(argv[2]);
sdelay = atoi(argv[3]) * 1000;
sdelay_m = sdelay / 10;
sourceport = (__u16) atoi(argv[4]);
destport = (__u16) atoi(argv[5]);
inet_aton(argv[6],tmpinaddr);
destip = (__u32) tmpinaddr->s_addr;
spooflistnb = argc - 7;
for (rdata = 0; rdata < spooflistnb; rdata++)
{
inet_aton(argv[7 + rdata],tmpinaddr);
*(spooflist + rdata) = (__u32) tmpinaddr->s_addr;
}
free(tmpinaddr);
srand(time(NULL));
datagram = (char *) malloc(DATAGRAM_SIZE * sizeof(char));
iph = (struct ipv4_header *) datagram;
tcph = (struct tcp_header *) (datagram
+ sizeof(struct ipv4_header));
tcpd = (struct data *) malloc(sizeof(struct data));
tcpd->data = (char *) (datagram + sizeof(struct ipv4_header)
+ sizeof(struct tcp_header));
tcpd->len = 0;
memset(&sain,0,sizeof(struct sockaddr_in));
sain.sin_family = AF_INET;
sain.sin_addr.s_addr = 1;
memset(datagram,0,DATAGRAM_SIZE);
data = DATA;
tcpd->len = strlen(data);
memcpy(tcpd->data,data,tcpd->len);
iph->version = 4;
iph->iphdrlen = 5;
iph->tos = 0;
iph->totlen = (__u16)(sizeof(struct ipv4_header)
+ sizeof(struct tcp_header) + tcpd->len);
iph->id = htons(random());
iph->fragoffset = 0;
iph->ttl = 0xff;
iph->proto = IPPROTO_TCP;
iph->ipchecksum = 0;
iph->sourceaddr = destip; /* inet_addr(IP_SRC); */
iph->destaddr = spooflist[0]; /* inet_addr(IP_DST); */
tcph->sourceport = htons(sourceport); /* htons(PORT_SRC); */
tcph->destport = htons(destport); /* htons(PORT_DST); */
tcph->seqnum = 0;
tcph->acknum = 0;
tcph->tcphdrlen = 5;
tcph->res = 0;
tcph->fin = 0;
tcph->syn = 1;
tcph->rst = 0;
tcph->psh = 0;
tcph->ack = 0;
tcph->urg = 0;
tcph->ece = 0;
tcph->ecn = 0;
tcph->window = htons(2);
tcph->tcpchecksum = 0;
tcph->urgptr = 0;
set_checksums();
if ((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0)
{
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_IP, IP_HDRINCL,(char *)&one,
sizeof (one)) < 0)
{
puts("Warning: Cannot set HDRINCL! You must be root\n");
exit(1);
}
if (send_seqdata(sockfd,0,0) < 0)
{
perror("sendto");
}
else
{
fputs("ok, starting the file transfert ...\n",stdout);
fd = open(argv[1],0);
while ((rdata = read(fd,filebuffer,SEQMAX)) > 0)
send_data(sockfd,filebuffer,rdata);
close(fd);
usleep(sdelay);
send_seqdata(sockfd,0,0);
}
close(sockfd);
free(datagram);
free(spooflist);
free(tcpd);
fputs("file transfert done.\n",stdout);
}
else
{
fprintf(stdout, "usage : %s <filename> <IP changement frequency"
"> <delay between 2 packet of %d bytes"
"(milliseconds)> <source port> <destination "
"port> <destination IP> <list of IP usable to "
"spoof>\n"
"(it is better to use IP of servers which have "
"about same latency to spoof)\n",argv[0],SEQMAX);
}
return 0;
}
/*
* Copyright (C) 2006, 2007 Sarzyniec Luc <mail@olbat.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* see the COPYING file for more informations */
#include <asm/types.h>
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN
#endif
struct ethernet_header
{
__u8 destmac[6];
__u8 sourcemac[6];
__u16 proto;
};
__extension__ struct ipv4_header
{
#if defined(LITTLE_ENDIAN)
__u8 iphdrlen:4,
version:4;
#elif defined(BIG_ENDIAN)
__u8 version:4,
iphdrlen:4;
#else
#error "Please define LITTLE_ENDIAN or BIG_ENDIAN"
#endif
__u8 tos;
__u16 totlen;
__u16 id;
__u16 fragoffset;
__u8 ttl;
__u8 proto;
__u16 ipchecksum;
__u32 sourceaddr;
__u32 destaddr;
};
__extension__ struct tcp_header
{
__u16 sourceport;
__u16 destport;
__u32 seqnum;
__u32 acknum;
#if defined(LITTLE_ENDIAN)
__u16 res:4,
tcphdrlen:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
ecn:1;
#elif defined(BIG_ENDIAN)
__u16 tcphdrlen:4,
res:4,
ecn:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Please define LITTLE_ENDIAN or BIG_ENDIAN"
#endif
__u16 window;
__u16 tcpchecksum;
__u16 urgptr;
};
struct pseudo_tcp_header
{
__u32 sourceaddr;
__u32 destaddr;
__u8 zero;
__u8 proto;
__u16 tcplen;
};
struct data
{
char *data;
unsigned int len;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment