SCAPY官方教程十
摘要
此文档涵盖了 Scapy 的常见问题及解决方案:
连接配置:无法在监控模式下嗅探数据包(scapy.ml(at)secdev.org)、TCP 连接配置错误(nfcap-0.9983)、以及无法处理环回接口上的 127.0.0.1(AI助手)。
获取帮助:可通过 Scapy 官方文档或 Gitter 社区寻求支持(例如 Traceroute() 不起作用时的解决方法)。
自动化测试:使用 UTScapy 执行测试活动并生成报告(例如 Traceroute() 不起作用时的修复方法)。
发布与签名:通过 Git 创建版本签名并发布至 PyPI(例如 v2.4.3 标签)。
此摘要简明扼要地涵盖了 Scopy 的核心功能与常见问题及其解决方案。
一、故障排除
常见问题
1. 无法在监控模式下嗅探/注入数据包。
使用监控模式因平台而异。
为了使用 Libpcap 应将 libpcap指定为 Scapy 的不同调用方式,并以便于在监控模式下建立套接字。您应将参数 monitor=True指定给所有与套接字相关联的操作(如 send, sniff, 或者自定义的 Scapy 套接字创建)。特别地,请注意区分并正确处理以下几种情况:1. 使用默认配置下的 Scapy 调用;2. 针对特定协议栈定制的 L2 或 L3 套接字;3. 根据需求自行设计的独特套接体构造方法等详细情况。
Native Linux(禁用 libpcap): 在禁用 libpcap 的情况下:建议您手动将网络接口配置为监控模式。通常我会通过 iwconfig 来实现这一功能,并推荐将命令 sudo iwconfig monitor | replace monitor with managed 以实现类似效果。
1. $ sudo ifconfig IFACE down
2. $ sudo iwconfig IFACE mode monitor
3. $ sudo ifconfig IFACE up
AI助手
您若使用 Npcap:
许多适配器无法支持监视模式,在Windows系统中尤其如此;也可能导致标题报告出现问题。请参考关于该功能的Wireshark文档
如果您拥有的适应器能够与Wireshark协同工作而不能与Scapy配合使用,请告知以便我们尽快解决该问题。
2. TCP 连接由 Scapy 或我的内核重置。
内核对 Scapy 的功能不太清楚。
当 Scapy 发起一个 SYN 时,在线目标会响应SYN-ACK报文,并且若内核接收到此报文,则会回应RST报文。
为了避免这种情况发生,请依据具体情况配置本地防火墙规则(如 Linux 中的NetFilter配置)。
对于本地防火墙的设置来说,Scrapy 对其反应相对不敏感。
3. 无法 ping 127.0.0.1(或 ::1)。Scapy 不适用于环回接口上的 127.0.0.1(或 ::1)。
loopback接口是一个独特的接口。通过它的数据包并未进行实际的组装或解 assembling. 内核负责将数据包路由至其目的地的同时仍保留着内部结构. 表面看来似乎一切都很正常. 内核完全 unaware of what Scapy does behind. 因此在 loopback 接口中所观察到的内容也仅仅是假象而已. 此外需要注意的是这一部分并非本地生成.
为了实现跨平台的网络通信需求,在 Linux 系统中,必须先构造出相应的数据包以确保本地 IPv4 应用程序能够正常通信。具体来说,在上一层协议中应使用 PF_INET/SOCK_RAW 套接字,并且避免使用 PF_PACKET/SOCK_RAW(类似于其他非Linux系统的相应配置)。
>>> conf.L3socket
<class __main__.L3PacketSocket at 0xb7bdf5fc>
>>> conf.L3socket = L3RawSocket
>>> sr1(IP(dst) / ICMP())
<IP version=4L ihl=5L tos=0x0 len=28 id=40953 flags= frag=0L ttl=64 proto=ICMP chksum=0xdce5 src=127.0.0.1 dst=127.0.0.1 options='' |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>
AI助手
使用 IPv6,您可以简单地执行以下操作:
# Layer 3
>>> sr1(IPv6() / ICMPv6EchoRequest())
<IPv6 version=6 tc=0 fl=866674 plen=8 nh=ICMPv6 hlim=64 src=::1 dst=::1 |<ICMPv6EchoReply type=Echo Reply code=0 cksum=0x7ebb id=0x0 seq=0x0 |>>
5. # Layer 2
>>> conf.iface = "lo"
>>> srp1(Ether() / IPv6() / ICMPv6EchoRequest())
<Ether dst=00:00:00:00:00:00 src=00:00:00:00:00:00 type=IPv6 |<IPv6 version=6 tc=0 fl=866674 plen=8 nh=ICMPv6 hlim=64 src=::1 dst=::1 |<ICMPv6EchoReply type=Echo Reply code=0 cksum=0x7ebb id=0x0 seq=0x0 |>>>
AI助手
在 Windows、BSD 和 macOS 系统中,请您首先关闭本地防火墙,并将conf.iface配置为环回接口;这样才能顺利运行以下命令。
# Layer 3
>>> sr1(IP() / ICMP())
<IP version=4L ihl=5L tos=0x0 len=28 id=40953 flags= frag=0L ttl=64 proto=ICMP chksum=0xdce5 src=127.0.0.1 dst=127.0.0.1 options='' |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>
>>> sr1(IPv6() / ICMPv6EchoRequest())
<IPv6 version=6 tc=0 fl=866674 plen=8 nh=ICMPv6 hlim=64 src=::1 dst=::1 |<ICMPv6EchoReply type=Echo Reply code=0 cksum=0x7ebb id=0x0 seq=0x0 |>>
7. # Layer 2
>>> srp1(Loopback() / IP() / ICMP())
<Loopback type=IPv4 |<IP version=4 ihl=5 tos=0x0 len=28 id=56066 flags= frag=0 ttl=64 proto=icmp chksum=0x0 src=127.0.0.1 dst=127.0.0.1 |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>>
>>> srp1(Loopback() / IPv6() / ICMPv6EchoRequest())
<Loopback type=IPv6 |<IPv6 version=6 tc=0 fl=0 plen=8 nh=ICMPv6 hlim=64 src=::1 dst=::1 |<ICMPv6EchoReply type=Echo Reply code=0 cksum=0x7ebb id=0x0 seq=0x0 |>>>
AI助手
4. BPF 过滤器不起作用。我在一个ppp链接上
此乃众所周知的一个问题。对于 BPF 过滤器而言,在 ppp 接口上实施不同偏移量的配置是必要的。若采用 libpcap 来构建 BPF 过滤器而非依赖本机 Linux 的 PF_PACKET 接口,则可能取得预期效果。
5. traceroute() 不起作用。我在一个ppp链接上
这是一个已知的错误。请参阅 BPF 过滤器不起作用。我在一个ppp链接上
要解决此问题,请使用nofilter=1:
>>> traceroute("target", nofilter=1)
AI助手
6. 图表很难看/字体太大/图像被截断。
快速修复:使用 png 格式:
>>> x.graph(format="png")
AI助手
升级到最新版本的 GraphViz。
尝试提供不同的 DPI 选项(例如 50,70,75,96,101,125):
>>> x.graph(options="-Gdpi=70")
AI助手
如果它有效,您可以使其永久化:
>>> conf.prog.dot = "dot -Gdpi=70"
AI助手
您也可以将此行放入~/.scapy_startup.py文件中
二、获取帮助
常见问题在常见问题解答中得到解答。
如果您需要更多帮助,请查看:
The Gitter channel
位于scapy.ml(at)secdev.org的相关讨论区(包括Archive、以及RSS和NNTP)也提供了一个流量较低的安全开发邮件列表。可订阅该列表的邮件地址为scapy.ml-subscribe(at)secdev.org。
我们鼓励您发送问题、错误报告、建议、想法、Scapy 的酷用法等。
Scapy API 具体请参考:
API reference — version 2.4.5 docs, accessible at https://scrapy.readthedocs.io/en/latest/api/scrapy.html#module-scrapy
三、Scapy发展
项目组织
Scapy 开发采用基于 Git 的版本控制系统进行管理与维护。具体存储位置位于GitHub - secdev/scapy: Scapy: the Python-based interactive packet manipulation program & library. Supports Python 2 & Python 3.
项目管理由GitHub(Github)负责实现。该平台提供了一个开放且易于编辑的公共 Wiki([ Wiki ](https://github.com/secdev/scapy/wiki/" Wiki ")),欢迎随时参与贡献!此外,请注意此 Wiki 支持引用项目中的关键文件、变更记录以及相关文档资料。另外,请了解该系统还提供了 Bug 管理功能以防止忘记补丁或错误修复
如何贡献
遇到Scapy中的错误?请引导至该问题的GitHub Issues页面进行提交
改进此文档。
编写一个新层并在邮件列表中共享它,或者创建一个拉取请求。
为项目添加了新的回归测试方案,并提供了相应的实施方法和资源链接
请确保您将新协议的数据包样本通过位于数据包样本页面的链接进行提交。
四、改进帮助文档
可以通过以下几种方式改进文档:
将文档字符串添加到源代码。
在文档中添加使用示例。
添加文档字符串
Scapy 的源代码对函数的作用机制缺乏详细的说明。通过提供清晰的注释和明确的输入输出示例,文档字符串能够显著地帮助层次分明的技术人员以及那些寻求深入功能模块的用户减少探索时间。
类中的文档字符串示例scapy.fields.FlagsField:
class FlagsField(BitField):
""" Handle Flag type field
4. Make sure all your flags have a label
6. Example:
>>> from scapy.packet import Packet
>>> class FlagsTest(Packet):
fields_desc = [FlagsField("flags", 0, 8, ["f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"])]
>>> FlagsTest(flags=9).show2()
###[ FlagsTest ]###
flags = f0+f3
>>> FlagsTest(flags=0).show2().strip()
###[ FlagsTest ]###
flags =
17. :param name: field's name
:param default: default value for the field
:param size: number of bits in the field
:param names: (list or dict) label for each flag, Least Significant Bit tag's name is written first
"""
AI助手
该文档将包含对所述类的一行简明扼要的描述,并随后提供关于其使用方法的相关指导。(如果采用doctest)这一格式具有意义时,则可以选择性地添加一个示例。(在sphinx 文档中加入经典的Python签名。)
此任务与编写非回归单元测试配合使用。
文档
改进文档内容的一种途径是确保文档内容与最新版本的 Scapy 接口保持同步。另外一种有效的方式是将现有技术方案与现有在线Scapy演示文稿中的相关技术方案进行参考并加以集成以提升整体效果
五、使用 UTScapy 进行测试
什么是 UTScapy?
UTScapy 是一种小型 Python 应用程序,在获取测试活动后会通过 Scapy 执行这些活动,并生成反映测试状态的信息报告。该报告可采用以下四种格式中的任意一种:文本格式、ANSI 格式、HTML 格式或 LaTeX 格式。
UTScapy包含三种基本的类型:分别是单元测试、标准测验和任务分组。其中一种是单独运行的一组Scapy指令序列;另一种是多个相关联的小测验集合;第三种则是一个或多个此类测验分组所构成的整体任务集合。在执行活动期间,可以通过关键字参数指定特定的集合或子集。每个测验类型都有其独特的执行流程:对于单独的小测验而言,在执行后会根据最后一个指令的结果来确定其最终状态;对于由多个相关联小测验组成的集合,则会根据所有成员的表现来综合评估整体表现;而用于任务分组的标准测验则会在完成所有成员后生成最终报告以供参考分析。
在每次单个测试用例执行过程中(无论是单元测试、还是整体测试集及活动),系统都会生成一个相应的 CRC32 值,并将其作为此测试的唯一标识符。通过此标识符(即所谓的"签名"),我们可以确认该测试并未被人为篡改。当遇到试图非法修改文件但仍保持 CRC32 不变的情况时,则应在完整文件上执行 SHA1 检验。
测试活动的语法
表 1 列出了 UTScapy 寻找的关键语法指标。每个测试文本文件的第一行都必须以特定语法符号开始;这些后续文本由 UTScapy 解释参数。未带有任何前导符号的行被视为 Python 命令;前提是它们位于单元测试场景中。UTScapy 会拒绝那些没有符号且位置错误的情况,并发出警告。
| 语法说明符 | 定义 |
|---|---|
| '%' | 给出测试活动的名称。 |
| '+' | 宣布一个新的测试集。 |
| '=' | 宣布一个新的单元测试。 |
| '~' | 宣布当前单元测试的关键字。 |
| '*' | 表示将包含在报告中的注释。 |
| '#' | 解释器丢弃的测试用例注释。 |
表 1 - UTScapy 语法说明符
放置于报告中的注释处于上下文之中。
每个评论都会与最后定义的实验环境相关联——无论涉及单独的一个单位测验、数据集合或是任务流程。
关联到同一实验环境下的多个评注会连在一起,并且会在实验环境宣告之后直接呈现于报告中。
通常会在声明实验流程之前出现。
对于要与之相关的评注而言,在其所属的具体实验流程或任务中出现是必要的前提条件。
应放置于该数据集合的第一个单位测验之前的适当位置。
测试活动的通用格式如下表所示:
% Test Campaign Name
* Comment describing this campaign
+ Test Set 1
* comments for test set 1
= Unit Test 1
~ keywords
* Comments for unit test 1
# Python statements follow
a = 1
print a
a == 1
AI助手
Python 语句可借助未定义的 UTScapy 语法指示符进行识别,在 Python 解释器中被模拟为交互式 Scapy 环境下的操作(interact)。允许嵌套循环、迭代与条件判断,并需以空白行结尾。一个测试集合可由若干单元测试构成,并可在每个活动下独立配置多个测试集合;在一个特定的测试定义文件中亦可包含多组测试活动。通过关键字的操作可限定特定子集的行为,在开发新测试活动时用户可用"调试"标记处于开发阶段的新测试;当完成预期目标后即可删除"debug"标签;也可采用"回归"或"有限"等关键字进行相关操作。
需要注意的是,在UTScapy中将最后一条Python语句中的布尔值用作程序是否通过或返回失败的具体标准是十分关键的一步
UTScapy 的语法如表 3 - UTScapy 命令行语法所示:
[root@localhost scapy]# ./UTscapy.py –h
Usage: UTscapy [-m module] [-f {text|ansi|HTML|LaTeX}] [-o output_file]
[-t testfile] [-k keywords [-k ...]] [-K keywords [-K ...]]
[-l] [-d|-D] [-F] [-q[q]]
-l : generate local files
-F : expand only failed tests
-d : dump campaign
-D : dump campaign and stop
-C : don't calculate CRC and SHA
-q : quiet mode
-qq : [silent mode]
-n <testnum> : only tests whose numbers are given (eg. 1,3-7,12)
-m <module> : additional module to put in the namespace
-k <kw1>,<kw2>,... : include only tests with one of those keywords (can be used many times)
-K <kw1>,<kw2>,... : remove tests with one of those keywords (can be used many times)
AI助手
表 3 - UTScapy 命令行语法
各参数均为可选设置。若某特定参数无指定值,则该参数可与其它无关联项连用(例如–lqF)。若未明确指定输入文件,默认情况下该程序将从标准输入读取数据。同样地,在无指明输出的情况下,默认输出将被重定向至标准输出。默认采用ANSI编码方式显示结果。表4详细列出了各关键配置项及其在UTScapy中的功能描述。
| 争论 | 参数值 | 对 UTScapy 的意义 |
|---|---|---|
| -t | testfile | 定义测试活动的输入测试文件(默认 = |
| -o | output_file | 用于输出测试活动结果的文件(默认 = |
| -F | test | ansi、HTML、LaTeX、格式化输出报告(默认 = ansi) |
| -l | 在本地生成报告关联文件。对于 HTML,生成 JavaScript 和样式表 | |
| -F | 默认情况下,失败的测试用例将在 HTML 输出中展开 | |
| -d | 在执行活动之前打印一个简短的活动列表 | |
| -D | 打印一个简短的活动列表并停止。不执行活动 | |
| -C | 不计算测试签名 | |
| -q | 执行测试时不要将测试进度更新到屏幕上 | |
| 静音模式 | ||
| -n | testnum | 仅执行按编号列出的那些测试。可以使用 -d 或 -D 检索测试编号。测试可能以逗号分隔列表的形式列出,并且可能包括范围(例如 1、3-7、12) |
| -m | module | 在执行测试之前加载模块。在测试 Scapy 的衍生作品时很有用。注意:旨在作为“main”执行的派生作品不会被 UTScapy 调用为“main”。 |
| -k | kw1, kw2, … | 仅包括带有关键字“kw1”的测试。可以指定多个关键字。 |
| -K | kw1, kw2, … | 排除带有关键字“kw1”的测试。可以指定多个关键字。 |
表 4 - UTScapy 参数
如表所示,在这项简单的测试活动中包含了多个不同的测试集定义。此外,在该活动中还明确指出了能够执行一定数量测试用例的关键字。特别值得注意的是,在对第3和第5个测试用例进行处理时使用了assert()语句来验证中间结果的状态。由于设计上的不足,这两个特定的测试用例(2和5)无法通过验证。
% Example Test Campaign
# Comment describing this campaign
#
# To run this campaign, try:
# ./UTscapy.py -t example_campaign.txt -f html -o example_campaign.html -F
#
* This comment is associated with the test campaign and will appear
* in the produced output.
+ Test Set 1
= Unit Test 1
~ test_set_1 simple
a = 1
print a
= Unit test 2
~ test_set_1 simple
* this test will fail
b = 2
a == b
= Unit test 3
~ test_set_1 harder
a = 1
b = 2
c = "hello"
assert (a != b)
c == "hello"
+ Test Set 2
= Unit Test 4
~ test_set_2 harder
b = 2
d = b
d is b
= Unit Test 5
~ test_set_2 harder hardest
a = 2
b = 3
d = 4
e = (a * b)**d
# The following statement evaluates to False but is not last; continue
e == 6
# assert evaluates to False; stop test and fail
assert (e == 7)
e == 1296
= Unit Test 6
~ test_set_2 hardest
print e
e == 1296
AI助手
要查看针对 Scrapy 的示例,请访问UTScrapy: Unit Testing with Scrapy。将页面底部的代码示例复制并粘贴到文件中demo-campaign.txt后运行 UTscrapy:
./test/run_tests -t demo_campaign.txt -f html -o demo_campaign.html -F -l
AI助手
检查文件中生成的输出demo_campaign.html。
使用 tox 测试 Scapy
这一命令使得Scapy的测试更加简便。它会自动生成一个虚拟环境并安装必要的Python模块。
例如,在全新的 Debian 系统安装中,该命令将被自动执行所有 Scapy 单元测试任务,并且不需要额外配置。
tox -- -K vcan_socket -K tcpdump -K tshark -K nmap -K manufdb -K crypto
AI助手
如果未指定--e选项,则该过程会触发所有可用Python版本的单元测试。请参考接下文。
为了您使用的便利和项目的维护需求, 我们提供了这个 tox 程序. 它仅在一个默认的 Python 环境中运行, 并且无需任何外部依赖.
./test/run_tests
AI助手
.uts 文件的 VIM 语法高亮显示
为了完成此操作,请将所有位于scapy/doc/syntax/vim_uts_syntax/ftdetect目录下的文件以及位于scapy/doc/syntax/vim_uts_syntax/syntax目录下的内容进行拷贝,并确保目标路径下的文件夹结构得以保留。
如果 ftdetect/filetype.vim 已经存在,你可能需要手动修改这个文件。
这些命令将执行安装:
cp -i -v ftdetect/filetype.vim $HOME/.vim/ftdetect/filetype.vim
cp -i -v ftdetect/uts.vim $HOME/.vim/ftdetect/uts.vim
cp -i -v syntax/uts.vim $HOME/.vim/syntax/uts.vim
AI助手
或者,安装脚本scapy/doc/syntax/vim_uts_syntax/会自动进行安装。
六、释放 Scapy
从底层来看,在源代码层面(即Scapy源码中),每个版本都被明确标识为带有签名的git标签。为了确保发布流程的顺利进行,在提交修改请求之前,维护团队需要采取以下措施:
检查相应的 Travis 和 AppVeyor 测试是否通过
./run_scapy在本地运行
跑tox
使用来自的 Vagrant 设置在 BSD 上运行单元测试scapy/doc/vagrant_ci/
以 v2.4.3 为例,可以使用以下命令对版本进行签名和发布:
git tag -s v2.4.3 -m "Release 2.4.3"
git tag v2.4.3 -v
git push --tags
AI助手
发布版本(RC)同样能够实现这一目标。例如,在项目初期阶段的第一次 RC 版本将被明确标注为 v2.4.3rc1 并附加相关信息 message 。2.4.3 释然:Release Candidate #1
应先在PyPI上准备发布前,在其setup.py文件中修改变量位置处的字段值为执行发布维护者所使用的邮箱地址。随后可以运行以下命令:
python3 setup.py sdist
twine check dist/scapy-2.4.3.tar.gz
twine upload dist/scapy-2.4.3.tar.gz
AI助手
