手把手教你玩转ARP包【数据包的游戏系列之一】 by PiggyXP【小猪】

Wireshark-ARP数据包 ARP:地址解析协议;    是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;    即当一台主机把以太网数据帧发送到位于同一局域网上的另一台主机时,是根据 48 bit的以太网地址来确定目的接口的(这是ip地址是没法找到目标主机的);   在以太网上解析 I P地址时, A R P请求 阅读详情

前   言

         首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料以及帮助^_^

经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,,我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码(为了照顾大多数朋友,我提供的都是MFC的源码)。

不过由于也是初学者,疏漏之处还望不吝指正。

本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^

 

OK,. Let’s go !  Have fun!! q^_^p

 

第一篇         手把手教你玩转ARP包

   目录:

    一.    关于ARP协议的基础知识

     1.        ARP的工作原理

     2.        ARP包的格式

  二。发送数据包的编程实现
          1.  填充数据包
          2.  发送数据包
  三。一些附加步骤及说明
         1.  如果在VC中使用winpcap
         2.  获得网卡信息列表
         3.  获得系统ARP信息列表
  作者:

    优快云  VC/MFC 网络编程 PiggyXP  ^_^

 

一.             关于ARP协议的基础知识

1.ARP的工作原理

本来我不想在此重复那些遍地都是的关于ARP的基本常识,但是为了保持文章的完整性以及照顾初学者,我就再啰嗦一些文字吧,资深读者可以直接跳过此节。

 

我们都知道以太网设备比如网卡都有自己全球唯一的MAC地址,它们是以MAC地址来传输以太网数据包的,但是它们却识别不了我们IP包中的IP地址,所以我们在以太网中进行IP通信的时候就需要一个协议来建立IP地址与MAC地址的对应关系,以使IP数据包能发到一个确定的地方去。这就是ARP(Address Resolution Protocol,地址解析协议)。

 

讲到此处,我们可以在命令行窗口中,输入

     arp –a

来看一下效果,类似于这样的条目

210.118.45.100    00-0b -5f -e6-c5-d7    dynamic

就是我们电脑里存储的关于IP地址与MAC地址的对应关系,dynamic表示是临时存储在ARP缓存中的条目,过一段时间就会超时被删除(xp/2003系统是2分钟)。

 

这样一来,比如我们的电脑要和一台机器比如210.118.45.1通信的时候,它会首先去检查arp缓存,查找是否有对应的arp条目,如果没有,它就会给这个以太网络发ARP请求包广播询问210.118.45.1的对应MAC地址,当然,网络中每台电脑都会收到这个请求包,但是它们发现210.118.45.1并非自己,就不会做出相应,而210.118.45.1就会给我们的电脑回复一个ARP应答包,告诉我们它的MAC地址是xx-xx-xx-xx-xx-xx,于是我们电脑的ARP缓存就会相应刷新,多了这么一条:

210.118.45.1   xx-xx-xx-xx-xx-xx   dynamic

 

为什么要有这么一个ARP缓存呢,试想一下如果没有缓存,我们每发一个IP包都要发个广播查询地址,岂不是又浪费带宽又浪费资源?

     而且我们的网络设备是无法识别ARP包的真伪的,如果我们按照ARP的格式来发送数据包,只要信息有效计算机就会根据包中的内容做相应的反应.

 

试想一下,如果我们按照ARP响应包的相应的内容来刷新自己的ARP缓存中的列表,嘿嘿,那我们岂不是可以根据这点在没有安全防范的网络中玩些ARP包的小把戏了?在后面的文章里我就手把手来教你们如何填充发送ARP包,不过先别急,我们再继续学点基础知识^_^

 

2.ARP包的格式

 

     既然我们要来做一个我们自己的ARP包,当然首先要学习一下ARP包的格式。

 

     从网络底层看来,一个ARP包是分为两个部分的,前面一个是物理帧头,后面一个才是ARP帧。

         首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLC Header,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。  

DLC Header

字段

长度(Byte)

默认值

备注

接收方MAC

6

 

广播时,为 ff-ff-ff-ff-ff-ff

发送方MAC

6

 

 

Ethertype

2

0x0806

0x0806是ARP帧的类型值

                           图1 物理帧头格式

 

     图1是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接收端的物理地址罢了,是不是很简单呢?

       接下来我们看一下ARP帧的格式.  

ARP Frame

字段

长度(Byte)

默认值

备注

硬件类型

2

0x1

以太网类型值

上层协议类型

2

0x0800

上层协议为IP协议

MAC地址长度

1

0x6

以太网MAC地址长度为 6

IP地址长度

1

0x4

IP地址长度为 4

操作码

2

 

0x1表示ARP请求包,0x2表示应答包

发送方MAC

6

 

 

发送方IP

4

 

 

接收方MAC

6

 

 

接收方IP

4

 

 

填充数据

18

 

因为物理帧最小长度为64字节,前面的42字节再加上4个CRC校验字节,还差18个字节

                             图2 ARP帧格式

 

我们可以看到需要我们填充的同样也只是MAC,IP,再加上一个1或2的操作码而已。

     ..................

 

    ======================================================================= 

晕,本来想一口气发完,没想到这么点字就到了64k限额了,不知道是不是彩色字和表格的关系,没办法,只好把文章掰成四、五瓣来发了-_-b,下次再说吧

 

请期待下文 : )

 

                                                                                                -------    Finished at  2004-05-29 19:41

                                                                                                -------    Made In     DLUT | DIP

第二篇   手把手教你捕获数据包

目录:

一.捕获数据包的实现原理

二.捕获数据包的编程实现:

1.   raw socket的实现方法

2.   Winpcap的实现方法

a.      枚举本机网卡的信息

b.      打开相应网卡并设置为混杂模式

c.       截获数据包并保存为文件

 

作者:

优快云  VC/MFC 网络编程版主 PiggyXP 

 

一.捕获数据包的实现原理:--------------------------------------------------------------------

在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。

所以我们要想实现截获流经网络设备的所有数据包,就要采取一点特别的手段了:

将网卡设置为混杂模式。

这样一来,该主机的网卡就可以捕获到所有流经其网卡的数据包和帧。

但是要注意一点,这种截获仅仅是数据包的一份拷贝,而不能对其进行截断,要想截断网络流量就要采用一些更底层的办法了,不在本文的讨论范围之内。

 

二. 捕获数据包的编程实现:

1.raw socket的实现方法--------------------------------------------------------------------

不同于我们常用的数据流套接字和数据报套接字,在创建了原始套接字后,需要用WSAIoctl()函数来设置一下,它的定义是这样的

int WSAIoctl(

  SOCKET s,

  DWORD dwIoControlCode,

  LPVOID lpvInBuffer,

  DWORD cbInBuffer,

  LPVOID lpvOutBuffer,

  DWORD cbOutBuffer,

  LPDWORD lpcbBytesReturned,

  LPWSAOVERLAPPED lpOverlapped,

  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

);

虽然咋一看参数比较多,但是其实我们最关心的只是其中的第二项而已,我们需要做的就是把第二项设置为SIO_RCVALL,讲了这么多其实要做的就是这么一行代码,很简单吧?^_^

 当然我们还可以指定是否亲自处理IP头,但是这并不是必须的。

完整的代码类似与如下这样,加粗的代码是与平常不同的需要注意的地方:

( 为了让代码一目了然,我把错误处理去掉了,下同)

 

#include “WinSock2.h”

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

 

SOCKET SnifferSocket

  WSADATA wsaData;

  iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);           //开启winsock.dll

                                 

SnifferSocket=WSASocket(AF_INET,             //创建raw  socket

SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

 

  char FAR name[128];                                //获取本机IP地址

gethostname(name, sizeof(name));

  struct hostent FAR * pHostent;

  pHostent = gethostbyname(name);

 

  SOCKADDR_IN sa;                           //填充SOCKADDR_IN结构的内容

  sa.sin_family = AF_INET;

  sa.sin_port = htons(6000);           // 端口号可以随便改,当然与当然系统不能冲突

  memcpy(&(sa.sin_addr),pHostent->h_addr,pHostent->h_length);

 

bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));            //绑定

 

  // 置ioctl来接收所有网络数据,关键步骤

  DWORD dwBufferLen[10] ;

  DWORD dwBufferInLen = 1 ;

  DWORD dwBytesReturned = 0 ;

  WSAIoctl(SnifferSocket, IO_RCVALL,&dwBufferInLen, izeof(dwBufferInLen),

        &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );

 

至此,实际就可以开始对网络数据包进行嗅探了,而对于数据包的接收还是和普通的socket一样,通过recv()函数来完成,因为这里涉及到不同的socket模型,接收方法差别很大,所以在此就不提供接收的代码了。

 

2.winpcap的实现方法:-----------------------------------------------------------------------

winpcap驱动包,是我们玩转数据包不可或缺的好东东,winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报,主要为我们提供了四大功能:

功能:
    1>
捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报;
    2>
在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉;
    3>
在网络上发送原始的数据报;
    4>
收集网络通信过程中的统计信息

如果环境允许的话(比如你做的不是木马程序),我还是推荐大家用winpcap来截获数据包,因为它的功能更强大,工作效率更高,唯一的缺点就是在运行用winpcap开发的程序以前,都要在主机上先安装winpcap的driver。

而且一会我们就会发现它比raw socket功能强大的多,而且工作得更为底层,最明显的理由就是raw socket捕获的数据包是没有以太头的,此乃后话。

至于怎么来安装使用,请参考本系列的系列一《手把手教你玩转ARP包中的》,里面有详细的加载winpcap驱动的方法^_^

废话不多说了,让我们转入正题, 具体用winpcap来截获数据包需要做如下的一些工作:

A . 枚举本机网卡的信息(主要是获得网卡的名称)

   其中要用到pcap_findalldevs函数,它是这样定义的

   /*************************************************

int pcap_findalldevs  (  pcap_if_t **    alldevsp, 

                             char *    errbuf

                          ) 

     功能:

             枚举系统所有网络设备的信息

     参数:  alldevsp:  是一个pcap_if_t结构体的指针,如果函数pcap_findalldevs函数执行成功,将获得一个可用网卡的列表,而里面存储的就是第一个元素的指针。

             Errbuf:    存储错误信息的字符串

     返回值: int :   如果返回0 则执行成功,错误返回 -1。

  *************************************************/

   我们利用这个函数来获得网卡名字的完整代码如下:

 

       pcap_if_t* alldevs;

       pcap_if_t* d;

       char errbuf[PCAP_ERRBUF_SIZE];

       pcap_findalldevs(&alldevs,errbuf);       // 获得网络设备指针

       for(d=alldevs;d;d=d->next)               // 枚举网卡然后添加到ComboBox中

       {

d->name;                            // d->name就是我们需要的网卡名字字符串,按照你// 自己的需要保存到你的相应变量中去

       }

pcap_freealldevs(alldevs);               // 释放alldev资源

 

请期待下文。。。。。^_^
目录:

二。发送数据包的编程实现
   1.  填充数据包
   2.  发送数据包
三。一些附加步骤及说明
   1.  如果在VC中使用winpcap
   2.  获得网卡信息列表
   3.  获得系统ARP信息列表
 
         ................紧接上 文................
 
1.        填充数据包
 
下面我举个填充包头的例子,我首先定义个了一个转换字符的函数,如下
 
/****************************************************************************
 *   Name & Params::
 *             formatStrToMAC
 *             (
 *                 const LPSTR lpHWAddrStr : 用户输入的MAC地址字符串
 *                 unsigned char *HWAddr :   返回的MAC地址字符串(赋给数据包结构体)
 *             )
 *   Purpose:
 *             将用户输入的MAC地址字符转成数据包结构体需要的格式
 ****************************************************************************/
void formatStrToMAC(const LPSTR lpHWAddrStr, unsigned char *HWAddr)
{
       unsigned int i, index = 0, value, temp;
      unsigned char c;
 
      _strlwr(lpHWAddrStr);                                                   // 转换成小写
 
      for (i = 0; i < strlen(lpHWAddrStr); i++)
     {
           c = *(lpHWAddrStr + i);
            if (( c>='0' && c<='9' ) || ( c>='a' && c<='f' ))
           {
               if (c>='0' && c<='9')  temp = c - '0';                         // 数字
               if (c>='a' && c<='f')  temp = c - 'a' + 0xa;               // 字母
               if ( (index % 2) == 1 )
              {
                   value = value*0x10 + temp;
                   HWAddr[index/2] = value;
              }
              else value = temp;
              index++;
         }
               if (index == 12) break;
        }
}
 
// 开始填充各个字段
ARPPACKET ARPPacket;                                                  // 定义ARPPACKET结构体变量
 
    memset(&ARPPacket, 0, sizeof(ARPPACKET));                      // 数据包初始化
 
     formatStrToMAC(“DLC源MAC字符串”,ARPPacket.dlcHeader.SrcMAC);       // DLC帧头
     formatStrToMAC(“DLC目的MAC字符串”,ARPPacket.dlcHeader.DesMAC);
 
     formatStrToMAC(“ARP源MAC字符串”,ARPPacket.arpFrame.Send_HW_Addr);  // 源MAC
     ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP);              // 源IP
     formatStrToMAC(“ARP目的MAC字符串”,ARPPacket.arpFrame.Targ_HW_Addr); // 目的MAC
     ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP);               // 目的IP
    
     ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType);        // arp包类型
    
     // 自动填充的常量
     ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型
     ARPPacket.arpFrame.HW_Type = htons((unsigned short)1);           // 硬件类型
     ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800);    // 上层协议类型
     ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6;                 // MAC地址长度
     ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4;               // IP地址长度
 
That’s all ! ^_^
填充完毕之后,我们需要做的就是把我们的ARPPACKET结构体发送出去
 
2.发送ARP数据包:
 
我们发送ARP包就要用到winpcap的api了,具体步骤及函数是这样的,为了简单易懂,我把错误处理的地方都去掉了,详见代码
/**********************************************************************
*    Name & Params::
*             SendARPPacket()
*    Purpose:
*             发送ARP数据包
*    Remarks:
*             用的是winpcap的api函数
***********************************************************************/
void SendARPPacket()
{
     char *AdapterDeviceName =GetCurAdapterName();     // 首先获得获得网卡名字
 
     lpAdapter = PacketOpenAdapter(AdapterDeviceName);     // 根据网卡名字打开网卡
 
     lpPacket = PacketAllocatePacket();               // 给PACKET结构指针分配内存
 
     PacketInitPacket(lpPacket, &ARPPacket, sizeof(ARPPacket)); //初始化PACKET结构指针
                                             // 其中的ARPPacket就是我们先前填充的ARP包
 
     PacketSetNumWrites(lpAdapter, 1);               // 每次只发送一个包
 
     PacketSendPacket(lpAdapter, lpPacket, true)       // Send !!!!! ^_^
 
     PacketFreePacket(lpPacket);                     // 释放资源
     PacketCloseAdapter(lpAdapter);
}
 
呵呵,至此,关于ARP包最关键的部分就讲完了,你现在就可以来随心所欲的发送自己的ARP包了
 
既然作为一篇“科普文章”,接下来我再讲一讲与整个项目有关的附加步骤以及说明
 
三.附加步骤以及说明
1. 如何在VC中使用winpcap驱动
       虽然winpcap开发包使用起来非常简便,但是前期准备工作还是要费一番功夫的,缺一不可。^_^
       首先就是要安装它的驱动程序了,可以到它的主页下载,更新很快的
     下载WinPcap auto-installer (driver +DLLs),直接安装就好了,或者我提供的代码包里面也有。
     希望以后用winpcap作开发的朋友,还需要下载 Developer's pack,解压即可。
    
        然后,需要设置我们工程的附加包含目录为我们下载Developer's pack开发包的Inclulde目录,连接器的附加依赖库设置为Developer's pack的lib目录。
       当然,因为我们的工作比较简单,就是借用winpcap发送数据包而已,所以只用从
winpcap开发包的include文件夹中,拷贝Packet32.h,到我们的工程来,并且包含它就可
以, 但是要注意,Packet32.h本身还要包含一个Devioctl.h,也要一并拷贝进来,当然还有运
行库Packet.lib,一共就是需要拷贝3个文件了,如果加入库不用我多说了吧,在工程里面设
置,或者是在需要它的地方加入 #pragma comment(lib, "Packet.lib")了。
 
        整个项目其实可以分为四个部分,填充数据包、发送数据包、枚举系统网卡列表和
相关信息以及枚举系统ARP缓存列表,下面我再讲一下如何获得系统的网卡以及ARP列
表,这两个部分都要用到IP Helper的api,所以要包含<Iphlpapi.h>以及库文件Iphlpapi.lib,
其实都是很简单的,只用寥寥几行就OK了
2.     枚举系统网卡以及信息
最好是先定义关于网卡信息的一个结构体,这样显得结构比较清晰
// 网卡信息
typedef struct tagAdapterInfo         
{
              char szDeviceName[128];           // 名字
              char szIPAddrStr[16];             // IP
              char szHWAddrStr[18];             // MAC
              DWORD dwIndex;                    // 编号         
}INFO_ADAPTER, *PINFO_ADAPTER;
 
/*********************************************************************
*    Name & Params::
*             AddAdapInfoToList
*             (
*                  CListCtrl& list :  CARPPlayerDlg传入的list句柄
*             )
*    Purpose:
*             获得系统的网卡信息,并将其添加到list控件中
*    Remarks:
*             获得网卡IP及MAC用到了IpHelper api GetAdaptersInfo
******************************************************************/
void AddAdapInfoToList(CListCtrl& list)
{
     char tempChar;
     ULONG uListSize=1;
     PIP_ADAPTER_INFO pAdapter;           // 定义PIP_ADAPTER_INFO结构存储网卡信息
     int nAdapterIndex = 0;
 
     DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);//关键函数
 
     if (dwRet == ERROR_BUFFER_OVERFLOW)
     {
  PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO)new(char[uListSize]);
  dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);
  if (dwRet == ERROR_SUCCESS)
  {
     pAdapter = pAdapterListBuffer;
     while (pAdapter)                                              // 枚举网卡然后将相关条目添加到List中
     {
        // 网卡名字
          CString strTemp = pAdapter->AdapterName;                    
          strTemp = "//Device//NPF_" + strTemp;                        // 加上前缀
          list.InsertItem(nAdapterIndex,strTemp);                 
          strcpy(AdapterList[nAdapterIndex].szDeviceName,strTemp);
          // IP
          strcpy(AdapterList[nAdapterIndex].szIPAddrStr,
                                                 pAdapter->IpAddressList.IpAddress.String );
          list.SetItemText(nAdapterIndex,1,AdapterList[nAdapterIndex].szIPAddrStr);
          // MAC
          formatMACToStr( AdapterList[nAdapterIndex].szHWAddrStr, pAdapter->Address );
          list.SetItemText(nAdapterIndex,2,AdapterLis[nAdapterIndex].szHWAddrStr);
          // 网卡编号
          AdapterList[nAdapterIndex].dwIndex = pAdapter->Index;         
 
          pAdapter = pAdapter->Next;
          nAdapterIndex ++;
          }
     delete pAdapterListBuffer;
     }
}
}
 
2)获取ARP条目列表
// ARP条目信息
typedef struct tagARPInfo            
{
     char szIPAddrStr[16];              // IP
     char szHWAddrStr[18];             // MAC
     DWORD dwType;                     // 类型
}INFO_ARP, *PINFO_ARP;
 
 
/**********************************************************************
*    Name & Params::
*             AddARPInfoToList
*             (
*                  CListCtrl& list :             CARPPlayerDlg传入的list句柄
*                  const short nAdapterIndex :   用户选中的网卡编号
*             )
*    Purpose:
*             读入系统的ARP缓存列表,.并添加到对话框中
*    Remarks:
*             用到了IpHelper api GetIpNetTable
*             而且用到了WinSock的api,所以要包含<WinSock2.h>
*****************************************************************/
void AddARPInfoToList(CListCtrl& list,const short nAdapterIndex)
{
     char tempChar;
     DWORD dwListSize = 1;
     DWORD dwRet;
     in_addr inaddr;
     list.DeleteAllItems();
 
     dwRet = GetIpNetTable((PMIB_IPNETTABLE)&tempChar, &dwListSize, TRUE);  // 关键函数
     if (dwRet == ERROR_INSUFFICIENT_BUFFER)
     {
         PMIB_IPNETTABLE pIpNetTable = (PMIB_IPNETTABLE)new(char[dwListSize]);
         dwRet = GetIpNetTable(pIpNetTable, &dwListSize, TRUE);
         if (dwRet == ERROR_SUCCESS)
         {
              for (int i=0; i<(int)pIpNetTable->dwNumEntries; i++)
              {
                  // IP
                   inaddr.S_un.S_addr = pIpNetTable->table[i].dwAddr;
                   strcpy( ARPList[i].szIPAddrStr, inet_ntoa(inaddr) );  
                   // MAC
                   formatMACToStr( ARPList[i].szHWAddrStr, pIpNetTable->table[i].bPhysAddr );
                   // Type
                   ARPList[i].dwType = pIpNetTable->table[i].dwType;        
 
                   if (AdapterList[nAdapterIndex].dwIndex != pIpNetTable->table[i].dwIndex)                                                       continue;
 
                   list.InsertItem(i,ARPList[i].szIPAddrStr);
                   list.SetItemText(i,1,ARPList[i].szHWAddrStr);
                   switch(ARPList[i].dwType) {           // 根据type的值来转换成字符显示
                   case 3:
                       list.SetItemText(i,2,"Dynamic");
                       break;
                   case 4:
                       list.SetItemText(i,2,"Static");
                       break;
                   case 1:
                       list.SetItemText(i,2,"Invalid");
                   default:
                       list.SetItemText(i,2,"Other");
                   }
              }
         }
         delete pIpNetTable;
     }
}
        这样一来,我们基本上大功告成了,其他还有一些东西在这里就不讲了,大家可以下载我的代码看看就好了。
        下面我们来用ARP包玩一些小把戏 ^_^。
本篇目录:

    四。ARP包的游戏

      1 .   小伎俩

      2.    ARP欺骗的实现

      3.   基于ARP欺骗的监听原理 

 

四.ARP包的游戏

既然我们可以自己来填充数据包,那么来玩些ARP的“小游戏”欺骗就是易如反掌了,当然,是在没有安全防护的网络里 ,比如只有hub或者交换机把你们相连,而没有路由分段……^_^

下面我就由浅入深的讲一些介绍一些关于ARP的小伎俩。

 

1. 小伎俩

1)       你可以试着发一个请求包广播,其中的ARP帧里关于你的信息填成这样:

(为了节省篇幅,我只写需要特别指出的填充字段)

发送方MAC

6

随便乱填一个错误的

发送方IP

4

 填上你的IP

   出现什么结果?是不是弹出一个IP地址冲突的提示?呵呵,同样的道理,如果发送方IP填成别人的,然后每隔1秒发一次………..-_-b

 

2)       比如你们都靠一个网关192.168.0.1 上网 ,如果你想让192.168.0.77 上不了网,就可以伪装成网关给192.168.0.77发一个错误的ARP响应包, like this

发送方MAC

6

随便乱填一个错误的

发送方IP

4

 网关IP 192.168.0.1

接收方就填192.168.0.77的相关信息,发送之后,它还能上网不?

这样能折腾他好一阵子了,只要它的系统得不到正确的到网关的ARP映射表它就一直上不了网了 ^_^

          呵呵类似的伎俩还有很多,不过只停留在这点东西上也没什么意思,还是看看稍微高深一点的吧^_^

 

       2.        ARP欺骗

因为在以太网里,网络设备就是靠MAC信息来识别的计算机的,比如A电脑知道MAC地址为22-22-22-22-22-22的电脑是B,而如果我给A发送一个ARP响应包,告诉它我的MAC是22-22-22-22-22-22的话,A同样会认为我的计算机是B了,那么好,我们设想有这么一个环境,

A的防火墙只对IP为192.168.0.2 MAC为 22-22-22-22-22-22的B有信任关系,而且A打开了21端口提供FTP服务,正常情况下因为防火墙的缘故我们的计算机是连不到A的,

于是我们想办法让B down掉,或者在它关机的时候,我们把我们的IP改成B的192.168.0.2,然后给A发送一个ARP回应包,告诉A更新一下ARP缓存列表,192.168.0.2的IP映射到我们的
MAC
地址上来,于是,奇迹出现了,我们可以连到A的FTP上了,防火墙失效了^_^

不过这个办法只能在同网段内生效,如果我们和A不在一个网段内,那就要复杂的多了,还要配合ICMP的重定向来控制报文的路由,这个我准备在以后阐述ICMP包的时候详细讲解,就不再此多说了。

    3.        基于ARP欺骗的监听原理

监听的技术有很多了,不过我们常用的sniffer工具只能在基于hub的网络中起作用,碰到哪怕是交换机都无能为力了,这个时候我们的ARP欺骗技术就派上用场了。

还是假设有三台主机A,B,还有我们的主机,位于同一个交换式局域网中

A与B正在通信,如果我们想要刺探A――>B通信的内容,于是我们就可以给A发送一个伪造的ARP回应包,告诉A,B的IP对应的MAC条目为我们的MAC地址,于是,A也就会相应的刷新自己的ARP缓存,将发给B的数据,源源不断的发送到我们的主机上来,这样我就可以对接收到的数据包进行分析就好了,达到了监听的目的。当然,因为动态ARP缓存是动态的,有超时时间的,所以我们必须每隔一段时间就给A发送一个ARP回应包

虽然我们这样达到了目的,但是A到B的通信却被停止了,为了不让B发现,我们还要对每次接收到的数据包进行转发,全部都转发给B,这样就天衣无缝了^_^

同样的,如果我们还想监听B à A的数据包,一样给B发一个ARP回应包,告诉B,A的IP对应的MAC是我们的主机MAC,于是B到A的数据包也源源不断的发到我们的主机上来了,当然我们也是一样要对这些数据包进行转发,如图:

A  <------>   我们的主机   <------>   B

一切都无误的话,A和B的通信内容就这样不知不觉的被我们监听到了^_^

具体的代码实现由于篇幅的关系我就不放在这里讲了,如果需要我就专门另写篇文章附上完整代码吧

至此,我们的ARP基础知识就讲完了,但愿您能从中有所收获

 

后记:

 因为本人开发都是使用VC++.net 2003,所以没有安装.net的朋友是打不开工程的,可以试一下vckbase上的工程转换工具,本人没有试过,不保证有效

             http://www.vckbase.com/tools/assist/prjconverter.rar

而且本文的代码使用了winpcap开发包,是要另外安装ainpcap驱动。

读者可以安装我代码包里的驱动,不过它更新很快,可以到它主页上去下载最新版本

        http://winpcap.polito.it/install/default.htm

    不做开发的读者,只用下载并安装这个就可以了WinPcap auto-installer (driver +DLLs)

   我的原文及源码下载地址稍后贴出,请关注本帖^_^

   

     源码下载地址,新鲜出炉,非常感谢 _foo 兄弟提供的空间

http://iunknown.com.cn/youkuaiyun.comwork/ARPPlayer_By_PiggyXP.rar

arp包格式分析及实例解析 一、ARP包格式分析 在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址,而数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得目的主机的硬件地址。ARP协议就起到这个作用。源主机发出ARP请求,询问“IP地址是192.168.0.1的主机的硬件地址是多少”,并将这个请求广播到本地网段(以太网 阅读详情

相关推荐

如何解决ipa包上传App Store Connect时出现的无效二进制文件问题

本文详细解析了ipa包上传App Store Connect时出现无效二进制文件问题的常见原因及解决方案。从Scheme配置、架构支持到权限声明,提供了全面的检查步骤和实用技巧,帮助开发者快速定位并解决上传问题,确保应用顺利通过审核。

weixin_28833069的博客 315

ARP游戏,很好玩的,以前经常用师兄的WIN版本在网吧,害人~~呵呵

 我写这片文章只是想让你明白深刻理解某一协议的好处。 高手免看。 如果有人利用这片文章所做的一切事情,盖不负责。 网上关于ARP的资料已经很多了,就不用我都说了。 用某一位高手的话来说,“我们能做的事情很多,唯一受 限制的是我们的创造力和想象力”。 ARP也是如此。 以下讨论的机子有 一个要攻击的机子:10.5.4.178              

【GTA: Vice City】 1551

保姆级教程:在RK3576上配置USB网卡从零到外网访问(附udev规则详解)

本文提供了在RK3576开发板上配置USB网卡的完整教程,涵盖从内核驱动、udev规则到网络路由的全流程。重点讲解了如何利用USB Gadget功能实现高速网络连接,并构建稳定的算力集群,确保多设备间通信及外网访问。

grass的博客 460

手把手教你玩转ARP包(一)【数据包的游戏系列之一】

前   言          首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料以及帮助^_^ 经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,,我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带

Thinking -Walking@未名 897

软件工程实验报告--用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

用Visio绘制数据流图、ER图、状态图、软件结构图、程序流程图、系统流程图

m0_73814332的博客 4163

SAP 系统里生成 PDF 的几条主干路径:从 Spool 转换到 Adobe 原生渲染,再到 BTP 云服务

本文系统梳理了SAP生态中PDF生成的多种技术方案,包括Spool转换、OTF转换、Smart Forms/Adobe Forms原生生成以及云端服务等不同路径。文章通过实际案例和代码示例,详细分析了各方案的适用场景、技术要点和工程实践建议,特别强调了多语言支持、字体处理、性能优化等关键因素。针对不同业务需求,提供了从简单导出到复杂交互式PDF的完整解决方案框架,为SAP环境下的PDF处理提供了实用指南。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 289

手把手教你玩转ARP包(完)【数据包的游戏系列之一】

作者:   优快云  VC/MFC 网络编程 PiggyXP  ^_^ 本篇目录:    四。ARP包的游戏      1 .   小伎俩      2.    ARP欺骗的实现      3.   基于ARP欺骗的监听原理  四.既然我们可以自己来填充数据包,那么来玩些ARP的“小游戏”欺骗就是易如

小猪的网络编程 2万+

【ROS机器人系统】自主导航+YOLO目标检测+语音播报

完成自主导航功能,并在小车移动至指定地点的过程中,通过机器人的摄像头检测导航途中所见物体,识别出物体的种类(框选出不同物体并标注识别结果),结合科大讯飞语音合成模块对识别结果进行语音播报。..............................

南京大学软件工程硕士在读 2万+

兄弟,有没有PiggyXP【小猪】老大的ARP工程文件,发一个给我,谢谢了。邮箱:798063697@qq.com

<br />兄弟,有没有PiggyXP【小猪】老大的ARP工程文件,发一个给我,谢谢了。邮箱:798063697@qq.com

wanyihui1989的专栏 1149

嵌入式工程师成长之路(3)——PCB设计

带有目的的学:要知道,PCB板子做出来需要我们给厂家哪些东西,我们设计板子的时候,需要遵循哪些设计规范,防止画好也是块废板子。然后再逐步开始学习画板。

云轩阁 8万+

RK3588 buildroot 双网口bonding调试

本文介绍了Rockchip Buildroot中配置网络冗余的方法,通过bonding技术将多个物理网口合并为逻辑接口。主要内容包括:1)7种常见bonding模式的特点及适用场景;2)RK3588的具体配置流程,包括内核配置(启用bonding驱动、修改dts)、添加ifenslave工具;3)系统编译和网络状态检查。

501846585_QQAndroid_java 460

基于IMD的包过滤防火墙原理与实现 by PiggyXP【小猪】

一、前言二、IMD中间层技术介绍三、passthru例程分析四、部分演示代码五、驱动编译与安装六. 总结一、前言    前段时间,在安全焦点上看到了TOo2y朋友写的《基于SPI的数据报过滤原理与实现》,很是不错。文章中提到的基于SPI的数据报拦截技术是在用户级的。用户级的拦截有其优势,实现方便、便于移植、通用性强,但是,用户级并不能得到所有的数据报。本文提到的基于IMD的数据报过滤则是属于内核级

XmagicX的专栏 1389

18、探索隐私工程技术的前沿:从理论到实践

本文深入探讨了隐私工程技术的核心概念、关键技术及其应用场景,分析了加密技术、访问控制和用户界面设计等在隐私保护中的作用,并结合数据库保护、物联网设备等实际场景进行阐述。同时,文章还讨论了隐私工程技术面临的挑战与未来发展趋势,提出了数据最小化原则、差分隐私、隐私增强技术等优化策略以及隐私设计、隐私影响评估等最佳实践,最后展望了新兴技术对隐私保护的影响及法规推动下的发展方向。

weixin_35307279的博客 373

终于把我的以前写的代码都找回来了呵呵,就等着空间上传了

把我以前的几个硬盘搜了个底朝天,基本上是把以前自己编写的一些网络编程方面的文字和代码都找齐了呵呵基于包括以下这几个方面:1. 网络服务器通信的几个模型框架代码:阻塞模型、WASEventSelect、重叠模型、完成例程等等2. 网络监听和网络数据分析的代码:可以分析IP、TCP/UDP、以及应用层(只包括email)的代码3. 其他网络方面的代码:ARP实验的代码、修改网卡MAC地

小猪的网络编程 3865

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

手把手教你玩转ARP包(三)【数据包的游戏系列之一】

作者:优快云  VC/MFC 网络编程 PiggyXP  ^_^   目录: 二。发送数据包的编程实现   1.  填充数据包   2.  发送数据包三。一些附加步骤及说明   1.  如果在VC中使用winpcap   2.  获得网卡信息列表   3.  获得系统ARP信息列表          ................紧接上文..

小猪的网络编程 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

手把手教你捕获数据包(下)【数据包的游戏系列之二】

B. 打开相应网卡并设置为混杂模式:    在此之前肯定要有一段让用户选择网卡、并获得用户选择的网卡的名字的代码,既然上面已经可以获得所有网卡的名字了,这段代码就暂且略过了。    我们主要是要用到 pcap_open_live 函数,不过这个函数winpcap的开发小组已经建议用pcap_open 函数来代替,不过因为我的代码里面用的就是pcap_open_live,所以也不便于修改了,不过pc

小猪的网络编程 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

深度剖析WinPcap之(七)——获得与释放网络适配器设备列表(2)

转自http://eslxf.blog.51cto.com/918801/198579   st1/:*{behavior:url(#ieooui) } 1.3    wpcap.dll中相应函数接口的实现 1.3.1        pcap_findalldevs函数  wpcap/libpcap/fad-win32.c(219): 218-327 参数alldevsp返回所找到的适

理性的幻想 1079

【Unity知识速递】第7期 Unity 6.6 深度解析:WebGPU 正式版与 WebAssembly64,Web 游戏的内存革命

如何启用 Wasm64?需要注意的是,Wasm64 需要浏览器支持 Memory64 提案,目前主流浏览器的最新版本都已支持。一句话总结: Unity 6.6 用 WebGPU 转正、Wasm64 16GB 内存和渐进式加载三连击,将 Web 游戏的体验天花板又往上推了一大截——Web 平台不再是"妥协版",正在成为真正的一等公民。Unity 6.6 新增了 WebAssembly64(Wasm64) 构建选项,这可能是本次更新中对 Web 游戏开发者影响最大的一项升级。

crystal_WJT的博客 435

设计模式(unity游戏研发版)

当你使用图形用户界面类时通常会遇到一个问题。比如,你创建了自定义按钮类并允许客户端在按钮中注入自定义代码,这样当用户按下按钮时就会触发这些代码。观察者模式允许任何实现了订阅者接口的对象订阅发布者对象的事件通知。你可在按钮中添加订阅机制,允许客户端通过自定义订阅类注入自定义代码。在Unity中,这就像UnityEvent在Inspector中绑定多个回调。

m0_63330263的博客 105

Claude Fable 5.2 登顶:65 分、单发做游戏,和一份 $26.54 一单的账单

Anthropic 发布 Claude Fable 5.2:AA 智能指数 65 分登顶历史第一,但性能 #71、成本 #73、冗余度 #72——最强能力、最贵成本、最慢速度的矛盾体。同底层 Mythos 5.2 无护栏反而更强。文章拆解:65 分构成、官方实战验收、基准提升真伪、一条提示词一晚做出街机游戏的完整流水线(自写机器人跑完 12 关自检)、$26.54 账单与 98% 缓存折扣下的真实成本重估。

johnsong2009的博客 259

10分钟完成第一个Python小游戏

第一个项目不用找复杂的,‌直接选「猜数字小游戏」对应的教程‌就好——几乎所有入门教程都会讲这个项目,资料最多、遇到问题随便搜就能找到解决方法,不会卡壳,30分钟肯定能做完,非常容易建立信心。‌教程链接‌:直接搜标题👉 ‌《Python零基础入门项目:30分钟写完猜数字游戏》‌(优先选黑马程序员、鱼C-小甲鱼这两个UP主的版本,播放量都是百万级,口碑稳定)‌教程地址‌:打开菜鸟教程官网→找到「Python 实例」板块,直接在线写代码运行。全程不跳步,30分钟就能做完,做完能直接运行玩,成就感拉满。

mF44Job8l的博客 65

Unity 数据存储指南:本地存储、个性化设置、缓存与 Resources/StreamingAssets 的区别

在 Unity 开发中,“数据存到哪里”、“缓存能不能清”、“打包后资源有什么区别” 是新手最容易混淆、老手也经常踩坑的问题。Unity 本地存储机制(包括 Unity 放在 C 盘的内容);Unity 个性化设置(编辑器首选项 Editor Preferences);Unity 缓存的打开、关闭与清理;打包后 Resources 与 StreamingAssets 的区别;其他可自定义存储的内容汇总。为方便理解,本文配有一个可直接运行的演示工程,所有代码见文末"配套工程说明"。

zhchyun 225
上一篇: 2004黑客推荐工具
下一篇: 基于IMD的包过滤防火墙原理与实现 by PiggyXP【小猪】
XmagicX
博客等级 码龄24年 13粉丝 78原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值