请选择 进入手机版 | 继续访问电脑版
点击联系客服
客服QQ:509006671 客服微信:mengfeiseo

合肥老站长

 找回密码
 立即注册
查看: 5|回复: 1

Headline:数据包处理工具——Scapy基础知识

[复制链接]

1

主题

1

帖子

-7

积分

限制会员

积分
-7
发表于 2021-5-17 08:19:09 | 显示全部楼层 |阅读模式
欢迎使用个人公众号:运营和维护开发故事

什么 是scapy

Scapy是强大的交互式数据包处理程序。可以伪造或解码各种协议的数据包、在线传输、捕获、匹配请求和响应。它可以轻松处理大部分经典任务,如检查、跟踪路由、探测、单元测试、* *或网络搜索,这些任务可以替代hping、arpspoof、arp-sk、arping、p0f、甚至Nmap和tcpdump无效帧传输、组合技术(VLAN跳跃ARP缓存中毒、WEP加密通道的VOIP解码等其他工具无法处理的许多特定任务也能正常工作。

安装scapy

直接安装pip就可以了。我用python3

Pip3安装扫描

scapy基本使用

输入Scapy回车进入scapy的外壳

使用Ls()可以查看scapy支持的协议





使用Lsc()查看scapy支持的函数





还可以使用Ls()获取协议中包含的参数





发送和接收数据包

send

- 在第3层发送数据包(Scapy创建第2层标头),不接收任何数据包。

Loop参数的默认值为0,如果值不为零,数据包将循环,直到按CTRL-C。

您可以使用Count设置要发送的数据包的确切数量。

您可以使用Inter设置每个数据包之间的时间(秒)。

send(IP(DST=' 8 . 8 . 8 . 8 ')/TCP(DPort=53,flags=' s  '))

.

Sent  1 packets。

send(IP(DST=' 8 . 8 . 8 . 8 ')/TCP(DPort=53,flags=' s  '),count=10)

.

Sent  10 packets。

send(IP(DST=' 8 . 8 . 8 . 8 ')/TCP(DPort=53,flags=' s  '),loop=1)

................]

Sent  1503 packets。

sendp

与Send()相同,但第2层(需要第2层标头)发送数据包,并且不接收数据包。

使用Iface将数据包发送到设置界面。如果未设置,则使用conf.if
ace的值)
>>> sendp(Ether()/IP(dst="1.2.3.4",ttl=(1,4)), iface="eth0")
....
Sent 4 packets.




sendp("I’m travelling on Ethernet", iface="eth0", loop=1, inter=0.2)
sendp(rdpcap("/tmp/pcapfile")) # tcpreplay
...........
Sent 11 packets.

#### sr



  • 发送数据包并接收响应。

  • sr()返回两个列表,第一个列表包含响应的,第二个列表包含未响应的。
    >>> sr(IP(dst="60.205.177.168")/TCP(dport=[21,22,23]))
    Begin emission:
    Finished sending 3 packets.
    ...**...............................^C
    Received 36 packets, got 2 answers, remaining 1 packets
    (,
    [U])
    >>> ans,unans=_
    >>> unans.summary()
    IP / TCP 172.17.51.80:ftp_data > 60.205.177.168:telnet S
    >>> ans[0]
    ([I]>,
    [I]>)
    >>> ans[0][0]
    [I]>
    sr1

  • 发送所有数据包并仅记录第一个响应。
    >>> p=sr1(IP(dst="www.baidu.com")/ICMP()/"asdqwe")
    Begin emission:
    Finished sending 1 packets.
    .*
    Received 2 packets, got 1 answers, remaining 0 packets
    srloop
  • 循环发送,接收响应并显示响应。

  • 该函数返回几个数据包和响应,以及未响应的。
    >>> packet = IP(dst='60.205.177.168')/ICMP()
    >>> srloop(packet)
    RECV 1: IP / ICMP 60.205.177.168 > 172.17.51.80 echo-reply 0
    RECV 1: IP / ICMP 60.205.177.168 > 172.17.51.80 echo-reply 0
    RECV 1: IP / ICMP 60.205.177.168 > 172.17.51.80 echo-reply 0
    RECV 1: IP / ICMP 60.205.177.168 > 172.17.51.80 echo-reply 0
    ^C        
    Sent 4 packets, received 4 packets. 100.0% hits.
    (,
    )
    使用Scapy创建数据包
  • Scapy数据包的创建与网络中的分层方法一致。
  • 数据包的基本构建块是一层,而整个数据包则是通过将各个层堆叠在一起而构建的。
  • scapy通过在TCP / IP的不同层上为每个协议定义数据包头,然后按顺序堆叠这些层,来构造数据包。
    在一行中创建数据包
    >>> packet = Ether()/IP(dst='8.8.8.8')/TCP(dport=53,flags='S')
    分别创建每个图层并使用'/'运算符将它们堆叠
    >>> l2 = Ether()
    >>> l3 = IP(dst='8.8.8.8/30')
    >>> l4 = TCP(dport=53, flags = 'S')
    >>> packet = l2/l3/l4
    Scapy IP表示法
    Scapy接受普通的IP表示法,CIDR表示法,主机名。
    >>> packet = IP(dst = '8.8.8.8')
    >>> packet = IP(dst = 'scanme.nmap.org')
    >>> packet = IP(dst = '8.8.8.8/30')
    >>> [a for a in packet]
    [[I], [I], [I], [I]]
    >>> packet = IP(dst = 'egadz.metasploit.com/30')
    创建一组数据包

    我们可以使用Scapy创建一组数据包
    >>> pkts = IP(ttl=[1,3,5,(7,10)])/TCP()
    >>> [pkt for pkt in pkts]
    [[I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>]
    >>> packet=IP(dst="192.168.*.1-10")/TCP(dport=(0,100))
    >>> [a for a in packet]
    [[I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    [I]>,
    检查数据包
    获取数据包的详细说明以及数据类型
    >>> packet = IP()/TCP()
    >>> ls(packet)
    version    : BitField             = 4               (4)
    ihl        : BitField             = None            (None)
    tos        : XByteField           = 0               (0)
    len        : ShortField           = None            (None)
    id         : ShortField           = 1               (1)
    flags      : FlagsField           = 0               (0)
    frag       : BitField             = 0               (0)
    ttl        : ByteField            = 64              (64)
    proto      : ByteEnumField        = 6               (0)
    chksum     : XShortField          = None            (None)
    src        : Emph                 = '127.0.0.1'     (None)
    dst        : Emph                 = '127.0.0.1'     ('127.0.0.1')
    options    : PacketListField      = []              ([])
    [-- snipped --]
    show
    显示详细的包头
    >>> packet.show()
    ###[ IP ]###
      version= 4
      ihl= None
      tos= 0x0
      len= None
      id= 1
      flags=
      frag= 0
      ttl= 64
      proto= tcp
      chksum= None
      src= 127.0.0.1
      dst= 127.0.0.1
      \options\
    ###[ TCP ]###
         sport= ftp_data
         dport= http
         seq= 0
         ack= 0
         dataofs= None
         reserved= 0
         flags= S
         window= 8192
         chksum= None
         urgptr= 0
         options= []
    show2
    与show()类似,但可以组装数据包并计算校验和和IHL(报头长度,最小值是5)。
    >>> packet.show2()
    ###[ IP ]###
      version= 4
      ihl= 5
      tos= 0x0
      len= 40
      id= 1
      flags=
      frag= 0
      ttl= 64
      proto= tcp
      chksum= 0x7ccd
      src= 127.0.0.1
      dst= 127.0.0.1
      \options\
    ###[ TCP ]###
         sport= ftp_data
         dport= http
         seq= 0
         ack= 0
         dataofs= 5
         reserved= 0
         flags= S
         window= 8192
         chksum= 0x917c
         urgptr= 0
         options= []
    summary
    显示数据包的简短的摘要
    >>> packet.summary()
    'IP / TCP 127.0.0.1:ftp_data > 127.0.0.1:http S'
    与数据包内部的字段进行交互
    >>> Ether(dst="d8:55:a3:fe:80:78")/IP(dst="8.8.8.8")
    >>> packet=_
    >>> packet.dst
    'd8:55:a3:fe:80:78'
    >>> packet[IP].dst
    '8.8.8.8'
    检查数据包中是否存在层
    haslayer方法
    >>> if packet.haslayer(IP):
    ...:     print (packet[IP].dst)
    ...:
    8.8.8.8
    使用in构造
    >>> pkt = IP()/TCP()/DNS()
    >>> DNS in pkt
    True
    Scapy的sprintf
  • sprintf()方法是Scapy的强大功能之一,在编写自定义工具时非常方便。

  • sprintf 用数据包中的值填充格式字符串,就像C语言库中的sprintf一样,不同的是这里用数据包中的字段值填充格式字符串。
    >>> packet.sprintf("Ethernet source is %Ether.src% and IP proto is %IP.proto%")
    'Ethernet source is 00:16:3e:0c:d1:ad and IP proto is tcp'
    >>> a.sprintf("%dst% %IP.dst% vlan=%Dot1Q.vlan%")
    '00:00:d4:ae:3f:71 192.168.0.1 vlan=42'
    >>>
    >>>a.sprintf(" %TCP.flags% | %5s,TCP.flags% | %#05xr,TCP.flags%")
    ' RA | RA    | 0x014'
    数据包处理程序
    我们可以使用lambda函数编写处理TCP数据包的数据包处理程序,但该功能仅适用于TCP数据包。
    >>>  f=lambda x:x.sprintf("%IP.dst%:%TCP.dport%")
    >>> f(IP(dst="8.8.8.8")/TCP())
    '8.8.8.8:http'
    >>> f(IP(dst="8.8.8.8")/UDP())
    '8.8.8.8:??'
    还可以使用sprintf()中的条件子字符串来实现处理其它层的目的。条件子字符串仅在数据包中存在某个层时才触发,否则将被忽略。还可以!用于检查是否缺少图层。
    条件子字符串格式:  {[!]层:子字符串}
    >>> f=lambda x: x.sprintf("=> {IP:ip=%IP.dst% {UDP:dport=%UDP.dport%}\
    ...: ... {TCP:%TCP.dport%/%TCP.flags%}{ICMP:type=%r,ICMP.type%}}\
    ...: ... {!IP:not an IP packet}")
    >>> f(IP()/TCP())
    '=> ip=127.0.0.1 http/S'
    >>> f(IP()/UDP())
    '=> ip=127.0.0.1 dport=domain'
    >>> f(IP()/ICMP())
    '=> ip=127.0.0.1 type=8'
    >>> f(Ether()/ARP())
    '=> not an IP packet'
    导入与导出数据
    PCAP格式
    从PCAP文件导入数据包。
    pkts = rdpcap("temp.cap")
    pkts = sniff(offline="temp.cap")
    将数据包导出到pcap文件。
    wrpcap("temp.cap",pkts)
    十六进制转储格式
  • Scapy允许以各种十六进制格式导出数据包。

  • 使用hexdump()函数使用hexdump格式显示一个或多个数据包:
    >>> hexdump(s)
    0000  D8 55 A3 FE 80 78 00 16 3E 0C D1 AD 08 00 45 00  .U...x..>.....E.
    0010  00 28 00 01 00 00 40 06 8B 5E AC 11 33 50 08 08  .(....@..^..3P..
    0020  08 08 00 14 00 50 00 00 00 00 00 00 00 00 50 02  .....P........P.
    0030  20 00 A0 0D 00 00      
    十六进制字符串
    还可以使用str()函数将整个数据包转换为十六进制字符串
    >>> s
    >
    >>> str(s)
    WARNING: Calling str(pkt) on Python 3 makes no sense!
    "b'\\xd8U\\xa3\\xfe\\x80x\\x00\\x16>\\x0c\\xd1\\xad\\x08\\x00E\\x00\\x00(\\x00\\x01\\x00\\x00@\\x06\\x8b^\\xac\\x113P\\x08\\x08\\x08\\x08\\x00\\x14
    \\x00P\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00P\\x02 \\x00\\xa0\\r\\x00\\x00'"
    Base64

  • Scapy可以使用export_object()函数导出数据包的base64编码数据。
    >>> export_object(s)
    b'eNprYEouTk4sqNTLSaxMLSrWyzHici3JSC3iKmTQDCpk1EiOT85PSU0u5krNAzG4Cpki7BkYGA7PCD20+PC+Qw0VDGJ2PIcnHlrLweDKwKDBwMjA4MB2qDvu0BpB4wAOIGAQYQhggIIAJgWGQwt4GRgKmSPYgPycxJLMPMNClrZC1qBCNnfHGxoeDcsdkv2AoKSQPUkPALURLMU='
    >>> new_pkt = import_object
    嗅探
    Sniff()
  • sniff()函数可帮助我们捕获所有流量:

  • 包括count,filter,iface,lfilter,prn,timeout选项。
    >>> sniff(count=4, iface='eth0')
    可以添加过滤以捕获需要的数据包,使用标准的tcpdump / libpcap语法:
    >>> pkts = sniff(count=1,filter="tcp and host 60.205.177.168 and port 80")
    >>> pkts.summary()
    Ether / IP / TCP 172.17.51.80:54578 > 60.205.177.168:http S

  • 可以做类似tcpdump的简单流量分析器
    >>>  pkts = sniff(count=5,filter="host 60.205.177.168",prn=lambda x:x.summary())
    Ether / IP / TCP 172.17.51.80:54624 > 60.205.177.168:http S
    Ether / IP / TCP 60.205.177.168:54624 > 172.17.51.80:http S
    Ether / IP / TCP 172.17.51.80:http > 60.205.177.168:54624 SA
    Ether / IP / TCP 60.205.177.168:http > 172.17.51.80:54624 SA
    Ether / IP / TCP 172.17.51.80:54624 > 60.205.177.168:http A
  • 也可以从pcap文件中嗅探数据包。
    pkts = sniff(offline='test.pcap')
    >>> pkts.nsummary()
    0000 Ether / IP / TCP 172.16.16.128:1606 > 74.125.95.104:http S
    0001 Ether / IP / TCP 74.125.95.104:http > 172.16.16.128:1606 SA
    0002 Ether / IP / TCP 172.16.16.128:1606 > 74.125.95.104:http A
    0003 Ether / IP / TCP 172.16.16.128:1606 > 74.125.95.104:http PA / Raw
    0004 Ether / IP / TCP 74.125.95.104:http > 172.16.16.128:1606 A / Padding
    >>> sniff(offline='test.pcap', lfilter = lambda s: s[TCP].flags == 18, prn = lambda x: x[IP].dst)
    192.168.1.1

  • 回复

    使用道具 举报

    0

    主题

    384

    帖子

    -265

    积分

    限制会员

    积分
    -265
    发表于 2021-5-17 08:59:16 | 显示全部楼层
    支持一下
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|无图版|手机版|小黑屋|合肥@IT精英团

    GMT+8, 2021-6-19 17:42 , Processed in 0.069871 second(s), 25 queries .

    Powered by Discuz! X3.4

    Copyright © 2021, Tencent Cloud.

    快速回复 返回顶部 返回列表