Python中的网络扫描大杀器Scapy初探

最近经历了Twisted的打击,这个网络编程实在看不懂,都摸不透它的内在逻辑,看来网络编程不是那么好弄的。还好,看到了scapy,这种网络的大杀器,让我一看就爱不释手,这才是我需要的网络工具啊。Scapy的功能如此之多,以至于。。。我到现在还是没看懂。在官方网站也介绍的不多,后来搜了一下,有一本书Security Power Tools一书中,第六章介绍了Scapy,虽然简单,但是还是不明白,这两天一直在忙活着看Scapy。看了几个应用,比较不错的有几个

1。扫描局域网内的客户机,将IP与MAC地址列出来

2。找DHCP服务器,列出IP与MAC地址

3。DNS解析

Scapy的强大之处就是它的自由度啊,可以自己封装一个网络包,然后发出去,包的内容自己定义,自由度太大了,现在才明白了OSI七层结构跟TCP/IP结构啊。真是受益匪浅。对包的结构涉及很深,对包的结构有很高的要求,反正我也看不懂,只是用来解决一些实际的问题。

Scapy的安装很简单,看官网的安装就可以

http://www.secdev.org/projects/scapy/doc/installation.html#installing-scapy-v2-x

安装完成后,先去下载一个OSI七层结构图,以作参考

2010073064658457

对照这张图,可以快速定位一些七层应用的底层协议,非常方便,因为Scapy就是按照这个结构组织包的

进入Scapy后,先记住两个常用的命令

ls()与lsc()

ls()是显示Scapy中的类与函数的

lsc()是显示Scapy中的方法,例如发3层包的方法send()与发送2层包的方法sendp()

非常有用

操作Scapy第一步是首先封装一个包,这个包可以自己选择在哪一层,具体可以使用ls()查看,例如,设置一个IP层的包,如果不做其它的设定,Scapy会按照默认值封装其它层的包

image

一个简单的TCP包

IP()/TCP()

>>> IP()/TCP()
<IP  frag=0 proto=tcp |<TCP  |>>

一个有效的TCP/IP包应该在IP层包括目标IP地址,那么可以这么设置

>>> a=IP()/TCP()
>>> a.dst
'127.0.0.1'
>>> a.dst='www.baidu.com'

在IP包设置完目的地址后,还需要在TCP包中的目的端口,否则是目的地的端口没有开,是不会返回应答包的,这就要涉及到TCP建立联系的三次握手,这三次握手分别是发送SYN,远端回复SYN-ACK,本地发送ACK,可以通过ls(TCP())来查看具体的标识

>>> TCP().show()
###[ TCP ]###
  sport= ftp_data
  dport= http
  seq= 0
  ack= 0
  dataofs= None
  reserved= 0
  flags= S
  window= 8192
  chksum= None
  urgptr= 0
  options= {}

查看这个包的目的端口

>>> a.dport
80

这是默认值,通过a.dport=num来设置

TCP可设置的东西很多,可以查看TCP包头的具体参数,在Scapy中,这个都有默认值。

建立好一个简单的包后,就需要发送了,发送的方法可以使用lsc()查看,一般发送用send(),发送接收用sr(),发送一次用sr1()

把建立好的包a发送出去,并接收目的地发送的返回包

>>> sr(a)
......Begin emission:
........Finished to send 1 packets.
...*
Received 18 packets, got 1 answers, remaining 0 packets
(<Results: TCP:1 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

结果分为两部分,一部分为发送的包与应答包,一部分为没有应答的包,所以在Scapy中,一般用

ans,unans分别调用不同的值,ans与unans都是自定义的变量,可以使用任何值

ans,unans=_ (_在python中代表上一次运行的结果,比较好用,是最近才发现的)

主要研究返回的包

>>> ans
<Results: TCP:1 UDP:0 ICMP:0 Other:0>

可以看出,返回了一个TCP包

>>> len(ans)
1

ans是以列表的形式返回的,所以可以使用标号来访问

>>> ans[0]
(<IP  frag=0 proto=tcp dst=61.135.169.125 |<TCP  |>>, <IP  version=4L ihl=5L tos=0x0 len=44 id=1 flags= frag=0L ttl=54 proto=tcp chksum=0xdbb6 src=61.135.169.125 dst=192.168.1.104 options=[] |<TCP  sport=http dport=ftp_data seq=2140061027 ack=1 dataofs=6L reserved=0L flags=SA window=8192 chksum=0x91be urgptr=0 options=[('MSS', 1440)] |<Padding  load='x00x00' |>>>)

这个包清晰的表明了层次结构,最左面的是IP包,<IP frag=0 proto=tcp dst=61.135.169.125 |<TCP |>>

逗号后面的是TCP包,就到TCP层,木有别的数据

光有这些不好用,如果scapy就这功能的话,还不如nmap好使,脚本比命令的最大优势就是对数据的操作能力,在python中,返回的可都是对象。所以可以对返回的结果进行筛选,还记得TCP()所显示的内容么?里面可都是对象的属性,例如TCP的窗口windows,要是显示的话,可以这么做

>>> ans[0][1][TCP]
<TCP  sport=http dport=ftp_data seq=2140061027 ack=1 dataofs=6L reserved=0L flags=SA window=8192 chksum=0x91be urgptr=0 options=[('MSS', 1440)] |<Padding  load='x00x00' |>>
>>> ans[0][1][TCP].window
8192

都是层次化的结构,可是这些包并不是固定的数据结构,如果TCP包很多(这很正常),那么如何去定位呢?

这就要用到scapy里面有用的工具sprintf()了,这个工具可以对包中的每个层的数据进行格式化,以层的名称与层的字段显示数据,要理解这个,先要看看ans对象的内容

在得到回答的包集合ans中,有两部分包,一个是发送的数据包,一个是收到的数据包,在python中,可以这么表示

for snd,rcv in ans:

如果只分析接收到的包,那么只要关注rcv就可以,snd是发送的包

res=rcv.sprintf(‘%IP.src%:%TCP.sport%’)

对于ans包含多个包的情况,最好建立空列表,在循环中,将生成的res附加到空列表中

collect=[]

collect.append(res)

在sprintd()中,%IP%是接收到的包rcv的IP层,%TCP%是rcv的TCP层,看rcv的结构就一目了然了

>>> ans[0][1]
<IP  version=4L ihl=5L tos=0x0 len=44 id=1 flags= frag=0L ttl=55 proto=tcp chksum=0xdaca src=61.135.169.105 dst=192.168.1.104 options=[] |<TCP  sport=http dport=ftp_data seq=3054601323 ack=1 dataofs=6L reserved=0L flags=SA window=8192 chksum=0x9447 urgptr=0 options=[('MSS', 1440)] |<Padding  load='x00x00' |>>>

那调用其中的字段,就直接用字段名就ok了,例如,需要返回的包rcv中,IP层的src字段,也就是远端服务器的IP地址,就用%IP.src%来表示,远端服务器的源端口就用sport来显示,综合起来就是

conf.verb=0 (这个找了半天,不知道干嘛用的,只是看到别人都是这么写的)

collect=[]

for snd,rcv in ans:

res=rcv.sprintf(‘%IP.src%:%TCP.sport%’)

collect.append(res)

这样就会只显示这个HTTP服务器的IP地址与端口号,非常的方便,这种方法还可以用在对局域网内的机器进行扫描,显示可以对ARP进行应答的机器IP地址与MAC地址,通过python的socket模块,还可以显示机器名,就相当于完成了局域网内的机器扫描。哇靠,非常简单

对接收包的数据检索,还有一种方法,个人感觉非常简洁,就是使用lambda表达式

ans.summary(lambda(s,r):r.sprinf(‘%IP.src%:%TCP.sport%’))

简洁的语句,非常喜欢

如果稍微改进一下,对生成的包进行定义,并定义IP()的src与dst,TCP()中的dport,对结果进行判断,就可以完成端口扫描的工作,特么的原来端口扫描就是这样

理解了这点,就可以做很多事情了,例如在网中有未经授权DHCP服务器,就可以找出它的MAC地址,进行追踪。准备写一下如何追踪DHCP,或者端口扫描。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值