Scapy中文使用文档.docx
《Scapy中文使用文档.docx》由会员分享,可在线阅读,更多相关《Scapy中文使用文档.docx(41页珍藏版)》请在冰点文库上搜索。
Scapy中文使用文档
from:
byLarry
0x01起航Scapy
Scapy的交互shell是运行在一个终端会话当中。
因为需要root权限才能发送数据包,所以我们在这里使用sudo
$sudoscapy
WelcometoScapy在Windows当中,请打开命令提示符(),并确保您拥有管理员权限:
C:
\>scapy
INFO:
NoIPv6supportinkernel
WARNING:
NoroutefoundforIPv6destination:
:
(nodefaultroute?
)
WelcometoScapy如果您没有安装所有的可选包,Scapy将会告诉你有些功能不可用:
INFO:
Can'timportpythongnuplotwrapper.Won'tbeabletoplot.
INFO:
Can'timportPyX.Won'tbeabletousepsdump()orpdfdump().
虽然没有安装,但发送和接收数据包的基本功能仍能有效。
0x02互动教程
本节将会告诉您一些Scapy的功能。
让我们按上文所述打开Scapy,亲自尝试些例子吧。
第一步
让我们来建立一个数据包试一试
>>>a=IP(ttl=10)
>>>a
>>>
’=""
>>>a
>>>
’del
>>>a
>>>
64
堆加层次(OSI参考模型)
/操作符在两层之间起到一个组合的作用。
当使用该操作符时,下层可以根据其上层,使它的一个或多个默认字段被重载。
(您仍可以赋予您想要的值)一个字符串也可以被用作原料层(rawlayer)。
>>>IP()
>>>IP()/TCP()
>
>>>Ether()/IP()/TCP()
>>
>>>IP()/TCP()/"GET/HTTP/\r\n\r\n"
>>
>>>Ether()/IP()/IP()/UDP()
>>>
>>>IP(proto=55)/TCP()
>
每一个数据包都可以被建立或分解(注意:
在Python中_(下划线)是上一条语句执行的结果):
>>>str(IP())
'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'
>>>IP(_)
chksum=0x7ce7src=dst=|>
>>>a=Ether()/IP(dst="")/TCP()/"GET/HTTP/\n\n"
>>>hexdump(a)
00021537A24400AEF352AAD108004500......R....E.
0043000100004006783CC0A805154223.C....@.x<....B#
FA970014005000000000000000005002.....P........P.
2000BB390000474554202F696E646578..9..GET/index
2E68746D6C20485454502F312E30200A.htmlHTTP/.
0A.
>>>b=str(a)
>>>b
'\x00\x02\x157\xa2D\x00\xae\xf3R\xaa\xd1\x08\x00E\x00\x00C\x00\x01\x00\x00@\x06x<\xc0
\xa8\x05\x15B#\xfa\x97\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02\x00
\xbb9\x00\x00GET/HTTP/\n\n'
>>>c=Ether(b)
>>>c
02:
15:
37:
a2:
44src=00:
ae:
f3:
52:
aa:
d1type=0x800|ihl=5Ltos=0x0len=67id=1flags=frag=0Lttl=64proto=TCPchksum=0x783c
src=dst=options=''|ack=0Ldataofs=5Lreserved=0Lflags=Swindow=8192chksum=0xbb39urgptr=0
options=[]|>>>
我们看到一个分解的数据包将其所有的字段填充。
那是因为我认为,附加有原始字符串的字段都有它自身的价值。
如果这太冗长,hide_defaults()方法将会删除具有默认值的字段:
>>>()
>>>c
0f:
66:
56:
fa:
d2src=00:
ae:
f3:
52:
aa:
d1type=0x800|frag=0proto=TCPchksum=0x783csrc=dst=|chksum=0xbb39options=[]|>>>
读取PCAP文件
你可以从PCAP文件中读取数据包,并将其写入到一个PCAP文件中。
>>>a=rdpcap("/spare/captures/")
>>>a
<:
UDP:
721TCP:
0ICMP:
0Other:
0>
图形转储(PDF,PS)
如果您已经安装PyX,您可以做一个数据包的图形PostScript/PDF转储(见下面丑陋的PNG图像,PostScript/PDF则具有更好的质量...)
>>>a[423].pdfdump(layer_shift=1)
>>>a[423].psdump("/tmp/",layer_shift=1)
命令效果
str(pkt)组装数据包
hexdump(pkt)十六进制转储
ls(pkt)显示出字段值的列表
()一行摘要
()针对数据包的展开试图
()显示聚合的数据包(例如,计算好了校验和)
()用数据包字段填充格式字符串
()改变payload的decode方式
()绘制一个解释说明的PostScript图表
()绘制一个解释说明的PDF
()返回可以生成数据包的Scapy命令
生成一组数据包
目前我们只是生成一个数据包。
让我们看看如何轻易地定制一组数据包。
整个数据包的每一个字段(甚至是网络层次)都可以是一组。
在这里隐含地定义了一组数据包的概念,意即是使用所有区域之间的笛卡尔乘积来生成的一组数据包。
>>>a=IP(dst="")
>>>a
>>>[pforpina]
[,,
,]
>>>b=IP(ttl=[1,2,(5,9)])
>>>b
>>>[pforpinb]
[,,,,
,,]
>>>c=TCP(dport=[80,443])
>>>[pforpina/c]
[>,
>,
>,
>,
>,
>,
>,
>]
某些操作(如修改一个数据包中的字符串)无法对于一组数据包使用。
在这些情况下,如果您忘记展开您的数据包集合,只有您忘记生成的列表中的第一个元素会被用于组装数据包。
命令效果
summary()显示一个关于每个数据包的摘要列表
nsummary()同上,但规定了数据包数量
conversations()显示一个会话图表
show()显示首选表示(通常用nsummary())
filter()返回一个lambda过滤后的数据包列表
hexdump()返回所有数据包的一个hexdump
hexraw()返回所以数据包Rawlayer的hexdump
padding()返回一个带填充的数据包的hexdump
nzpadding()返回一个具有非零填充的数据包的hexdump
plot()规划一个应用到数据包列表的lambda函数
maketable()根据lambda函数来显示表格
发送数据包
现在我们知道了如何处理数据包。
让我们来看看如何发送它们。
send()函数将会在第3层发送数据包。
也就是说它会为你处理路由和第2层的数据。
sendp()函数将会工作在第2层。
选择合适的接口和正确的链路层协议都取决于你。
>>>send(IP(dst="")/ICMP())
.
Sent1packets.
>>>sendp(Ether()/IP(dst="",ttl=(1,4)),iface="eth1")
....
Sent4packets.
>>>sendp("I'mtravellingonEthernet",iface="eth1",loop=1,inter=
................^C
Sent16packets.
>>>sendp(rdpcap("/tmp/pcapfile"))#tcpreplay
...........
Sent11packets.
Fuzzing
fuzz()函数可以通过一个具有随机值、数据类型合适的对象,来改变任何默认值,但该值不能是被计算的(像校验和那样)。
这使得可以快速建立循环模糊化测试模板。
在下面的例子中,IP层是正常的,UDP层和NTP层被fuzz。
UDP的校验和是正确的,UDP的目的端口被NTP重载为123,而且NTP的版本被更变为4.其他所有的端口将被随机分组:
>>>send(IP(dst="target")/fuzz(UDP()/NTP(version=4)),loop=1)
................^C
Sent16packets.
发送和接收数据包(sr)
现在让我们做一些有趣的事情。
sr()函数是用来发送数据包和接收应答。
该函数返回一对数据包及其应答,还有无应答的数据包。
sr1()函数是一种变体,用来返回一个应答数据包。
发送的数据包必须是第3层报文(IP,ARP等)。
srp()则是使用第2层报文(以太网,等)。
>>>p=sr1(IP(dst="")/ICMP()/"XXXXXXXXXXX")
Beginemission:
...Finishedtosend1packets.
.*
Received5packets,got1answers,remaining0packets
>>>p
chksum=0x51ddsrc=dst=options=''|code=0chksum=0xee45id=0x0seq=0x0||>>>
>>>()
---[IP]---
version=4L
ihl=5L
tos=0x0
len=39
id=15489
flags=
frag=0L
ttl=42
proto=ICMP
chksum=0x51dd
src===''
---[ICMP]---
type=echo-reply
code=0
chksum=0xee45
id=0x0
seq=0x0
---[Raw]---
load='XXXXXXXXXXX'
---[Padding]---
load='\x00\x00\x00\x00'
DNS查询(rd =recursiondesired)。
主机是我的DNS服务器。
注意从我Linksys来的非空填充具有Etherleak缺陷:
>>>sr1(IP(dst="")/UDP()/DNS(rd=1,qd=DNSQR(qname="")))
Beginemission:
Finishedtosend1packets.
..*
Received3packets,got1answers,remaining0packets
src=dst=options=''||nscount=0arcount=0qd=
an=
ns=0ar=0|>>>
发送和接收函数族是scapy中的核心部分。
它们返回一对两个列表。
第一个就是发送的数据包及其应答组成的列表,第二个是无应答数据包组成的列表。
为了更好地呈现它们,它们被封装成一个对象,并且提供了一些便于操作的方法:
>>>sr(IP(dst="")/TCP(dport=[21,22,23]))
Received6packets,got3answers,remaining0packets
(UDP:
0TCP:
3ICMP:
0Other:
0>,UDP:
0TCP:
0ICMP:
0Other:
0>)
>>>ans,unans=_
>>>()
IP/TCP>S==>Ether/IP/TCP>RA/Padding
IP/TCP>S==>Ether/IP/TCP>RA/Padding
IP/TCP>S==>Ether/IP/TCP>RA/Padding
如果对于应答数据包有速度限制,你可以通过inter参数来设置两个数据包之间等待的时间间隔。
如果有些数据包丢失了,或者设置时间间隔不足以满足要求,你可以重新发送所有无应答数据包。
你可以简单地对无应答数据包列表再调用一遍函数,或者去设置retry参数。
如果retry设置为3,scapy会对无应答的数据包重复发送三次。
如果retry设为-3,scapy则会一直发送无应答的数据包,直到。
timeout参数设置在最后一个数据包发出去之后的等待时间:
SYNScans
在Scapy提示符中执行一下命令,可以对经典的SYNScan初始化:
>>>sr1(IP(dst="")/TCP(dport=80,flags="S"))
以上向Google的80端口发送了一个SYN数据包,会在接收到一个应答后退出:
Beginemission:
.Finishedtosend1packets.
*
Received2packets,got1answers,remaining0packets
proto=TCPchksum=0x6a34src=dst=options=.....*.**.......Finishedtosend9packets.
**.*.*..*..................
Received362packets,got8answers,remaining1packets
>>>(
...lambda(s,r):
,
...("{TCP:
%%}{ICMP:
%%-%%}")))
-dest-unreachRA-
80SARASA
443SASASA
在以上的例子中,如果接收到作为响应的ICMP数据包而不是预期的TCP数据包,就会打印出ICMP差错类型(errortype)。
对于更大型的扫描,我们可能对某个响应感兴趣,下面的例子就只显示设置了"SA"标志位的数据包:
>>>(lfilter=lambda(s,r):
("%%")=="SA")
0003IP/TCP>S======>IP/TCP>SA
如果我们想对响应进行专业分析,我们可以使用使用以下的命令显示哪些端口是open的:
>>>(lfilter=lambda(s,r):
("%%")=="SA",prn=lambda(s,r):
("%%isopen"))
httpsisopen
对于更大型的扫描,我们可以建立一个端口开放表:
>>>(lambda(s,r):
TCPinrandr[TCP].flags&2).make_table(lambda(s,r):
...,,"X"))
X-X
443XXX
如果以上的方法还不够,Scapy还包含一个report_ports()函数,该函数不仅可以自动化SYNscan,而且还会对收集的结果以LaTeX形式输出:
>>>report_ports("",(440,443))
Beginemission:
...*.**Finishedtosend4packets.
*
Received8packets,got4answers,remaining0packets
'\\begin{tabular}{|r|l|l|}\n\\hline\nhttps&open&SA\\\\\n\\hline\n440
&closed&TCPRA\\\\\n441&closed&TCPRA\\\\\n442&closed&
TCPRA\\\\\n\\hline\n\\hline\n\\end{tabular}\n'
TCPtraceroute
TCP路由追踪:
>>>ans,unans=sr(IP(dst=target,ttl=(4,25),id=RandShort())/TCP(flags=0x2))
*****.******.*.***..*.**Finishedtosend22packets.
***......
Received33packets,got21answers,remaining1packets
>>>forsnd,rcvinans:
...print,,isinstance,TCP)
...
50
60
40
70
80
90
100
110
130
120
140
150
160
170
180
191
201
211
221
231
241
注意:
TCP路由跟踪和其他高级函数早已被构造好了:
>>>lsc()
sr:
Sendandreceivepacketsatlayer3
sr1:
Sendpacketsatlayer3andreturnonlythefirstanswer
srp:
Sendandreceivepacketsatlayer2
srp1:
Sendandreceivepacketsatlayer2andreturnonlythefirstanswer
srloop:
Sendapacketatlayer3inloopandprinttheanswereachtime
srploop:
Sendapacketatlayer2inloopandprinttheanswereachtime
sniff:
Sniffpackets
p0f:
PassiveOSfingerprinting:
whichOSemittedthisTCPSYN?
arpcachepoison:
Poisontarget'scachewith(yourMAC,victim'sIP)couple
send:
Sendpacketsatlayer3
sendp:
Sendpacketsatlayer