Cover Image

Scapy

建议在PC端阅读。

Scapy是一个基于Python的强大的、可交互的数据包操作(编辑)库。Scapy能够伪造或者解码多种协议的数据包,并通过网络发送、捕获数据包,重新组合请求和回复等等。

Scapy is a powerful interactive packet manipulation library written in Python. Scapy is able to forge or decode packets of a wide number of protocols, send them on the wire, capture them, match requests and replies, and much more.[1]

Scapy的在线官方文档在readthedocs

中文版可参考Osgeo技术栈

简单上手

1. 构造IP/TCP/UDP/HTTP数据包

>>> IP()
<IP  |>
>>> IP() / TCP()
<IP  frag=0 proto=tcp |<TCP  |>>
>>> IP() / UDP()
<IP  frag=0 proto=udp |<UDP  |>>
>>> IP() / TCP() / "GET / HTTP/1.0\r\n\r\n"
<IP  frag=0 proto=tcp |<TCP  |<Raw  load=b'GET / HTTP/1.0\r\n\r\n' |>>>

2. ping测一下

ping测试使用ICMP数据包进行网络探测,根据Echo回复,检查网络连通性与网络质量。

>>> IP() / ICMP()
<IP  frag=0 proto=icmp |<ICMP  |>>
>>> p = sr1(IP(dst="www.baidu.com") / ICMP() / "Hello!")
Begin emission
..
Finished sending 1 packets
.*
Received 4 packets, got 1 answers, remaining 0 packets
>>> # 测试时www.baidu.com的IP地址为183.240.99.169,开始ping测。
>>> p
<IP  version=4 ihl=5 tos=0x0 len=34 id=1 flags= frag=0 ttl=49 proto=icmp chksum=0x3eb2 src=183.240.99.169 dst=192.168.110.230 |<ICMP  type=echo-reply code=0 chksum=0xdc0c id=0x0 seq=0x0 unused=b'' |<Raw  load=b'Hello!' |>>>

3. 实现一个traceroute

  1. 使用Scapy测试
>>> ans, uans = sr(IP(dst="8.8.8.8", ttl=(1, 17)) / ICMP())
>>> for snd, rcv in ans:
...     print(f"TTL {snd.ttl} | {rcv.src} | {rcv.time - snd.sent_time:.3f}ms")
...
TTL 1 | 192.168.1.1 | 0.006ms
TTL 2 | 100.64.40.1 | 0.013ms
TTL 3 | 220.165.16.157 | 0.023ms
TTL 4 | 222.221.28.193 | 0.037ms
TTL 5 | 202.97.95.170 | 0.070ms
TTL 6 | 8.8.8.8 | 0.081ms
TTL 7 | 203.22.178.197 | 0.081ms
TTL 8 | 62.115.174.47 | 0.070ms
TTL 9 | 142.251.67.15 | 0.070ms
TTL 10 | 8.8.8.8 | 0.079ms
TTL 11 | 8.8.8.8 | 0.079ms
TTL 12 | 8.8.8.8 | 0.079ms
TTL 13 | 8.8.8.8 | 0.069ms
TTL 14 | 8.8.8.8 | 0.069ms
TTL 15 | 8.8.8.8 | 0.069ms
TTL 16 | 62.115.176.166 | 0.203ms
  1. PC端测试
C:\Users\MSI-PC>tracert 8.8.8.8

通过最多 30 个跃点跟踪
到 dns.google [8.8.8.8] 的路由:

  1    12 ms    13 ms     4 ms  SMBSHARE [192.168.1.1]
  2    12 ms    15 ms    17 ms  100.64.40.1
  3    11 ms     9 ms     9 ms  220.165.16.157
  4    25 ms    23 ms    22 ms  222.221.28.193
  5     *        *       45 ms  202.97.14.25
  6     *        *        *     请求超时。
  7     *        *        *     请求超时。
  8    50 ms    59 ms    51 ms  202.97.95.170
  9    59 ms    58 ms     *     CTCN2.DE.FRK.CTGNet [203.22.178.197]
 10     *      215 ms     *     hnk-b4-link.ip.twelve99.net [62.115.176.166]
 11     *       68 ms    53 ms  google-ic-344101.ip.twelve99-cust.net [62.115.174.47]
 12    53 ms    50 ms    51 ms  142.251.67.15
 13    61 ms    60 ms    60 ms  216.239.43.61
 14    57 ms    82 ms    68 ms  dns.google [8.8.8.8] 

跟踪完成。

PC端与Scapy测试中间路由顺序不一致,与实现逻辑不同有关。

PC端测试,会在上一个ttl值测试结束后才会发起新的ttl值测试。每个ttl测试都会发送三个测试包,取出现次数最多的IP地址。

而测试使用的Scapy程序,一次性将20个不同ttl数据包全部发送出去,根据响应顺序排序。

从准确性上来说,PC端更准确。

4. 构造HTTP数据包

模拟百度搜索Scapy,百度搜索的接口是http://www.baidu.com/s?wd=%q

>>> req_text = u"GET /s?wd=Scapy HTTP/1.1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\n\r\n"
>>>
>>> pkt = IP(dst="www.baidu.com", ttl=32) / TCP(dport=80, flags='S') / req_text
>>>
>>> pkt
<IP  frag=0 ttl=32 proto=tcp dst=Net('www.baidu.com') |<TCP  dport=http flags=S |<Raw  load='GET /s?wd=Scapy HTTP/1.1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\n\r\n' |>>>
>>>
>>> ans, unans = sr(pkt, timeout=6)
Begin emission:
Finished sending 1 packets.
.*
Received 2 packets, got 1 answers, remaining 0 packets

Scapy HTTP GET request

这里已经捕获到了HTTP的请求,这里没有对返回的TCPSYN+ACK数据包回应,TCP连接未建立,所以没有期望的搜索结果。完整HTTP测试,可使用爬虫完成。

5. 快速生成测试流量[1]

>>> send(IP(dst="192.168.1.1") / ICMP(), loop=1, inter=0.01)

6. 端口扫描[1]

>>> res = sr1(IP(dst="192.168.1.1") / TCP(dport=80, flags="S"), timeout=4)
>>> if res and res[TCP].flags == 0x12:
        send(IP(dst="192.168.1.1") / TCP(dport=80, flags="R"))
        print("端口开放")

一、Scapy入门

入门

1. 功能提升

通过安装其他依赖库或软件,可以增强Scapy的功能。

matplotlib | PyX | graphviz | ImageMagick  | vpython | cryptography | Nmap

标红为Python库,可通过pip安装,标黑为独立软件,须在对应网站下载安装。

详情见Scapy可选依赖

2. 环境变量Environment Variable与Scapy全局变量配置conf

  1. conf.iface,主网卡(默认网卡)
  2. conf.ifaces,所有网卡。包含蓝牙、WiFi等连接,主要为当前已启用网络接口。
  3. conf.route,所有路由
  4. conf.commands,当前支持的命令
  5. get_windows_if_list(),查看网络适配器(网卡)列表。相比conf.ifaces,包含全部接口,内容也更加详细。
  6. get_working_if(),返回一个当前可用的网卡
>>> from scapy.arch import get_windows_if_list
>>> print(conf.iface)
\Device\NPF_{EAED598E-5F7F-4E58-B4EE-5353DD60ECA1}
>>>
>>> print(conf.ifaces)
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     WAN Miniport (Network Monitor)
libpcap  11     WAN Miniport (IPv6)
libpcap  15     Bluetooth Device (Personal Area Network) #3                                    Intel:3b:f7:62         169.254.230.20  fe80::xxx:xxxx:5xxx:xxxx
libpcap  20     Qualcomm Atheros AR8171/8175 PCI-E Gigabit Ethernet Controller (NDIS 6.30) #2  MicroStarINT:03:65:76  169.254.204.15  fe80::exxx:axxx:dxxx:8b0
>>> 
>>> print(conf.route)
Network          Netmask          Gateway      Iface                                                                          Output IP       Metric
0.0.0.0          0.0.0.0          192.168.1.1  Intel(R) Wireless-AC 9462                                                      192.168.1.5     301
127.0.0.0        255.0.0.0        0.0.0.0      Software Loopback Interface 1                                                  127.0.0.1       331
127.0.0.1        255.255.255.255  0.0.0.0      Software Loopback Interface 1                                                  127.0.0.1       331
127.255.255.255  255.255.255.255  0.0.0.0      Software Loopback Interface 1                                                  127.0.0.1       331   
>>>
>>> print(conf.commands)
IPID_count            : Identify IP id values classes in a list of packets
arp_mitm              : ARP MitM: poison 2 target's ARP cache
arpcachepoison        : Poison targets' ARP cache
arping                : Send ARP who-has requests to determine which hosts are up::
>>>
>>> if_list = get_windows_if_list()
>>> if_list[0]
{'name': '以太网 2', 'index': 20, 'description': 'Qualcomm Atheros AR8171/8175 PCI-E Gigabit Ethernet Controller (NDIS 6.30) #2', 'guid': '{936BB600-8136-4ECF-8717-EB81EC064A55}', 'mac': '00:d8:61:03:65:76', 'type': 6, 'ipv4_metric': 5, 'ipv6_metric': 5, 'ips': ['fe80::e2a7:a2ed:d647:8b0', '169.254.204.15'], 'nameservers': ['2001:da8::666', '2400:da00::6666', '192.168.1.1']}
>>> 
>>> for i in if_list[70:74]:
...     print(i['description'] + "\t" + i['name'])
...
Microsoft Wi-Fi Direct Virtual Adapter-Native WiFi Filter Driver-0000   本地连接* 2-Native WiFi Filter Driver-0000
Intel(R) Wireless-AC 9462-VirtualBox NDIS Light-Weight Filter-0000      WLAN 2-VirtualBox NDIS Light-Weight Filter-0000
Intel(R) Wireless-AC 9462-WFP 802.3 MAC Layer LightWeight Filter-0000   WLAN 2-WFP 802.3 MAC Layer LightWeight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-Huorong NDIS Filter Driver-0000  本地连接* 2-Huorong NDIS Filter Driver-0000

3.

二、Scapy抓包与查看


参考资料:

[1]. Scapy.net. Scapy.net
[2]. CSDN. austin1000. scapy学习笔记(1)——win10下安装scapy、查看网卡、查看路由
[3]. 技术栈. Linux上Scapy完全指南:从入门到实战攻防
[4]. CSDN. austin1000. win10下scapy get_working_if()不能获得正确的网卡原因分析

This article is licensed under CC BY-NC-SA 4.0.
Back To Top