scapy库

一.概述

Scapy是一个功能强大且灵活的Python库,用于操作和探索计算机网络中的数据包。它允许用户构建各种类型的网络数据包,并支持多种网络协议,如TCP、UDP、ICMP、ARP等。Scapy不仅可以发送和接收数据包,还可以捕获、修改和解析网络流量,使用户能够深入研究网络通信并进行网络安全测试。

二.scapy的基本使用

依赖npcap,最好是最新版本

安装:pip install scapy

有两种使用方式:1.交互式使用 2.python中使用

image-20240426141745205

  • 查看当前设备所有网卡信息
  • >>> show_interfaces()
    Source   Index  Name                                    MAC                IPv4            IPv6
    libpcap  1      Software Loopback Interface 1           00:00:00:00:00:00  127.0.0.1       ::1
    libpcap  10     Realtek PCIe GbE Family Controller      80:fa:5b:11:9b:9e  169.254.136.18  fe80::14b7:abf9:a634:1813
    libpcap  14     Intel(R) Dual Band Wireless-AC 7265     60:57:18:26:1f:29  192.168.2.8     fe80::12a1:306f:c371:b4fe
    libpcap  17     Microsoft Wi-Fi Direct Virtual Adapter  60:57:18:26:1f:2a  169.254.106.74  fe80::6b57:f4f4:f5cf:5cb2
    libpcap  18     WAN Miniport (IP)
    libpcap  21     WAN Miniport (IPv6)
    libpcap  9      WAN Miniport (Network Monitor)
    
  • 捕获数据包
  • >>> pkg=sniff(count=4,iface='Intel(R) Dual Band Wireless-AC 7265',filter='icmp')
    如果卡住,说明还未抓到包,当抓到4个包,就会恢复>>>状态
    
  • 查看数据包
  • >>> pkg
    <Sniffed: TCP:0 UDP:0 ICMP:4 Other:0>
    
    >>> pkg.show()
    0000 Ether / IP / ICMP 192.168.2.8 > 192.168.2.1 echo-request 0 / Raw
    0001 Ether / IP / ICMP 192.168.2.1 > 192.168.2.8 echo-reply 0 / Raw
    0002 Ether / IP / ICMP 192.168.2.8 > 192.168.2.1 echo-request 0 / Raw
    0003 Ether / IP / ICMP 192.168.2.1 > 192.168.2.8 echo-reply 0 / Raw
    
    >>> pkg[0]
    <Ether  dst=80:05:88:e9:45:11 src=60:57:18:26:1f:29 type=IPv4 |<IP  version=4 ihl=5 tos=0x0 len=31 id=32438 flags= frag=0 ttl=128 proto=icmp chksum=0x36ce src=192.168.2.8 dst=192.168.2.1 |<ICMP  type=echo-request code=0 chksum=0x5941 id=0x64e1 seq=0x78 unused='' |<Raw  load='\\xe1dX' |>>>>
    
    >>> pkg[0].show()
    ###[ Ethernet ]###
      dst       = 80:05:88:e9:45:11
      src       = 60:57:18:26:1f:29
      type      = IPv4
    ###[ IP ]###
         version   = 4
         ihl       = 5
         tos       = 0x0
         len       = 31
         id        = 32438
         flags     =
         frag      = 0
         ttl       = 128
         proto     = icmp
         chksum    = 0x36ce
         src       = 192.168.2.8
         dst       = 192.168.2.1
         \options   \
    ###[ ICMP ]###
            type      = echo-request
            code      = 0
            chksum    = 0x5941
            id        = 0x64e1
            seq       = 0x78
            unused    = ''
    ###[ Raw ]###
               load      = '\\xe1dX'
               
    >>> pkg[0][IP].ttl
    128
    
  • 保存离线文件
  • wrpcap('H:\\demo.pcap',pkg)
    第一个参数是路径,第二个参数是包名
    
  • 读离线文件
  • >>> pkg1=rdpcap('H:\\demo.pcap')
    括号跟文件路径
    
  • 编辑数据包
  • pkg2=IP(src='192.168.2.8',dst='192.168.2.1')/ICMP(type=8,code=0)/'abcdefg'
    
  • 发送数据包
  •     send(pkt):发送三层数据包,但不会受到返回的结果
        sr(pkt):发送三层数据包,返回两个结果,分别是接收到响应的数据包和未收到响应的数据包
        sr1(pkt):发送三层数据包,仅仅返回接收到响应的数据包
        sendp(pkt):发送二层数据包
        srp(pkt):发送二层数据包,并等待响应
        srp1(pkt):发送第二层数据包,并返回响应的数据包
    
    有数字1,就是发送1个数据包,有r就是有返回数据包,有p从二层协议发送数据包
    >>> pkg3=sr1(pkg2)
    Begin emission:
    Finished sending 1 packets.
    ...*
    Received 4 packets, got 1 answers, remaining 0 packets
    
    发送完后返回的响应就存储在pkg3变量里
    
    三.python使用scapy库
    # 使用pycharm发送icmp报文
    from scapy.all import *
    from scapy.layers.inet import *
    
    # 编写一个icmp包
    pkg = IP(src='192.168.2.8', dst='www.woniuxy.com') / ICMP() / 'abcdefg'
    # 发送数据包
    pkg1 = sr1(pkg, verbose=0)
    print(pkg1[IP].ttl)
    
    四.基于arp扫描

    arp作用:通过IP地址查找mac地址

    pkg = ARP(pdst='192.168.2.33', psrc='192.168.2.8', op=1)
    pkg2 = sr1(pkg, verbose=0)
    print(pkg2[ARP].hwsrc)
    
    
    优化
    try:
        pkg = ARP(pdst='192.168.2.100', psrc='192.168.2.8', op=1)
        pkg2 = sr1(pkg, timeout=1)
        print(pkg2[ARP].hwsrc)
    except Exception:
        print('该IP的主机不存在')
        
    优化:引入循环
    for i in range(1, 255):
        try:
            pkg = ARP(pdst=f'192.168.2.{i}', op=1)
            pkg2 = sr1(pkg, verbose=0, timeout=1)
            print(f'192.168.2.{i}的MAC是:{pkg2[ARP].hwsrc}')
        except Exception:
            print(f'192.168.2.{i}的MAC不存在')
            
    优化:引入多线程(作业)
    
    五.TCP三次握手
        F:FIN 结束,结束会话
        S:SYN 同步,表示开始会话请求
        R:RST 复位,中断一个连接
        P:PUSH 推送,数据包立即发送
        A:ACK 应答
        U:URG 紧急
        E:ECE 显式拥塞提醒回应
        W:CWR 拥塞窗口减少
    
    
    # 第一次握手包
    pkg = IP(dst='192.172.0.100') / TCP(dport=3306, flags='S')
    pkg2 = sr1(pkg, verbose=0, timeout=1)
    # 第二次握手包(pkg2)
    
    # 第三次握手包
    ack = pkg2[TCP].seq + 1
    seq = pkg2[TCP].ack
    pkg3 = IP(dst='192.172.0.100') / TCP(dport=3306, flags='A', seq=seq, ack=ack)
    # 发送第三个握手包
    pkg4 = sr1(pkg3, verbose=0, timeout=1)
    # 返回了第四个包,整个三次握手就成功了
    
    六.基于TCP的端口扫描
    for i in range(1, 65536):
        random_port = random.randint(10000, 20000)
        pkg = IP(dst='192.172.0.100') / TCP(dport=i, sport=random_port, flags='S')
        pkg2 = sr1(pkg, verbose=0, timeout=1)
        if pkg2[TCP].flags == 'SA':
            print(f'端口:{i}已开放')
        elif pkg2[TCP].flags == 'RA':
            # print(f'----端口:{i}未开放----')
            pass
    
    七.基于scapy的三次握手四次挥手
    from scapy.all import *
    from scapy.layers.inet import *
    import random
    
    random_port = random.randint(10000, 65535)
    pkg1 = IP(src="192.168.7.25", dst="192.172.0.100") / TCP(sport=random_port, dport=8080, seq=3472901066, ack=0,
                                                             flags="S")
    pkg2 = sr1(pkg1, iface="Intel(R) Dual Band Wireless-AC 7265")
    seq = pkg2[TCP].ack
    ack = pkg2[TCP].seq + 1
    pkg3 = IP(src="192.168.7.25", dst="192.172.0.100") / TCP(sport=random_port, dport=8080, seq=seq, ack=ack, flags="A")
    send(pkg3, verbose=0, iface="Intel(R) Dual Band Wireless-AC 7265")
    
    pkg4 = IP(src="192.168.7.25", dst="192.172.0.100") / TCP(sport=random_port, dport=8080, seq=seq, ack=ack, flags="FA")
    pkg5 = sr1(pkg4, iface="Intel(R) Dual Band Wireless-AC 7265")
    pkg6 = IP(src="192.168.7.25", dst="192.172.0.100") / TCP(sport=random_port, dport=8080, seq=seq + 1, ack=ack + 1,
                                                             flags="A")
    send(pkg6, verbose=0, iface="Intel(R) Dual Band Wireless-AC 7265")
    

    作者:蜗牛学苑_武汉

    物联沃分享整理
    物联沃-IOTWORD物联网 » python的scapy库基础使用

    发表回复