前言
众所周知,我们每天上网都会有很多数据包需要发送,然后处理在接受在发送,这样一个循环往复的过程
这里就显示了很多数据包的发送接收数据,那什么是包呢?下面一起看看
包( packet )是网络通信传输中的数据单位,一般称之为数据包,其主要由源地址,目标地址,净载数据组成
它包括包头和包体,包头是固定长度,包体长度不变
简单了解下包的定义,下面我们来看看发包利器 scapy 的用法吧
一、常用命令
1、ls():显示所有支持的数据包对象,可带参数也可不带,参数可以是任意具体的包
可以看出,它包含了全部的内容,如果我们想详细查看某个模块中的内容,比如说我想查看 arp ,tcp 的话了,可以这样:
在这里要告诉大家的是,我们必须要注意大小写,ls(arp)这样才可以得出正确结果,ls(arp)是错误的。
2、lsc():列出所有函数
满屏的英文,我头都是大的,不知道大家此时此刻是什么样的心情,哈哈哈哈
3、hide_defaults():用来删除一些用户提供的那些和 default value 相同的项目
1
2
|
a = ip() print (a.hide_defaults()) |
4.display():可以简单查看当前 packet 的各个参数的取值情况,
1
2
|
a = ip() a.display() |
5.更多命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
命令 作用 show_interfaces() 显示网卡信息 str (pkt) 组装数据包 hexdump(pkt) 十六进制转储 ls(pkt) 显示出字段值的列表 pkt.summary() 一行摘要 pkt.show() 针对数据包的展开视图 pkt.show2() 显示聚合的数据包(例如,计算好了的校验和) pkt.sprintf() 用数据包字段填充格式字符串 pkt.decode_payload_as() 改变payload的decode方式 pkt.psdump() 绘制一个解释说明的postscript图表 pkt.pdfdump() 绘制一个解释说明的pdf pkt.command() 返回可以生成数据包的scapy命令 nsummary() 同上,但规定了数据包数量 conversations() 显示一个会话图表 filter () 返回一个 lambda 过滤后的数据包列表 hexdump() 返回所有数据包的一个hexdump import_hexcap() 将hexdump重新导入到scapy中 hexraw() 返回所有数据包raw layer的hexdump padding() 返回一个带填充的数据包的hexdump nzpadding() 返回一个具有非零填充的数据包的hexdump plot() 规划一个应用到数据包列表的 lambda 函数 make table() 根据 lambda 函数来显示表格 traceroute( "baidu.com" ) 查看ip路径的traceroute功能 export_object() 数据包转换成base64编码的python数据结构 import_object() 可以将输出重新导入 save_session() 保存所有的session变量 load_session() 读取保存的session fuzz() 更改一些默认的不被计算的值(比如校验和checksums),更改的值是随机的,但是是符合字段的值的。 |
二、嗅探数据包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
from scapy. all import * pkt = sniff(iface = "realtek pcie gbe family controller" ,count = 3 , filter = 'tcp' ,prn = lambda x: x.sprintf( '{ip:%ip.src%->%ip.dst%\n}{raw:%raw.load%\n}' )) filter :过滤条件 iface:网卡接口名称 count:数据包数量 prn:回调函数,通常与 lambda 搭配使用 sprintf()函数控制输入信息 抓取源地址为 192.168 . 3.3 的端口为 80 的tcp报文: sniff( filter = "ip src 192.168.3.3 and tcp and tcp port 80" , prn = lambda x:x.summary()) 抓取目的地址网段为 192.168 . 3.3 / 24 的报文: sniff( filter = "dst net 192.168" , prn = lambda x:x.summary()) 抓取非icmp的报文: sniff( filter = "not icmp" , prn = lambda x:x.summary()) 将抓取到的报文的summary打印出来: sniff( filter = "icmp" , prn = lambda x:x.summary(), count = 10 ) 将所有ip报文的源地址打印出来: sniff( filter = "icmp" , prn = lambda x:x[ip].src, count = 10 ) |
三、构造数据包
1
|
pkt = ether() / ip(dst = '192.168.1.2' ) / tcp(dport = 80 ) |
提到数据包,不得不说各个协议了,提到协议,又自然而然想到了 osi 七层模型
osi 七层网络模型 | tcp/ip 四层概念模型 | 对应网络协议 |
应用层(application) | 应用层 | http、tftp, ftp, nfs, wais、smtp |
表示层(presentation) | 应用层 | telnet, rlogin, snmp, gopher |
会话层(session) | 应用层 | smtp, dns |
传输层(transport) | 传输层 | tcp, udp |
网络层(network) | 网络层 | ip, icmp, arp, rarp, akp, uucp |
数据链路层(data link) | 数据链路层 | fddi, ethernet, arpanet, pdn, slip, ppp |
物理层(physical) | 数据链路层 | ieee 802.1a, ieee 802.2到ieee 802.11 |
以上便是各个网络协议对应的 osi 模型,那么各个协议的用法是怎样的了,下面我们一起来看下
四、各个协议用法
1、构造一个 ip 包,并传入一些参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#构造一个 ip 包,并传入一些参数 pkt = ip(dst = "192.168.1.2" ,ttl = 10 ) ls(pkt) version:版本号 ihl:头长度 tos:服务类型 len :ip数据包总长 id :标识符 flags:标记 flag:片偏移 ttl:生存时间 proto:协议类型 chksum:头部校验 src:源ip地址 dst:目的ip地址 options:可选项 |
2、构造arp包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#构造arp包 arp(op = 1 , hwdst = "ff:ff:ff:ff:ff:ff" , pdst = ip_address) #arp类的构造函数列表: ls(arp) hwtype : xshortfield = ( 1 ) 值为 1 表示以太网地址,其它还可能表示令牌环地址 ptype : xshortenumfield = ( 2048 ) 0x0800 表示ip地址,其它还可能是icmp / igmp hwlen : bytefield = ( 6 ) arp报文中,它的值为 6 plen : bytefield = ( 4 ) arp报文中,它的值为 4 op : shortenumfield = ( 1 ) 取值为 1 或者 2 ,代表arp请求或者响应包。 1.arp 请求, 2.arp 应答, 3.rarp 请求, 4.rarp 应答 hwsrc : arpsourcemacfield = (none) 发送方mac地址。 psrc : sourceipfield = (none) 发送方ip地址。 hwdst : macfield = ( '00:00:00:00:00:00' ) 目标mac地址。 pdst : ipfield = ( '0.0.0.0' ) 目标ip地址。 |
3、构造ether
1
2
3
4
5
6
7
|
#构造ether ether(dst = "ff:ff:ff:ff:ff:ff" ) ls(ether) dst : destmacfield = (none) 目的mac src : sourcemacfield = (none) 源mac type : xshortenumfield = ( 36864 ) 构造一个以太网数据包通常需要指定目标和源mac地址,如果不指定,默认发出的就是广播包ff:ff:ff:ff:ff:ff |
4、构造tcp包
1
2
3
4
5
6
7
8
9
10
11
12
|
#构造tcp包 sport : shortenumfield = 20 ( 20 ) 目标端口 dport : shortenumfield = 80 ( 80 ) 源端口 seq : intfield = 0 ( 0 ) ack : intfield = 0 ( 0 ) dataofs : bitfield ( 4 bits) = none (none) reserved : bitfield ( 3 bits) = 0 ( 0 ) flags : flagsfield ( 9 bits) = <flag 2 (s)> (<flag 2 (s)>) window : shortfield = 8192 ( 8192 ) chksum : xshortfield = none (none) urgptr : shortfield = 0 ( 0 ) options : tcpoptionsfield = [] (b'') |
五、发包,收包
可分为两种情况,用法如下:
1、只发不收
1
2
3
4
5
6
7
8
9
|
send(pkt, inter = 0 , loop = 0 , count = 1 , iface = n) pkt:数据包 inter:发包间隔时间 count:发包数量 iface:网卡接口名称 send(),在第三层发包,没有接收功能;send(ip(dst = "www.baidu.com" ,ttl = 2 ) / icmp()) sendp(),在第二层发包,没有接收功能。sr(ether() / ip(dst = www.baidu.com)) |
2、发包且收包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
sr()和sr1()都是在第三层发包,sr1表示只接收第一个回复。 sr(ip(dst = "www.baidu.com" ,ttl = ( 1 , 4 )) / tcp(dport = [ 21 , 23 , 80 ],flags = "s" )) 返回两个值 sr1(ip(dst = "www.baidu.com" ,ttl = ( 1 , 4 )) / icmp()) srloop(ip(dst = "www.baidu.com" ,ttl = 1 ) / icmp()) #不停的ping百度 srloop(ip(dst = "www.baidu.com" ,ttl = 1 ) / icmp(),inter = 3 ,count = 2 ) #每隔3秒ping一次,一共执行两次 #inter表示间隔,count记录次数 srp()和srp1()都是根据第二层发包,srp1表示只接收第一个回复 srp(ether() / ip(dst = "www.baidu.com" )) srp1(ether() / ip(dst = www.baidu.com)) |
六、syn半开式扫描
当 tcp 链接指定端口时,flags 参数设为 s 时则为半开式扫描,若此时该端口处于监听状态,返回 syn/ack,否则返回 rst/ack
1
|
sr1(ip(dst = "192.168.1.2" ) / tcp(dport = 80 ,flags = "s" )) |
七、数据包序列化,反序列化
序列化:将数据包对象保存为 pcap 文件
反序列化:读取 pcap 文件中的内容
1
2
3
4
5
6
7
|
pkt = ether() / ip(dst = '192.168.1.2' ) / tcp(dport = 80 ) #将嗅探到的数据包内容写到pcap文件中 wrpcap( "hw.pcap" ,pkt) #读取pcap文件。 read = rdpcap( 'hw.pcap' ) print (read[ 1 ]) #打印嗅探到的包的数据 |
八、数据包与字符串转换
更加直观清晰的分析数据。
1
2
|
zfc = str (pkts[ 0 ]) z = ether(zfc) |
九、导入导出 base64 编码
为了方便我们对数据进行加密而发明的一种方式
1
2
|
export_object( str (pkts[ 0 ])) 导出数据包 new_pkt = import_object() #将上一步导出的字符串填入 |
十、离线数据包的解析
如果我们捕获到数据包,未联网的情况下如何解析呢?
现在就可以使用我们的离线数据包分析数据了:
1
|
sniff(offline = "hw.pcap" ) #离线数据包 |
总结
通过上面的学习,我们对 scapy 算是有了一个基础性的认识了,scapy 的确很强大,简单的几行命令就能实现发包收包,极大的节省了我们的开发时间
如果你深入学习它的每个命令,你会发现更多有趣的事情,当然这么强大的工具可不要拿来做坏事哦!
以上就是python使用scapy模块发包收包的详细内容,更多关于python用scapy模块发包收包的资料请关注服务器之家其它相关文章!
原文链接:https://mp.weixin.qq.com/s/xsoGn21-uFh4Gq_Ct1kMxQ