SCAPY官方教程七
Scapy的Pipes工具(Pipetool)是一个用于构建复杂数据流的管道系统。它由Source、Drain和Sink三个核心组件组成,允许用户创建复杂的流程并处理数据流量。默认支持的数据源包括Clifeeper、CLIHighFeeder和其他集成源类型,并可自定义扩展以满足特定需求。Drains包括基本的TransformDrain、UpDrain和DownDrain等类,并支持自定义创建以实现特定的功能。Sinks则接收来自Drains的消息并可配置输出方式,默认包括ConsoleSink、QueueSink等常用类型。
PipeEngine是该系统的核心类,负责初始化和管理所有源,并提供启动(start())、强制停止(stop())和等待停止(waitandstop())等功能。此外,高级对象如SniffSource和RdpcapSource可用于从接口或PCAP文件捕获数据包并发送到低层输出;而Trigger排水管则允许根据特定条件触发消息传递。
该系统通过管道式的数据处理机制简化了复杂的流量管理任务,并提供了灵活的配置选项以适应不同场景的需求。
一、管道工具
Scapypipetool是一个智能管道系统,允许执行复杂的流数据管理。
本意在于构建一个由多步操作组成的管道结构,在这个系统中会有多个节点依次排列形成流程线。该软件支持处理多种数据源及相应的输出结果,并提供灵活的操作方式。例如它能够管理用户的常规输入数据以及网络流量捕捉(pcap)结果等不同类型的资源。该管道架构允许在运行过程中实时调整配置并动态连接各个组件从而形成完整的业务流程网状结构。对于同一个数据来源还能够同时配置多组过滤器以满足不同的监控需求
Pipetool 默认对象位于内部 scapy.pipetool
演示:嗅探、匿名化、发送到 Wireshark
该代码将在默认接口上捕获数据包,并对匿名来源与目标IP地址进行记录后通过管道传输至Wireshark。例如,在展示在线演示时非常有帮助。
source = SniffSource(iface=conf.iface)
wire = WiresharkSink()
def transf(pkt):
if not pkt or IP not in pkt:
return pkt
pkt[IP].src = "1.1.1.1"
pkt[IP].dst = "2.2.2.2"
return pkt
source > TransformDrain(transf) > wire
p = PipeEngine(source)
p.start()
p.wait_and_stop()
AI助手
引擎非常简单:

让我们运行它:

二、类类型
有 3 类不同的对象用于数据管理:
Sources
Drains
Sinks
该对象负责通过PipeEngine对象进行操作并处理相关任务。
运行时,在pipetool引擎处于等待状态时接收来自Source节点的所有可用数据,并将这些信息通过与之直接相连的Drains节点传递出去。随后,在各相关Drains节点之间进行数据传输操作直至最终达到其对应的Sink节点,并标志着该数据处理流程的完成。
让我们通过一个基本的演示来看看如何构建一个 pipetool 系统。

例如,此引擎是使用以下代码生成的:
>>> s = CLIFeeder()
>>> s2 = CLIHighFeeder()
>>> d1 = Drain()
>>> d2 = TransformDrain(lambda x: x[::-1])
>>> si1 = ConsoleSink()
>>> si2 = QueueSink()
>>>
>>> s > d1
>>> d1 > si1
>>> d1 > si2
>>>
>>> s2 >> d1
>>> d1 >> d2
>>> d2 >> si1
>>>
>>> p = PipeEngine()
>>> p.add(s)
>>> p.add(s2)
>>> p.graph(target="> the_above_image.png")
AI助手
initiate() 用于启动 PipeEngine 工作流程:指定所需功能并设置相关参数。
>>> p.start()
AI助手
现在,让我们通过发送一些输入数据来玩它
>>> s.send("foo")
>'foo'
>>> s2.send("bar")
>>'rab'
>>> s.send("i like potato")
>'i like potato'
>>> print(si2.recv(), ":", si2.recv())
foo : i like potato
AI助手
让我们研究一下这里发生了什么:
a有两种流动路径可选,在PipeEngine中存在一条低优先级的方向和一条高优先级的方向。部分数据源放置在低优先级的方向上,并有其他数据源分散在高优先级的方向及两者的交汇处。
多数水源能够通过任何排水管与不同水位或深深度的运河相连。其中符号>被定义为低水位或浅深度运河之间的连接;而符号>>则用于表示高水位或深深度运河之间的连接。
当向系统发送数据时s该数据通过下运河传输如图所示经由Drain接口被转发至QueueSink和ConsoleSink
当我们将数据发送至s2时, 它将首先经由 Drain 进行处理, 然后经过变换处理的 TransformDrain(如图所示), 最后才会被转发至ConsoleSink. 这也解释了为何在 QueueSink 中我们仅接收来自较低优先级的数据源: 高优先级的数据源未与其建立连接.
大部分水槽被下水道和上水道所获取。该系统可以通过调用帮助功能(ConsoleSink)来进行验证工作。
>>> help(ConsoleSink)
Help on class ConsoleSink in module scapy.pipetool:
class ConsoleSink(Sink)
| Print messages on low and high entries
| +-------+
| >>-|--. |->>
|print||
| >-|--' |->
| +-------+
||
[...]
AI助手
Sources
Source 是一个生成一些数据的类。
多种源类型与 Scapy 集成直接利用现有配置进行测试和分析。此外, 您也可以创建自己的源类型以满足特定需求.
默认源类
每个类中的对象,请通过调用函数help([theclass])来获取相关信息或必要的参数设置。
CLIFeeder: 该类专门用于交互式软件的源数据输入。通过send(data)方法,在下行链路上负责传递事件数据
CLIHighFeeder:与 CLIFeeder 相同,但写在更高的运河上
该网络元素定期地发送消息至其低运河
AutoSource:此为默认起始点,在构建自定义源时需通过扩展来生成。
创建自定义源
创建自定义数据源时,请确保深入开发并详细实现AutoSource模块。
避免直接使用默认提供的[...]: 该工具仅用于内部操作,并缺乏某些功能。AutoSource旨在满足特定需求。
为实现目标,系统必须使用该功能发送消息,并由相应的生成函数将其传输至 PipeEngine。
在可能的情况下,在空时将本类属性self.is_exhausted设置为True以便能够彻底终止PipeEngine. 如果源是无限的,则必须强制停止,请参考其文档说明。
例如,在此处是如何通过 CLIHighFeeder 实现的:
class CLIFeeder(CLIFeeder):
def send(self, msg):
self._gen_high_data(msg)
def close(self):
self.is_exhausted = True
AI助手
Drains
默认排水类
应在此处链接排水管。可用符号为下一个符号(使用>)或上一个符号(使用>>)。如需进一步了解,请参考基本示例部分。
该函数代表基础版本的 Drain 实现。若连接成功,则会通过低位和高位进行接入。
该工具用于将函数应用于低端和高端数据项
该组件为Up-Drain工具(https://scapy.readthedocs.io/en/latest/api/scapy.pipetool.html#scapy.pipetool.UpDrain)的功能描述
DownDrain:按照入口降序至出口升序的循环数据
创建自定义排水管
为了实现功能需求而需将Drain类进行扩展以支持自定义排水管的创建
该Drain实例将在push()方法中读取来自标准输入的数据块,并在另一个处理流程中通过high_push方法读取来自标准输出的数据块。
为了将数据传递到下一个链接的Drain/Sink端口,该对象必须被调用self._send(msg)或self._high_send(msg)方法.
这里是如何利用TransformDrain来完成任务的:
class TransformDrain(Drain):
def __init__(self, f, name=None):
Drain.__init__(self, name=name)
self.f = f
def push(self, msg):
self._send(self.f(msg))
def high_push(self, msg):
self._high_send(self.f(msg))
AI助手
Sinks
接收器是消息的目的地。
该组件通过Sink捕获类似a的数据,并通过Drain对其进行处理,在随后的过程中不再进行任何信息的传输。
较低端的接口通过push()函数接收消息来源;而更高端的接口则通过high_push()函数接收消息来源。
默认接收器类
ConsoleSink:输出针对低和高条目的消息到stdout
RawConsoleSink: 主要功能是通过os.write向低端和高端缓冲区输出信息
TermSink:在单独的终端上打印低和高条目上的消息
QueueSink:负责整合来自低负载和高负载端的消息,并将其分配到特定的队列中。
创建自定义接收器
需在[ Sink ]类中创建自定义接收器,则需在其基础上扩展该类并提供 push() 方法的支持。此外,在设计时还可以考虑支持 push() 方法以及 high_push() 方法中的一个或多个选项。
这是一个简化版本ConsoleSink:
class ConsoleSink(Sink):
def push(self, msg):
print(">%r" % msg)
def high_push(self, msg):
print(">>%r" % msg)
AI助手
三、链接对象
如示例所示,大多数源可以连接到任何漏极,无论是低入口还是高入口。
的使用>表示低入口和>>高入口上的链接。
例如,要链接a,b并c在低条目上:
>>> a = CLIFeeder()
>>> b = Drain()
>>> c = ConsoleSink()
>>> a > b > c
>>> p = PipeEngine()
>>> p.add(a)
AI助手
这不会链接高条目,所以这样的事情不会做任何事情:
>>> a2 = CLIHighFeeder()
>>> a2 >> b
>>> a2.send("hello")
AI助手
由于b$ ([Drain](https://scapy.readthedocs.io/en/latest/api/scapy.pipetool.html#scapy.pipetool.Drain "Drain"))和c$ (scapy.pipetool.ConsoleSink)位于高处无连接
然而, 该方法通过采用 DownDrain 实现了将来自 CLIHighFeeder 的高消息内容传输至其低通道。
>>> a2 = CLIHighFeeder()
>>> b2 = DownDrain()
>>> a2 >> b2
>>> b2 > b
>>> a2.send("hello")
AI助手
四、PipeEngine 类
此对象PipeEngine属于 Pipetool 系统的关键成员。它需要初始化,并通过所有来源的集合进行操作。
传递源有两种方式:
初始化期间:p = PipeEngine(source1, source2, ...)
使用add(source)方法
每个 PipeEngine 类都需要通过调用 .start() 函数来实现初始化功能。
该类可以通过调用 .stop() 方法实现强制终止。
此外,该类也可以使用 .wait_and_stop() 方法实现干净地终止操作。
仅当 Sources 已用尽(没有数据要发送)时,才可以完全停止。
能够实现将一个实例生成为图形.graph()。
关于可用关键字参数的列表信息,请参考help(do_graph)。
五、Scapy 高级 PipeTool 对象
相较于之前的位置,这些对象而位于scapy.scapypipes。
您现在已经了解了 PipeTool 的默认对象。此外还有基于数据包功能实现的更高级的对象。
SniffSource:该工具通过从网络接口接收数据包,并将其转发至指定的出口进行操作。
RdpcapSource:该工具通过解析PCAP文件中的数据包,并将其传输至最低端口进行处理。
InjectSink:该组件在低输入端接收的数据包被转发出去。
该接口WrpcapSink: 当输入量较低时会将接收到的报文块记录至PCAP文件中。
UDPDrain:在高入口处接收到来自于的有效UDP流量并通过UDP发送出去(建议参考帮助文档以获取更多信息)
FDSourceSink: 基于文件描述符实现源与接收器的连接
该 API 用于建立一个 TCP 连接到指定地址和端口,并将该端口作为发送数据的源以及接收数据的目标。
TCPListenerPipe: TCP is watching [addr:]port and using the first connection as both source and destination (complex, consult help(TCPListenerPipe))
六、触发
存在一些特殊类型的排水管:触发排水管。
特殊的触发漏极在接收数据时不仅传递数据本身也会发送"触发"输入由后续存在的下一个触发漏极进行接收与处理。
例如,在网络安全协议中,默认情况下该协议(TriggersDrain)被设计用于处理来自不同端口的HTTP/HTTPS流量请求的基本操作流程概述。它能够有效识别并拦截异常流量,并通过配置参数实现对常见攻击的防护机制。
>>> a = CLIFeeder()
>>> d = TriggerDrain(lambda msg: True) # Pass messages and trigger when a condition is met
>>> d2 = TriggeredValve()
>>> s = ConsoleSink()
>>> a > d > d2 > s
>>> d ^ d2 # Link the triggers
>>> p = PipeEngine(s)
>>> p.start()
INFO: Pipe engine thread started.
>>>
>>> a.send("this will be printed")
>'this will be printed'
>>> a.send("this won't, because the valve was switched")
>>> a.send("this will, because the valve was switched again")
>'this will, because the valve was switched again'
>>> p.stop()
AI助手
涉及多个明确标识的排水系统已存在多个触发点,并且这些排水系统具有清晰明确的功能划分。为确保操作准确无误,请参考官方帮助文档中的相关内容:help([the class])
TriggeredMessage: 在触发时传递预加载信息并在后续流程中进行触发。
TriggerDrain: 传递消息并在满足条件时触发
TriggeredValve是一种机制,在触发时控制消息的传递状态,并根据触发条件进行相应的调整。
该组件(TriggeredQueueingValve)的作用是实现消息轮流经过或排队的状态,在触发条件满足时完成切换操作
TriggeredSwitch:让消息交替高或低,在触发时改变
