需求
用scapy解析每个层需要的数据
但是有一个问题是不支持http的,解决方法是安装scapy-http,具体效果请参考这里
实现完整代码:
#!/usr/bin/env python
try:
import scapy.all as scapy
except ImportError:
import scapy
try:
# This import works from the project directory
import scapy_http.http as http
except ImportError:
# If you installed this package via pip, you just need to execute this
from scapy.layers import http
import re
def processStr(data):
pattern = re.compile('^b\'(.*?)\'$', re.S)
res = re.findall(pattern, str(data))
final = re.split('\\\\r\\\\n', res[0])
return final
packets = scapy.sniff(iface='eth0', count=100)
for p in packets:
if 'TCP' in p:
print('=' * 78)
Ether_name = p.name
Ether_dst = p.dst
Ether_src = p.src
IP_name = p.payload.name
# IP_proto = p.payload.proto
IP_src = p.payload.src
IP_dst = p.payload.dst
print(Ether_name)
print('dst : ' + Ether_dst)
print('src : ' + Ether_src)
print(IP_name)
# print('protcol : ' + IP_proto)
print('src : ' + IP_src)
print('dst : ' + IP_dst)
if p.haslayer(http.HTTPRequest):
print("*********request******")
http_name = 'HTTP Request'
http_header = p[http.HTTPRequest].fields
headers = http_header['Headers']
items = processStr(headers)
for i in items:
print(i)
elif p.haslayer(http.HTTPResponse):
print("*********response******")
http_name = 'HTTP Response'
http_header = p[http.HTTPResponse].fields
headers = http_header['Headers']
items = processStr(headers)
for i in items:
print(i)
if 'Raw' in p:
load = p['Raw'].load
items = processStr(load)
for i in items:
print(i)
具体实现
得到数据
有两种方式,实时抓包,读取 pcap文件
实时抓包:利用sniff方法来实现
from scapy.all import *
packets = sniff(iface=eth0, count=100)
eth0是我想检测的网卡,你需要根据你的情况来换
读取文件:利用这个库中的 rdpcap()方法来实现
import scapy.all as scapy
packets = scapy.rdpcap(你的文件路径)
解析制定数据
大致思路,可以采用
for p in packets:
p.show()
来查看每个层的数据有那些属性可以取出,这里的p代表的是 ether层。
例如想要取出 ether层的dst属性 可以用p.dst
还有一个属性payload可以不断进下一个层
比如现在有四个层 Ether,IP,TCP,RAW
IP 可以表示为p.payload, 想要IP层的src可以用p.payload.src
但是这些表示方法只是在scapy库中,补充的那个库并虽然可以这样使用,
如果要取得http层的数据有些字段会不好取,像Agent-Encoding这个字段,就不好取,他会识别不出来,而且这么写代码太累。
具体怎么使用一开始我也有点难下手,后来看到了这篇博客,非常感谢
我这里是需要http层的request,response的所有headers的内容,如果response里面有返回的内容也要保存下来
- 存在问题
一开始我是想像这样上面那个博客一样,一个一个的取数据,但是这样有个问题,访问不同的网页有时候你定义的这个数据在这个返回内容里面可能是没有的,那它就没有这个定义的字段返回,那么你写的这个字段的值就会报错,说这个值不存在。
所以这条路行不通,后来看到他其实有把所有的headers放到的内容放到headers这个属性里面,所以我想到那这个属性会随着这个内容的不同而改变,可以用正则得到这部分的数据,然后按格式解析出来就不会有我刚刚说的问题了。
取得headers的内容后调用正则解析得到一个包含有header所有内容的list
实现如下:
def processStr(data):
pattern = re.compile('^b\'(.*?)\'$', re.S)
res = re.findall(pattern, str(data))
final = re.split('\\\\r\\\\n', res[0])
return final
遗留问题 :
现在基本已经达到我的需求,但是还有一个问题,所有返回的内容如果里面包含汉字,是以16进行的编码进行显示的,最好可以显示成汉字,我现在能想到的解决方法是利用编码函数给转一下就应该能解决,但是还没具体实现,实现了来更新。
大家有什么问题欢迎交流呀~,欢迎指正
参考
https://github.com/invernizzi/scapy-http
https://www.cnblogs.com/14061216chen/p/8093441.html
https://blog.csdn.net/yuberhu/article/details/64123516
http://fivezh.github.io/2016/05/31/Python-http-packet-parsing/