python scapy 网络包管理工具--基础篇

来源:互联网 发布:php上传视频到七牛云 编辑:程序博客网 时间:2024/06/08 12:28

写在前面

scapy 是python的一个库,提供网络协议的构造,请求等
scrapy 是python的爬虫框架。

这两个差一个字母,大家还是要分清楚的。

因为涉及到发包等系统层面的操作,所以请保证具备root权限,这一点贯穿全文。

安装

博主使用的环境有
centos6、centos7、windows10

直接使用pip install scapy就可以安装

运行模式

你可以直接在命令行敲 scapy 进入交互模式
可以采用在py文件中运行。

交互模式

以linux下为例子,直接输入scapy

INFO: Can't import matplotlib. Won't be able to plot.INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().INFO: No IPv6 support in kernelWARNING: No route found for IPv6 destination :: (no default route?)INFO: Can't import python Crypto lib. Won't be able to decrypt WEP.INFO: Can't import python Crypto lib. Disabled certificate manipulation toolsINFO: Can't import python ecdsa lib. Disabled certificate manipulation tools

提示缺少库文件,以及IPv6的支持性问题。

这里基本功能用不到这些库,可以选择安装也可以暂时不用安装。

pip install matplotlib提示已经安装
pip install matplotlib --upgrade更新下,(更新的包比较多约30M,不先更新的可以跳过)
(别更新了,更新完还是提示不能使用plot,以及后面几个,即便安装了那个库还是提示不可用啦,巴拉巴拉。但是还好大部分是info,个别是warning.)


开始

>>> a=IP(ttl=10)>>> a< IP ttl=10 |>>>> a.src’127.0.0.1>>> a.dst="192.168.1.1">>> a< IP ttl=10 dst=192.168.1.1 |>>>> a.src’192.168.8.14>>> del(a.ttl)>>> a< IP dst=192.168.1.1 |>>>> a.ttl64

以上就是在IP造包的一些简单操作。
如果对IP协议的TTL不了解顺手看下 http://www.cnblogs.com/awpatp/archive/2010/05/27/1745883.html

构建多层数据包

如何加入TCP层信息,或者以太网信息呢?

>>> IP()<IP |>>>> IP()/TCP()<IP frag=0 proto=TCP |<TCP |>>>>> Ether()/IP()/TCP()<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>>>> Ether()/IP()/IP()/UDP()<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>>>> IP(proto=55)/TCP()<IP frag=0 proto=55 |<TCP |>>

不用觉得晕,这里只是说明,不同网络层级之间的连接用 “/”

这里我还试了下TCP()/IP() 。显然这是一个错误的层次,但是依然可以返回结果。说明,在构造包的时候你需要自己注意网络层次的分布。


>>> str(IP())'E\x00\x00\x14\x00\x01\x00\x00@\x00|\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01'>>> IP(_)<IP version=4L ihl=5L tos=0x0 len=20 id=1 flags= frag=0L ttl=64 proto=IP chksum=0x7ce7 src=127.0.0.1 dst=127.0.0.1 |>>>>  a=Ether()/IP(dst="www.slashdot.org")/TCP()/"GET /index.html HTTP/1.0 \n\n">>>  hexdump(a)00 02 15 37 A2 44 00 AE F3 52 AA D1 08 00 45 00  ...7.D...R....E.00 43 00 01 00 00 40 06 78 3C C0 A8 05 15 42 23  .C....@.x<....B#FA 97 00 14 00 50 00 00 00 00 00 00 00 00 50 02  .....P........P.20 00 BB 39 00 00 47 45 54 20 2F 69 6E 64 65 78   ..9..GET /index2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A  .html HTTP/1.0 .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 /index.html HTTP/1.0 \n\n'>>> c=Ether(b)>>> c<Ether dst=00:02:15:37:a2:44 src=00:ae:f3:52:aa:d1 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=67 id=1 flags= frag=0L ttl=64 proto=TCP chksum=0x783c src=192.168.5.21 dst=66.35.250.151 options='' |<TCP sport=20 dport=80 seq=0L ack=0L dataofs=5L reserved=0L flags=S window=8192 chksum=0xbb39 urgptr=0 options=[] |<Raw load='GET /index.html HTTP/1.0 \n\n' |>>>>

不要被以上一长串的返回值所吓到。划重点一下
1.str(IP()), IP(_) 可以查看IP协议的首部信息
2.hexdump() 方法可以16进制显示数据报,类似wireshark中一样


构造多个数据包

>>> a=IP(dst="www.slashdot.org/30")>>> a<IP  dst=Net('www.slashdot.org/30') |>>>> [p for p in a][<IP dst=66.35.250.148 |>, <IP dst=66.35.250.149 |>, <IP dst=66.35.250.150 |>, <IP dst=66.35.250.151 |>]>>> b=IP(ttl=[1,2,(5,9)])>>> b<IP ttl=[1, 2, (5, 9)] |>>>> [p for p in b][<IP ttl=1 |>, <IP ttl=2 |>, <IP ttl=5 |>, <IP ttl=6 |>, <IP ttl=7 |>, <IP ttl=8 |>, <IP ttl=9 |>]>>> c=TCP(dport=[80,443])>>> [p for p in a/c][<IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=80 |>>, <IP frag=0 proto=TCP dst=66.35.250.148 |<TCP dport=443 |>>, <IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=80 |>>, <IP frag=0 proto=TCP dst=66.35.250.149 |<TCP dport=443 |>>, <IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=80 |>>, <IP frag=0 proto=TCP dst=66.35.250.150 |<TCP dport=443 |>>, <IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=80 |>>, <IP frag=0 proto=TCP dst=66.35.250.151 |<TCP dport=443 |>>]

这里需要你对子网掩码了解一下 http://blog.csdn.net/aerchi/article/details/39396423


发送包

讲完包的构造,我们接下来说说如何发送这些报文。

>>> send(IP(dst="1.2.3.4")/ICMP()).Sent 1 packets.>>> sendp(Ether()/IP(dst="1.2.3.4",ttl=(1,4)), iface="eth1")....Sent 4 packets.>>> sendp("I'm travelling on Ethernet", iface="eth1", loop=1, inter=0.2)................^CSent 16 packets.>>> sendp(rdpcap("/tmp/pcapfile")) # tcpreplay...........Sent 11 packets.Returns packets sent by send()>>> send(IP(dst='127.0.0.1'), return_packets=True).Sent 1 packets.<PacketList: TCP:0 UDP:0 ICMP:0 Other:1>

send()在第三层发包。
sendp() 在第二层发包。

这里很多教程都有提及,说实话,这个我的理解也不是很深入。

你只要知道第一层是链路层。sendp()更靠近底层。