zoukankan      html  css  js  c++  java
  • 路由器欺骗(原始套接字五)

    Windows系统保持着一张已知的路由器列表,我们可以使用route PRINT命令显示路由表,下面是笔者的电脑运行route PRINT命令后的结果:


      列表中到达某目的节点的第一项Gateway为默认路由器,如果默认路由器关闭,则位于列表第二项的路由器成为缺省路由器。缺省路由向发送者报告另一条到特定主机的更短路由,就是ICMP重定向。攻击者可利用ICMP重定向报文破坏路由,并伪装成路由器截获所有到某些目标网络或全部目标网络的IP数据包,进行窃听。

      显然,前文中我们只是讲解了发送ICMP Ping命令,可以编写更加通用的函数以便发送各种类型的ICMP报文。下面给出了美国北卡罗莱纳大学(University of North Carolina)计算机系的开放源代码的发送各类ICMP报文的程序:

    // icmp:发送各类ICMP报文
    icmp(type, code, dst, pa1, pa2) short type, code;
    IPaddr dst;
    char *pa1, *pa2;
    {
     struct ep *pep;
     struct ip *pip;
     struct icmp *pic;
     Bool isresp, iserr;
     IPaddr src;
     int i, datalen; 
     IcmpOutMsgs++;

     pep = icsetbuf(type, pa1, &isresp, &iserr);
     if (pep == 0)
     {
      IcmpOutErrors++;
      return SYSERR;
     }
     pip = (struct ip*)pep->ep_data;
     pic = (struct icmp*)pip->ip_data;

     datalen = IC_HLEN;

     /* we fill in the source here, so routing won't break it */

     if (isresp)
     {
      if (iserr)
      {
       if (!icerrok(pep))
       {
        freebuf(pep);
        return OK;
       } blkcopy(pic->ic_data, pip, IP_HLEN(pip) + 8);
       datalen += IP_HLEN(pip) + 8;
      }
      icsetsrc(pip);
     }
     else
      pip->ip_src = ip_anyaddr;
      pip->ip_dst = dst;

      pic->ic_type = (char)type;
      pic->ic_code = (char)code;
      if (!isresp)
      {
       if (type == ICT_ECHORQ)
        pic->ic_seq = (int)pa1;
       else
        pic->ic_seq = 0;
        pic->ic_id = getpid();
      }
      datalen += icsetdata(type, pip, pa2);

      pic->ic_cksum = 0;
      pic->ic_cksum = cksum(pic, datalen);

      ipsend(dst, pep, datalen, IPT_ICMP, IPP_INCTL, IP_TTL);
      return OK;
     }
     // icsetdata:根据报文类型填充相应的数据
     int icsetdata(type, pip, pa2)
     int type;
     struct ip *pip;
     char *pa2;
     {
      struct icmp *pic = (struct icmp *)pip->ip_data;
      int i, len;
     
      switch (type) {
       case ICT_ECHORP:
        len = pip->ip_len - IP_HLEN(pip) - IC_HLEN;
        if (isodd(len))
         pic->ic_data[len] = 0; /* so cksum works */
        return len;
       case ICT_DESTUR:
       case ICT_SRCQ:
       case ICT_TIMEX:
        pic->ic_mbz = 0; /* must be 0 */
        break;
       case ICT_REDIRECT:
        pic->ic_gw = (IPaddr)pa2;
        break;
       case ICT_PARAMP:
        pic->ic_ptr = (char) pa2;
        for (i=0; i<IC_PADLEN; ++i)
         pic->ic_pad[i] = 0;
         break;
       case ICT_MASKRP:
        blkcopy(pic->ic_data, &pa2, IP_ALEN);
        break;
       case ICT_ECHORQ:
        if ((int)pa2 > ECHOMAX(pip))
         pa2 = (char *)ECHOMAX(pip);
        for (i=0; i<(int)pa2; ++i)
         pic->ic_data[i] = i;
         return (int)pa2;
       case ICT_MASKRQ:
        blkcopy(pic->ic_data, &ip_anyaddr, IP_ALEN);
        return IP_ALEN;
      }
      return 0;
    }


      而下面的代码则显示了计算机在收到ICMP redirect报文后的行为:

    // icredirect:处理接收到的ICMP redirect报文,刷新路由缓存
    int icredirect(pep) struct ep *pep;
    {
     struct route *prt;
     struct ip *pip, *pip2;
     struct icmp *pic;
     IPaddr mask;

     pip = (struct ip*)pep->ep_data;
     pic = (struct icmp*)pip->ip_data;
     pip2 = (struct ip*)pic->ic_data;

     if (pic->ic_code == ICC_HOSTRD)
      mask = ip_maskall;
     else
      netmask(mask, pip2->ip_dst);
      prt = rtget(pip2->ip_dst, RTF_LOCAL);
      if (prt == 0)
      {
       freebuf(pep);
       return OK;
      }
      if (pip->ip_src == prt->rt_gw)
      {
       rtdel(pip2->ip_dst, mask);
       rtadd(pip2->ip_dst, mask, pic->ic_gw, prt->rt_metric, prt->rt_ifnum,IC_RDTTL);
      }
      rtfree(prt);
      freebuf(pep);
     return OK;
    } 


      University of North Carolina完整的ICMP代码下载地址为:http://www.cs.unc.edu/~dewan/242/s00/xinu-pentium/icmp/

  • 相关阅读:
    修改文件小练习
    登录、注册、删除小练习
    自动生成用户名和密码
    自动生成密码文件
    监控日志被攻击情况-小练习
    随机函数_手机自动生成小练习
    as与c++的反射机制对比
    as中的陷阱
    关于as中的事件与回调函数
    身份证号码验证
  • 原文地址:https://www.cnblogs.com/happy-pm/p/3809498.html
Copyright © 2011-2022 走看看