做公司网站别人能看到吗,北京值得去的商场,html个人网页源码,创建网站数据库背景#xff1a;
常见的抓包工具有tcpdump和wireshark#xff0c;二者可基于网卡进行抓包#xff1a;tcpdump用于Linux环境抓包#xff0c;而wireshark用于windows环境。抓包后需借助包分析工具对数据进行解析#xff0c;将不可读的二进制数转换为可读的数据结构。 wires…背景
常见的抓包工具有tcpdump和wireshark二者可基于网卡进行抓包tcpdump用于Linux环境抓包而wireshark用于windows环境。抓包后需借助包分析工具对数据进行解析将不可读的二进制数转换为可读的数据结构。 wireshark不仅可以作为抓包工具还可以作为包解析工具。Wireshark针对常见协议都提供了对应的解析插件 如: TCP、UDP、HTTP、SIP等同时提供了自定义插件机制用户可以基于此解析自定义消息。至于插件wireshark支持C语言插件和Lua插件Lua作为脚本不需要编译方便调试速度相对C语言较慢。由于抓包时可以根据条件过滤且一般数据包分析在本地进行这部分性能优势相对于Lua脚本的方便性可以忽略。 因此本文的主体内容是介绍如何在Wireshark中开发自定义插件解析消息。
1.插件配置方式
1.1 配置protobuf加载路径
根据Wireshark-Preferences-Protocols路径进入配置页面(Windows中路径为 “编辑-首选项-Protocols” ): 勾选Load .proto files on startup选项然后点击Edit按钮开始配置。添加proto文件所在文件夹勾选load all files选项。 经过上述配置已经为wireshark指定了查找proto文件的路径后续在lua脚本中可直接使用proto文件。
1.2 配置lua脚本路径
根据Wireshark-About Wireshark-Folders路径进入配置页面(windows下路径为: 帮助-关于-文件夹): 添加或者查看个人Lua插件的存放位置后面开发的插件需要存放到这个路径下才会生效。添加或者修改lua插件后需要重新加载lua插件:分析-重新载入Lua插件或者通过快捷键CtrlShiftL.
1.3 Lua console调试工具
在Tools-Lua console页面可以编写和执行Lua脚本可用于调试: 说明调试工具是开发Lua插件的关键结合快捷键CtrlShiftL通过打印提示信息可以快速定位和发现问题。
2.wireshark关于Lua API介绍 Lua语法请参考: Lua使用方式介绍 Lua API参考自: https://mika-s.github.io/wireshark/lua/dissector/2017/11/04/creating-a-wireshark-dissector-in-lua-1.html 这部分介绍wireshark为Lua脚本的API以及根据如何使用这些API实现自定义Lua插件。介绍Lua API前有必要对Wireshark页面进行介绍:
需要关注上图红色标注的区域包括:column区、tree区、data区后续API会操作这些区域。
2.1 定义协议
seong_protocol Proto(seong, seong description)seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);
endDissectorTable.get(tcp.port):add(9003, seong_protocol)将上述Lua插件注册到环境后可使用自定义的seong协议过滤消息Wireshark页面显示如下 定义协议需要三个步骤定义Proto协议对象为Proto对象添加解码器方法将Proto对象与对应的端口进行绑定。 [1] 定义协议对象
seong_protocol Proto(seong, seong description)Proto作为构造参数用于创建Proto对象接收两个参数协议名称和协议描述。
[2] 为协议对象添加解析器 解析器函数:
seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);
end函数包括三个入参 (1) buffer为二进制消息数据可以通过类似buffer(0,2)方式从消息中截取字节数组 (2) pinfo为数据包的元数据对象包括消息大小、源地址/目标地址、大小、时间戳等信息 (3) tree为协议树节点对象数据结构会被渲染在tree区。
tree.add方法 解析器内部的tree:add(seong_protocol, buffer(),Seong Message Data)功能是: 在tree区域添加一个子树(并返回子树的引用)。其中第一个参数是必选的后面两个参数是可选的 (1) 协议参数 tree区域中每层协议对应一个子树即每个子tree需要与指定的协议绑定此时需要为seong协议创建一个子树:
local subtree tree:add(seong_protocol, nil, nil);后续通过操作subtree对象为seong协议子树添加显示数据。
(2) 数据参数 当传递为nil和buffer或者buffer(0,2) 时鼠标选中seong协议时关联的data区域不同: (3) 描述信息 当描述信息为nil时wireshark会选择使用协议的描述信息展示。
[3] 将协议与端口绑定 将协议与端口绑定后Wireshark会自动将该端口上的消息使用绑定的协议解析:
DissectorTable.get(tcp.port):add(9003, seong_protocol)此时TCP协议的9003端口的消息使用seong插件解析。
2.2 修改Column区
在过滤窗口通过seong过滤后可以得到TCP-9003端口的消息显示的Protocol协议仍未TCP应该修改为seong. 在解析器内部添加语句pinfo.columns.protocol:set(seong_protocol.name),得到:
seong_protocol Proto(seong, seong description)seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);pinfo.columns.protocol:set(seong_protocol.name);
endDissectorTable.get(tcp.port):add(9003, seong_protocol)Wireshark显示为: 消息的协议名称修改为了seong. 除了protocol外还可以通过pinfo.columns对象修改columns区域的其他字段的内容, 如修改info消息: pinfo.columns.info:set(此时充值VIP可观看);
2.3 修改Tree区
Tree区为重点区域自定义插件的核心功能是为了在这个区域直观地展示消息的内容。解析器的重点职责是从二进制数据中解析消息并将消息作为字段添加到tree上从而在Tree区域展示。 以下结合两种方式其中通过Proto对象的fields属性方式是官方文档的推荐方式直接操作tree对象方式是个人探索所得相对比较简单(可能有坑)。
2.3.1 Proto对象的fields属性方式
先给出案例:
seong_protocol Proto(seong, seong description)message_length ProtoField.int32(message_length, Message-Length, base.DEC)
seong_protocol.fields {message_length}seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);pinfo.columns.protocol:set(seong_protocol.name);subtree:add(message_length, 123456)
endDissectorTable.get(tcp.port):add(9003, seong_protocol)与之前的lua脚本区域在于新增了Proto.fields相关的逻辑: [1] 声明字段类型 message_length ProtoField.int32(“message_length”, “Message-Length”, base.DEC) 创建一个属性属性名称为message_length描述为Message-Length(显示使用) 为十进制的整数。 [2] 字段添加到协议对象中
seong_protocol.fields {message_length}[3] 为message_length赋值并添加到tree中
subtree:add(message_length, 123456)此时, wireshark显示如下:
2.3.2 直接操作tree对象
通过subtree:add(字符串)方法直接将字符串设置到tree对象上:
seong_protocol Proto(seong, seong description)seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);pinfo.columns.protocol:set(seong_protocol.name);subtree:add(Message-Length: .. 11223344)
endDissectorTable.get(tcp.port):add(9003, seong_protocol)2.3.3 简单案例
假设消息中前两个字节表示有效的数据长度
seong_protocol Proto(seong, seong description)seong_protocol.dissector function(buffer, pinfo, tree)local subtree tree:add(seong_protocol, buffer(),Seong Message Data);pinfo.columns.protocol:set(seong_protocol.name);subtree:add(Message-Length: .. buffer(0,2))
endDissectorTable.get(tcp.port):add(9003, seong_protocol)其中buffer(0,2)从二进制消息中提取前两个字节; subtree:add方法调用时可以关联data区域 subtree:add(Message-Length: .. buffer(0,2)) 修改为 subtree:add(buffer(0,2), Message-Length: .. buffer(0,2)): 显示如下:
3.案例
3.1 protobuf文件准备
Person.proto文件:
syntax proto2;option java_package com.seong;option java_outer_classname TestProtoMsg;message Person {required int32 id 1;required string name 2;required bool isMale 3;repeated Address address 4;
};message Address {required string country 1;optional string location 2;
};编译后生成com.seong.TestProtoMsg类内部有Person和Address两个内部类生成的Java类将在服务端和客户端程序中使用。然后将Person.proto文件放到1.1章节中配置的protobuf加载路径下。
3.2 Java服务端和客户端单例
使用Netty构建一个服务端(监听端口为9999)与客户端, 二者之间通过TCP-Protobuf通信消息格式如下: 首部固定为AAAA(2字节)消息大类为BB(1字节), 消息子类为CC(1字节)消息长度表示PB消息体的长度(2字节)PB消息内容为5.1中Person.proto文件的protobuf消息。 关于Netty相关代码这里不进行介绍请参考IO系列-netty相关的文章。 客户端:
(1) 客户端Netty模板代码:
public class Application {public static void main(String[] args) throws Exception {new Application().start();}public void start() throws Exception {EventLoopGroup group new NioEventLoopGroup();try {Bootstrap b new Bootstrap();b.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializerSocketChannel() {Overrideprotected void initChannel(SocketChannel ch) {ch.pipeline().addLast(new PersonProtoBufEncoder());}});ChannelFuture f b.connect(localhost, 9999).sync();f.channel().writeAndFlush(buildPersonMsg());f.channel().closeFuture().sync();} finally {group.shutdownGracefully();}}
}(2) 构造消息: 根据PB定义构造案例消息
private TestProtoMsg.Person buildPersonMsg() {TestProtoMsg.Person.Builder personBuilder TestProtoMsg.Person.newBuilder();personBuilder.setId(1960001001);personBuilder.setName(ue001);personBuilder.setIsMale(false);TestProtoMsg.Address.Builder addressBuilder TestProtoMsg.Address.newBuilder();addressBuilder.setCountry(zh-CN);addressBuilder.setLocation(NanJing);personBuilder.addAddress(addressBuilder.build());return personBuilder.setId(1).build();
}(3) Protobuf编码器:将TestProtoMsg.Person对象编码为二进制数据然后发送给服务端
public class PersonProtoBufEncoder extends MessageToByteEncoderTestProtoMsg.Person {private static final int TYPE 4;private static final int LENGTH 4;Overrideprotected void encode(ChannelHandlerContext ctx, TestProtoMsg.Person person, ByteBuf byteBuf) {byte[] playLoadBytes person.toByteArray();int playLoadLen playLoadBytes.length;ByteBuf msgBuffer Unpooled.buffer(TYPE LENGTH playLoadLen);msgBuffer.writeBytes(new byte[] {(byte)0xAA, (byte)0xAA});msgBuffer.writeBytes(new byte[] {(byte)0xBB, (byte)0xCC});msgBuffer.writeInt(playLoadLen);msgBuffer.writeBytes(playLoadBytes);byteBuf.writeBytes(msgBuffer);}
}服务端:
(1) 服务端Netty模板代码:
public class Application {public static void main(String[] args) throws Exception {new Application().start(9999);}public void start(int port) throws Exception {EventLoopGroup bossGroup new NioEventLoopGroup();EventLoopGroup workerGroup new NioEventLoopGroup();try {ServerBootstrap b new ServerBootstrap();b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializerSocketChannel() {Overridepublic void initChannel(SocketChannel ch) {ch.pipeline().addLast(new PersonProtoBufDecoder());ch.pipeline().addLast(new PersonProtoServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);ChannelFuture f b.bind(port).sync();f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}
}(2) 解码器: 将来自客户端的二进制数据解码为TestProtoMsg.Person对象
public class PersonProtoBufDecoder extends ByteToMessageDecoder {private static final int TYPE_HEAD 4;private static final int LENGTH_HEAD 4;private static final int HEAD_LEN TYPE_HEAD LENGTH_HEAD;Overrideprotected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, ListObject list) throws Exception {byte[] msgBytes new byte[byteBuf.readableBytes()];byteBuf.readBytes(msgBytes);int msgLen msgBytes.length;if (msgLen HEAD_LEN) {return;}byte[] bodyMsg new byte[msgLen - HEAD_LEN];System.arraycopy(msgBytes, HEAD_LEN, bodyMsg, 0, msgLen - HEAD_LEN);TestProtoMsg.Person person TestProtoMsg.Person.parseFrom(bodyMsg);list.add(person);}
}(3) 解码后的消息处理: 打印TestProtoMsg.Person对象
Slf4j
public class PersonProtoServerHandler extends ChannelInboundHandlerAdapter {Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {if (!(msg instanceof TestProtoMsg.Person)) {ctx.fireChannelRead(msg);return;}LOGGER.info(Receive from client, msg is {}., msg);}
}运行结果如下所示:
17:17:42.874 [nioEventLoopGroup-3-1] INFO com.seong.PersonProtoServerHandler - Receive from client, msg is id: 1
name: ue001
isMale: false
address {country: zh-CNlocation: NanJing
}
.3.3 抓包分析
通过wireshark或者tcpdump可进行抓包这里对端口进行过滤(9999): 可以看到客户端与服务端的通信数据包已被获取为二进制数据没有可读性。
3.4 Lua脚本定义协议
-- 自定义协议Proto构造函数有两个参数名称和描述
seong_protocol Proto(seong, seong Message)
-- 添加一个字段用于在数据树中显示
message_length ProtoField.int32(seong.message_length, PB-Message-Length, base.DEC)
seong_protocol.fields {message_length}-- 自定义协议的解析器
seong_protocol.dissector function(buffer, pinfo, tree)-- 消息长度为0直接返回local length buffer:len();if length 0 then return end;-- 添加子树显示为Seong Message Datalocal subtree tree:add(seong_protocol, buffer(),Seong Message Data); -- 消息树中添加PB-Message-Length信息local msgLen buffer(4,4):uint()subtree:add(message_length, msgLen)-- 消息树中添加HEADMain-TypeSub-Type数据local headFlag .. buffer(0,2)local mainType .. buffer(2,1)local subType .. buffer(3,1)subtree:add(buffer(0,2),HEAD: .. headFlag)subtree:add(buffer(2,1),Main-Type: .. mainType)subtree:add(buffer(3,1),Sub-Type: .. subType)-- 调用wireshark内置的protobuf解析器sipProtoType Person;pinfo.private[pb_msg_type] message, .. sipProtoTypelocal protobuf_dissector Dissector.get(protobuf);local result pcall(Dissector.call, protobuf_dissector, buffer(8, msgLen):tvb(), pinfo, subtree)pinfo.columns.protocol:set(seong_protocol.name)
end--注册协议到指定的端口
local tcp_port DissectorTable.get(tcp.port):add(9999, seong_protocol)3.5 查看协议 此时二进制数据已经通过树区域进行了展示, 与服务端解码后的消息保持一致。
3.6 扩展
本文中涉及的protobuf文件只有一个实际上系统间的消息类型数以百计因此需要对上述Lua脚本进行扩展以具备更好的通用性。 注意到定义消息时添加了消息大类和消息子类两个冗余字段可通过这两个字段与protobuf之间建立映射关系即这两个消息确定了消息类型和解码方式。
local function matchedProtoType(mainType, subType)print(mainType: .. mainType .. subType: .. subType)if mainType bb thenif subType cc thenreturn Person;endelsereturn nilendreturn nil
end定义一个函数根据mainType和subType返回protobuf消息类型相应地Lua脚本中解析器的定义进行如下修改(将硬编码的Person类型改为通过matchedProtoType获取):
idslds_protocol.dissector function(buffer, pinfo, tree)-- ...--sipProtoType Person;sipProtoType matchedProtoType(mainType,subType)-- ...
end本文主要介绍如何在wireshark中介绍自定义Lua插件因此扩展这一部分不进行详细描述。后续在IO系列-Netty应用相关的文章中将介绍一个通过Netty实现子网穿越的案例之后结合该案例对Lua插件的应用进行完整的阐述。 文章转载自: http://www.morning.gpryk.cn.gov.cn.gpryk.cn http://www.morning.krjrb.cn.gov.cn.krjrb.cn http://www.morning.rlwgn.cn.gov.cn.rlwgn.cn http://www.morning.crtgd.cn.gov.cn.crtgd.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.hxgly.cn.gov.cn.hxgly.cn http://www.morning.bybhj.cn.gov.cn.bybhj.cn http://www.morning.hypng.cn.gov.cn.hypng.cn http://www.morning.qwzpd.cn.gov.cn.qwzpd.cn http://www.morning.krdmn.cn.gov.cn.krdmn.cn http://www.morning.glcgy.cn.gov.cn.glcgy.cn http://www.morning.xllrf.cn.gov.cn.xllrf.cn http://www.morning.wmqrn.cn.gov.cn.wmqrn.cn http://www.morning.fhyhr.cn.gov.cn.fhyhr.cn http://www.morning.wkwds.cn.gov.cn.wkwds.cn http://www.morning.hlnys.cn.gov.cn.hlnys.cn http://www.morning.jphxt.cn.gov.cn.jphxt.cn http://www.morning.hfbtt.cn.gov.cn.hfbtt.cn http://www.morning.qbpqw.cn.gov.cn.qbpqw.cn http://www.morning.lrmts.cn.gov.cn.lrmts.cn http://www.morning.rqrxh.cn.gov.cn.rqrxh.cn http://www.morning.qddtd.cn.gov.cn.qddtd.cn http://www.morning.nwcgj.cn.gov.cn.nwcgj.cn http://www.morning.hxxwq.cn.gov.cn.hxxwq.cn http://www.morning.smzr.cn.gov.cn.smzr.cn http://www.morning.txzmy.cn.gov.cn.txzmy.cn http://www.morning.tfbpz.cn.gov.cn.tfbpz.cn http://www.morning.ztqj.cn.gov.cn.ztqj.cn http://www.morning.qjdqj.cn.gov.cn.qjdqj.cn http://www.morning.pjqxk.cn.gov.cn.pjqxk.cn http://www.morning.mbfj.cn.gov.cn.mbfj.cn http://www.morning.srmdr.cn.gov.cn.srmdr.cn http://www.morning.dbfwq.cn.gov.cn.dbfwq.cn http://www.morning.nknt.cn.gov.cn.nknt.cn http://www.morning.mjglk.cn.gov.cn.mjglk.cn http://www.morning.xfcjs.cn.gov.cn.xfcjs.cn http://www.morning.gwzfj.cn.gov.cn.gwzfj.cn http://www.morning.qkgwx.cn.gov.cn.qkgwx.cn http://www.morning.rqqmd.cn.gov.cn.rqqmd.cn http://www.morning.drkk.cn.gov.cn.drkk.cn http://www.morning.jtqxs.cn.gov.cn.jtqxs.cn http://www.morning.wmdlp.cn.gov.cn.wmdlp.cn http://www.morning.tkzqw.cn.gov.cn.tkzqw.cn http://www.morning.jmllh.cn.gov.cn.jmllh.cn http://www.morning.sxjmz.cn.gov.cn.sxjmz.cn http://www.morning.rzscb.cn.gov.cn.rzscb.cn http://www.morning.pkwwq.cn.gov.cn.pkwwq.cn http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.jqpyq.cn.gov.cn.jqpyq.cn http://www.morning.lcdtb.cn.gov.cn.lcdtb.cn http://www.morning.zckhn.cn.gov.cn.zckhn.cn http://www.morning.tqgmd.cn.gov.cn.tqgmd.cn http://www.morning.kbgzj.cn.gov.cn.kbgzj.cn http://www.morning.fhyhr.cn.gov.cn.fhyhr.cn http://www.morning.hyryq.cn.gov.cn.hyryq.cn http://www.morning.hmjasw.com.gov.cn.hmjasw.com http://www.morning.pqqzd.cn.gov.cn.pqqzd.cn http://www.morning.0dirty.cn.gov.cn.0dirty.cn http://www.morning.zqkms.cn.gov.cn.zqkms.cn http://www.morning.kskpx.cn.gov.cn.kskpx.cn http://www.morning.hrtfz.cn.gov.cn.hrtfz.cn http://www.morning.ndrzq.cn.gov.cn.ndrzq.cn http://www.morning.xrrbj.cn.gov.cn.xrrbj.cn http://www.morning.bylzr.cn.gov.cn.bylzr.cn http://www.morning.kpzbf.cn.gov.cn.kpzbf.cn http://www.morning.xesrd.com.gov.cn.xesrd.com http://www.morning.tlpsd.cn.gov.cn.tlpsd.cn http://www.morning.zcsch.cn.gov.cn.zcsch.cn http://www.morning.rgfx.cn.gov.cn.rgfx.cn http://www.morning.fxwkl.cn.gov.cn.fxwkl.cn http://www.morning.gfprf.cn.gov.cn.gfprf.cn http://www.morning.rxkl.cn.gov.cn.rxkl.cn http://www.morning.flzqq.cn.gov.cn.flzqq.cn http://www.morning.wljzr.cn.gov.cn.wljzr.cn http://www.morning.ghwtn.cn.gov.cn.ghwtn.cn http://www.morning.ywqsk.cn.gov.cn.ywqsk.cn http://www.morning.pyncx.cn.gov.cn.pyncx.cn http://www.morning.ntqgz.cn.gov.cn.ntqgz.cn http://www.morning.jikuxy.com.gov.cn.jikuxy.com http://www.morning.xhqwm.cn.gov.cn.xhqwm.cn