python中scapy模块的基础应用

scapy是一个可用于网络嗅探的非常强大的第三方库

1.交互模式,可做第三方库
2.可以用来做packet嗅探和伪造packet
3.已经在内部实现了大量的网络协议.(DNS,ARP,TCP,UDP等等) 编写非常灵活实用的工具

该博客借鉴Scapy官方文档的中文翻译版 附上下载地址
https://legacy.gitbook.com/book/wizardforcel/scapy-docs/details

安装Scapy

在命令行输入以下命令

pip install scapy
pip install ipython#该模块可以让交互环境更加友好

注意 windows下安装scapy需要安装winpcap或者是npcap.

运行Scapy

Scapy的交互shell是运行在一个终端会话中.
在Linux中,需要root权限才能发送数据包,所以在这里必须使用sudo

$ sudo scapy
Welcome to Scapy(2.4.2-dev)

在Windows中,使用管理员权限打开命令提示符(cmd.exe):
输入scapy可以看到如下结果.
在这里插入图片描述
有警告信息是因为没有安装所有的可选包,Scapy会告诉有哪些功能不可用.

注:可以在交互环境下输入 show_interfaces() 来查看本机的网卡名称

嗅探流量包

sniff函数

使用sniff函数进行嗅探流量,

>>> pkts = sniff(count = 10)
>>> pkts
<Sniffed: TCP:8 UDP:1 ICMP:0 Other:1>

这条命令是使用默认的网卡嗅探10 个包,结果得到八个TCP一个UDP包,以及一个其他类型包.
使用pkts[i]来查看具体的包的内容.
在这里插入图片描述

其中Ether为网络接口层数据,dst,src为目标MAC地址和源MAC地址.
IP为网络层的数据,可以得到使用的协议,源IP地址目标IP地址,TTL的值等.
UDP为运输层数据,可以得到源端口目的端口等信息.
Raw为应用层信息,其中含有要发送的数据

.show()可以更加详细的看到数据
show()
summary()可以看到大概的有标识信息的信息.

>>> pkts[1].summary()
'Ether / IP / TCP 10.245.3.203:52021 > 222.22.29.94:https PA / Raw'

Sniff的参数

各参数的含义:
iface表示使用的网卡接口,如果没有指定则会在所有的interface上进行嗅探(在交互环境输入show_interfaces()可以查看所有的网卡)
count是嗅探包的个数
filter是过滤条件
prn是回调函数,通常与lambda搭配使用
sprintf()函数控制输入信息

参数的使用

filter过滤包

演示:

>>> a = sniff(filter = 'tcp and (port 25 or port 110)',prn = lambda x: x.sprintf('%IP.src%:%TCP.sport% -> %IP.dst%:%TCP.dport%  %2s,TCP.flags% : %TCP.payload%))

这条语句的含义是,筛选协议为tcp并且端口为25或者是110的的packet,并且按照给定的格式输出.

写入与读取

PCAP

使用wrpacp和rdpcap可以将嗅探到的packet内容写入到pcap文件和读取pacp文件中.其他抓包软件也可以打开.

#写入
wrpacp('demo.pacp',pkts)

#读取
read_pkts = rdpacp('demo.pcap')
read_pkts
>>> <demo.pcap:TCP:3 UDP:5 ICMP:0 Other:0>

Hexdump

Scapy允许以不同的十六进制格式输出编码的数据包
使用**hexdump()**函数可以以经典的hexdump格式(十六进制)输出数据包.
使用import_hexcap()函数可以将hexdump格式重新导入到Scapy中

Hex string

使用str()函数可以将整个数据包转换成十六进制字符串.

>>> pkts = sniff(count = 3)
>>> pkt = pkts[0]
>>> pkt
<Ether  dst=ff:ff:ff:ff:ff:ff src=9c:b6:d0:07:df:83 type=0x800 |<IP  version=4 ihl=5 tos=0x0 len=291 id=24335 flags= frag=0 ttl=64 proto=udp chksum=0xf31f src=10.101.2.211 dst=10.101.15.255 |<UDP  sport=54915 dport=54915 len=271 chksum=0xb702 |<Raw  load="\x00USER-QO5VP7A5TA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000o\r\x02\x00\x00\x00\x00\x90\xbb\xfc\x06\x00\x00\x00\x003'\x00\x00\x00\x00\x00\x00 o\r\x02\x00\x00\x00\x00\xd0xK\x05\x00\x00\x00\x00|j'n\x00\x00\x00\x00\xc8\xa5\xdan\x00\x00\x00\x00\xb9\xbf\xfc\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80^\x0f\x05\x00\x00\x00\x00\x04\xbc\xfc\x06\x00\x00\x00\x00 \xbc\xfc\x06\x00\x00\x00\x00\x08/\x80{627f3fa9-86ea-4076-bd57-9deaef085603}\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xfc\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x90\xcdF" |>>>>
>>> str(pkt)
'b"\\xff\\xff\\xff\\xff\\xff\\xff\\x9c\\xb6\\xd0\\x07\\xdf\\x83\\x08\\x00E\\x00\\x01#_\\x0f\\x00\\x00@\\x11\\xf3\\x1f\\ne\\x02\\xd3\\ne\\x0f\\xff\\xd6\\x83\\xd6\\x83\\x01\\x0f\\xb7\\x02\\x00USER-QO5VP7A5TA\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x000o\\r\\x02\\x00\\x00\\x00\\x00\\x90\\xbb\\xfc\\x06\\x00\\x00\\x00\\x003\'\\x00\\x00\\x00\\x00\\x00\\x00 o\\r\\x02\\x00\\x00\\x00\\x00\\xd0xK\\x05\\x00\\x00\\x00\\x00|j\'n\\x00\\x00\\x00\\x00\\xc8\\xa5\\xdan\\x00\\x00\\x00\\x00\\xb9\\xbf\\xfc\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x80^\\x0f\\x05\\x00\\x00\\x00\\x00\\x04\\xbc\\xfc\\x06\\x00\\x00\\x00\\x00 \\xbc\\xfc\\x06\\x00\\x00\\x00\\x00\\x08/\\x80{627f3fa9-86ea-4076-bd57-9deaef085603}\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xbc\\xfc\\x06\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xf0\\x90\\xcdF"'

Base64

export_object() 函数:
Scapy可以将数据包转换为base64编码的Python数据结构

>>> pkt
<Ether  dst=ff:ff:ff:ff:ff:ff src=9c:b6:d0:07:df:83 type=0x800 |<IP  version=4 ihl=5 tos=0x0 len=291 id=24335 flags= frag=0 ttl=64 proto=udp chksum=0xf31f src=10.101.2.211 dst=10.101.15.255 |<UDP  sport=54915 dport=54915 len=271 chksum=0xb702 |<Raw  load="\x00USER-QO5VP7A5TA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000o\r\x02\x00\x00\x00\x00\x90\xbb\xfc\x06\x00\x00\x00\x003'\x00\x00\x00\x00\x00\x00 o\r\x02\x00\x00\x00\x00\xd0xK\x05\x00\x00\x00\x00|j'n\x00\x00\x00\x00\xc8\xa5\xdan\x00\x00\x00\x00\xb9\xbf\xfc\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80^\x0f\x05\x00\x00\x00\x00\x04\xbc\xfc\x06\x00\x00\x00\x00 \xbc\xfc\x06\x00\x00\x00\x00\x08/\x80{627f3fa9-86ea-4076-bd57-9deaef085603}\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xfc\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x90\xcdF" |>>>>
>>> export_object(pkt)
b'eNprYEouTk4sqNTLSaxMLSrWyzHici3JSC3iKmTQDCpkTI5Pzk9JTS7mSs0DMbgKmSIiGRkYDu9HwENzDm07PIH98PxDzRwMrgyMyvH8DAwOgoc3y3OlMh2ezJXKD1Q17VAzCDPyH9rOxBAa7BqkG+hvGhZg7mga4siABgzyeZlA9KEJh3Yf3sMGYhqrQ6QUoFKHJ1R4s4IYNVnqeWCBjkNLD88CMw/tPLQfqg0GDjXE8YOVsxzaA5VSgLM49A81VJsZmacZpyVa6lqYpSbqmhiYm+kmpZia61qmpCamphlYmJoZGNdCTWOEG7sHzR4KwOENhyYc7nUrZI4AmZiTWJKZZ1jI0lbIGlTI1lrInqQHAGGUZtg='

Sessions

可以使用save_session()函数保存所有的session变量

>>>	dir() 
['__builtins__',	'conf',	'new_pkt',	'pkt',	'pkt_export',	'pkt_he x',	'pkt_str',	'pkts']
>>>	save_session("session.scapy")

使用load_session()函数,在下一次启动Scapy的时候就能加载保存的session

>>>	dir() 
['__builtins__',	'conf'] 
>>>	load_session("session.scapy") 
>>>	dir() 
['__builtins__',	'conf',	'new_pkt',	'pkt',	'pkt_export',	'pkt_he x',	'pkt_str',	'pkts']

创建数据包

简单的数据包

第一步,建立一个简单的数据包

>>> a = IP(ttl = 10)
>>> a
<IP  ttl=10 |>
>>> a.src
'10.245.3.203'
>>> a.dst = '119.75.217.26'
>>> a
<IP  ttl=10 dst=119.75.217.26 |>
>>> del(a.ttl)
>>> a
<IP  dst=119.75.217.26 |>
>>> a.ttl
64

增加层次之后的数据包(OSI参考模型)

’ / ’ 操作符在两层之间起到一个组合的作用.当使用该操作符的时候,下层可以根据其上层,使它的一个或多个默认字段被重载,但还是可以赋予你想要的值.

>>> 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' |>>>
>>> IP(proto=55)/TCP()
<IP  frag=0 proto=55 |<TCP  |>>

每一个数据包都可以被建立或者是分解

>>> a = Ether()/IP(dst='www.baidu.com')/TCP()/'GET /index.html HTTP/1.0 \n\n'
>>> hexdump(a)
0000  7C 1E 06 24 40 DB A4 02 B9 B4 D4 3A 08 00 45 00  |..$@......:..E.
0010  00 43 00 01 00 00 40 06 20 1A 0A F5 03 CB DC B5  .C....@. .......
0020  6F 25 00 14 00 50 00 00 00 00 00 00 00 00 50 02  o%...P........P.
0030  20 00 63 17 00 00 47 45 54 20 2F 69 6E 64 65 78   .c...GET /index
0040  2E 68 74 6D 6C 20 48 54 54 50 2F 31 2E 30 20 0A  .html HTTP/1.0 .
0050  0A
>>> b = str(a)
>>> b
"b'|\\x1e\\x06$@\\xdb\\xa4\\x02\\xb9\\xb4\\xd4:\\x08\\x00E\\x00\\x00C\\x00\\x01\\x00\\x00@\\x06 \\x1a\\n\\xf5\\x03\\xcb\\xdc\\xb5o%\\x00\\x14\\x00P\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00P\\x02 \\x00c\\x17\\x00\\x00GET /index.html HTTP/1.0 \\n\\n'"
>>> d = IP(a)
>>> d
<IP  version=7 ihl=12 tos=0x1e len=1572 id=16603 flags=MF+evil frag=1026 ttl=185 proto=180 chksum=0xd43a src=8.0.69.0 dst=0.67.0.1 options=[<IPOption_EOL  copy_flag=0 optclass=control option=end_of_list |>, <IPOption_EOL  copy_flag=0 optclass=control option=end_of_list |>, <IPOption_EOL  copy_flag=0 optclass=debug option=end_of_list |>, <IPOption  copy_flag=0 optclass=control option=commercial_security length=32 value='\x1a\n\xf5\x03\xcb\xdc\xb5o%\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02' |>] |<Raw  load=' \x00c\x17\x00\x00GET /index.html HTTP/1.0 \n\n' |>>

以下是一些常用的命令

命令效果
str(pkt)组装数据包
hexdump(pkt)十六进制转储
Is(pkt)显示出字段值的列表
pkt.summary()一行摘要
pkt.show()针对数据包的展开
pkt.show2()显示聚合的数据包
pkt.decode_payload_as()改变decode方式
pkt.psdump()绘制一个解释说明的PostScript图表
pkt.pdfdump()绘制一个解释说明的PDF
pkt.command()返回可以生成数据包的Scapy的命令

生成一组数据包

轻易的定制一组数据包:整个数据包的每一个字段都可以是一组,可以使用所有区域之间的笛卡尔积来生成一组数据包.

>>> a = IP(dst = '10.245.3.203/30')
>>> [p for p in a]
[<IP  dst=10.245.3.200 |>,
 <IP  dst=10.245.3.201 |>,
 <IP  dst=10.245.3.202 |>,
 <IP  dst=10.245.3.203 |>]
>>> 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=10.245.3.200 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.200 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.201 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.201 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.202 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.202 |<TCP  dport=https |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.203 |<TCP  dport=http |>>,
 <IP  frag=0 proto=tcp dst=10.245.3.203 |<TCP  dport=https |>>]

发送数据包

send()和sendp()函数

send() 函数将会在第3层发送数据包,会处理路由和第二层的数据.
sendp() 函数将会工作在第2层,可以自主的选择合适的接口和正确的链路协议.
send()和sendp()只是发送,并没有接受

sr 发送和接收数据包

sr() 函数是用来发送数据包和接受应答.该函数返回一对数据包及其应答,还有无应答的数据包
sr1() 函数是一种变体,用来返回一个应答数据包,发送的数据包必须是第3层报文(IP,ARP等)
srp() 则是使用第2层报文(以太网,802.3等)

以下例子是通过发送arp请求包来查看某一个IP或者是网段的存活情况,但是必须是与主机IP在同一个局域网内.

from scapy.all import srp, Ether, ARP
IpScan = input('请输入IP:')
print("扫描中,请稍候...")
ans,unans = srp(Ether(dst="FF:FF:FF:FF:FF:FF")/ARP(pdst=IpScan),timeout=2,verbose=0,iface="Intel(R) Dual Band Wireless-AC 7265")
#verbose 不说明下载的形况
print("本次扫描一共扫描到%d台主机:" % len(ans))
for send,recv in ans:
    print("%s----%s"%(recv.src,recv.psrc))

在Python程序中使用Scapy

导入Scapy

使用

from scapy.all import *

在import后加入所需要的功能即可
例子: 传入一个IP或者是一个主机名作为参数,发送一个ICMP响应请求,然后显示返回包完整的构造.

import	sys 
from	scapy.all	import	sr1,IP,ICMP
p=sr1(IP(dst=sys.argv[1])/ICMP()) 
if	p:				
	p.show()

注: sys模块中的sys.argv[1]用法可以在命令行中得到你想传入的参数
如:

scapy.py 127.0.0.1

sys.argv[1]就等于 127.0.0.1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值