本人英文水平有限,翻译不当之处,请參考官方站点。
关于Scapy
Scapy
是一个能够让用户发送、侦听和解析并伪装网络报文的Python程序。这些功能能够用于制作侦測、扫描和攻击网络的工具。
换言之,Scapy
是一个强大的操纵报文的交互程序。它能够伪造或者解析多种协议的报文,还具有发送、捕获、匹配请求和响应这些报文以及很多其他的功能。
Scapy
能够轻松地做到像扫描(scanning)、路由跟踪(tracerouting)、探測(probing)、单元測试(unit tests)、攻击(attacks)和发现网络(network discorvery)这种传统任务。它能够取代hping
,arpspoof
,arp-sk
,arping
,p0f
甚至是部分的Namp
,tcpdump
和tshark
的功能。
Scapy
在大多数其他工具无法完毕的特定任务中也表现优异,比方发送无效帧、加入自己定义的802.11的侦、多技术的结合(跳跃攻击(VLAN hopping)+ARP缓存中毒(ARP cache poisoning)、在WEP加密信道(WEP encrypted channel)上的VOIP解码(VOIP decoding))等等等等。
理念非常easy。Scapy
主要做两件事:发送报文和接收回应。
您定义一系列的报文,它发送这些报文,收到回应。将收到的回应和请求匹配。返回一个存放着(request, answer)即(请求, 回应)的报文对(packet couples)的列表(list)和一个没有匹配的报文的列表(list)。这样对于像Nmap
和hping
这种工具有一个巨大的优势:回应没有被降低 (open/closed/filtered)而是完整的报文。
在这之上能够建立很多其他的高级功能。比方您能够跟踪路由(traceroutes)并得到一个仅仅有请求的起始TTL和回应的源IP的结果。您也能够ping整个网络并得到匹配的回复的列表,您还能够扫描商品并得到一个LATEX 报表。
Scapy
为何如此特别
第一,对于其他的大多数网络工具来说,您无法制作一些作者无法想到的东西。这些工具已经被一个特定的目标所局限和固定,因此无法和这个目标有大的偏离。
比方,一个ARP缓存中毒程序不会让您使用double 802.1q
包裹内容。相同无法找到一个程序能够发送填充(padding)的ICMP报文(是填充(padding)。不是负载(payload))。其实,每次有新需求时,您必需又一次建立一个新的工具。
第二,这些工具经常混淆解码(decoding)和解释(interpreting)。机器擅长解码并能帮助人类完毕这个工作。
解释应该留给人类。
一些程序试图模拟这个行为。比方它们说“这个port是打开的”而不是说“我收到一个SYN-ACK
“.有时它们是对的。但有时不是。
这样做对于刚開始学习的人来说更easy,可是当您知道您正在做什么,您将继续试图推从程序的解释中測实际上发生了什么来制作自己的工具,可是这相当困难。由于大量的信息已经丢失。因此终于经常是您使用tcpdump -xX
来解码和解释这些工具丢掉的内容。
第三,即使是那些仅仅管解码的程序也没有把它们收到的全部的信息交给您。它们给您展示的网络信息仅仅是其作者觉得足够的信息。可是这些并不完整,对您来说是偏颇的。
比方。您知道有什么工具能够得到以太帧填充的报文吗(reports the Ethernet padding)?
其实,每次执行本程序,更像是建造一个新的工具,不是处理上百行的C程序代码。您使用Scapy
仅仅需写几行代码。
在探測(probe)(或者扫描(scan)、路由跟踪(traceroute)等等)之后,Scapy
总是在不论什么的解释之前把探測到的全部的包解码后给您。
这意味着您能够探測一次而解释非常多次,也能够使用路由跟踪并查看报文填充内容。
高速的报文设计
其他的工具坚持命令行执行的模式。这导致描写叙述一个报文须要糟糕的语法。对于这些工具。解决办法是在其作者想像的情景下,採用一种更高层可是功能更弱的描写叙述方法。
举例来说。在port扫描的情景中,port扫描器必须的參数仅仅有IP地址。即使情景有所改变,情况依旧如此(Even if the scenario is tweaked a bit, you still are stuck to a port scan)。
Scapy
的原则是推荐使用一种特定领域语言(Domain Specific Language (DSL))以达到对于不论什么种类报文的功能强大并高速的描写叙述。使用Python
语法和Python
解释器作为特定领域语言(DSL)的语法和解释器有很多优势:没有必要写一个单独的解释器,用户不须要再学一种新语言并能够从这个完整、简约且非常强大的语言中受益。
Scapy
同意用户将一个或一系列报文描写叙述成为一个个堆起来的层(layer)。每层的数据域有实用的且可重载的默认值。
Scapy
不强制用户使用预先定义的方法和模板。这样每次碰到不同的情景时写新工具的须要得到了降低。
在C语言中,描写叙述一个报文可能平均要用60行代码。
使用Scapy
,发送的报文可能仅需一行代码描写叙述再加一行打印结果的代码。
90%的网络探測工具能够使用Scapy
使用2行代码又一次实现。
一次探測,多次解释
网络的发现是一个黑盒測试。
当探測一个网络时。很多侦測报文(stimuli)发送然而它们其中仅仅有少数能够被回应。假设选择了正确的侦測报文,希望得到的信息能够通过回应的报文或者是没有回应的情况来获得。不像非常多其他的工具,Scapy
得到全部的信息,也就是说,全部的发送的侦測报文和全部收到的回应。
通过检查这些数据用户能够得到想要的信息。当数据量较小时,用户能够直接查看数据。
在其他情况下。对于数据的解释将依赖于关注点的不同。多数工具选择展示关注点内容而忽略和关注点无关的内容。由于Scapy
给出完整的原始数据,因此这些数据能够多次使用从而同意关注点在分析过程中发生变化。比方,可能探測一个TCPport扫描而关注(展示)port扫描的结果。同一时候也能够查看回应报文的TTL方面的内容。一个新的探測并不须要再来一次,而仅仅是在已有的数据中改一下关注点就可以。
Scapy
解码而不解释
网络探測工具所共同拥有的一个问题是它们都试图解释收到的回应而非仅仅解码并给出结果。
报告一些相似于在80port收到一个TCP Reset报文这种消息不属于解释错误。报告80port关闭在多数情况下是正确的,可是在某些特定的工具的作者没有想到的上下文中是错误的。比方。一些扫描器在收到一个目的地址不可达的ICMP报文后倾向于报告一个过滤TCPport。这可能是正确的。可是在某些情况下,这表明报文被防火墙过滤掉而找不到报文的非目的主机。
解释结果能够帮助那些不知道什么是port扫描的用户,可是弊大于利,由于这对于结果是一种主观的解释。可能的结果就是它们能够自己解释。知识丰富的用户将试图反向还原这个工具的解释以得到引起这个解释的真正原因。不幸的是,在这个过程中有大量的信息丢失。
高速展示(Quick demo)
首先我们略微试一下,一次创建4个IP报文来看看这个工具是怎样工作的。
我们首先初始化IP类。然后。我们又一次将其实例化并给出4个IP报文的目的地址(/30给出掩码)。使用Python
语法,我们在一系列明白的报文中定义这个报文(we develop this implicit packet in a set of explicit packets)。然后,我们退出解释器。作为我们提供的会话文件(session file)。这些我们正在使用变量已经保存,然后又一次载入:
# ./scapy.py -s mysession
New session [mysession]
Welcome to Scapy (0.9.17.108beta)
>>> IP()
<IP |>
>>> target="www.target.com"
>>> target="www.target.com/30"
>>> ip=IP(dst=target)
>>> ip
<IP dst=<Net www.target.com/30> |>
>>> [p for p in ip]
[<IP dst=207.171.175.28 |>, <IP dst=207.171.175.29 |>
<IP dst=207.171.175.30 |>, <IP dst=207.171.175.31 |>]
>>> ^D
# scapy -s mysession
Using session [mysession]
Welcome to Scapy (0.9.17.108beta)
>>> ip
<IP dst=<Net www.target.com/30 |>
如今。我们来操纵一些报文:
>>> IP()
<IP |>
>>> a=IP(dst="172.16.1.40")
<IP dst=172.16.1.40 |>
>>> a.dst
'172.16.1.40'
>>> a.ttl
64
让我们来说我想要一个广播的MAC地址。而且负载的IP报文要到达ketchup.com和mayo.com。TTL值从1到9。并负载UDP报文:
>>> Ether(dst="ff:ff:ff:ff:ff:ff")
/IP(dst=["ketchup.com", "mayo.com"], ttl=(1,9))
/UDP()
如今我们在一行(一个确定报文(implicit packet))中定义了18个报文。
合理的默认值
Scapy
试图在全部种类的报文数据域中使用合理的默认值,假设没有被重载的话,
- IP源地址依据目的地址和路由表选择
- 校验和自己主动计算
- 源MAC地址依据输出接口(output interface)选择
- 以太网类型和IP协议由高层决定
其他数据域选择最实用的值:
- TCP源port为20,目的port为80
- UDP源port和目的port均为53
- ICMP类型为echo request
学习Python
Scapy
使用Python
解释器作为命令面板。这意味着你能够直接使用Python
语言(创建变量,使用循环,定义函数等等)。
假设你刚開始使用Python
而且因此你不理解这些词语,或者假设你想学习这个语言,花一个小时来阅读一个Guido Van Rossum写的非常棒的Python教程。在此之后,你将知道Python
:)(真的!
)。
对于更加深入的学习,Dive Into Python也是一个非常好的開始。
作为一个高速的開始,以下是Python
数据类型的概览:
-
int
(signed, 32bits) :42
-
long
(signed, infinite) :42L
-
str
:"bell\x07\n"
or'bell\x07\n'
-
tuple
(immutable):(1,4,"42")
-
list
(mutable):[4,2,"1"]
-
dict
(mutable):{"one":1, "two":2}
Python
中没有块切割符,而是同缩进决定:
if cond:
instr
instr
elif cond2:
instr
else:
instr