第三周进展
本周计划
继续编写和完善脚本。
完成过程
学习笔记
关于lua
lua是一种用c语言写的轻量级语言。当我们在wireshark上使用时是不需要安装环境的,因为wireshark继承了lua的解释器,且给用户留了API供数据包处理。这里有几点要说明的:
lua语言在wireshark上使用时,你的调试过程完全不依赖lua的环境,所以你不需要安装lua的包,只需要wireshark加载你写的name.lua就可以(可以用文本编辑器写,后缀为.lua)。
lua语言其不足之处–虽然它是用c写的,但是它没有继承c语言的位操作。也就是说没有<< >> || &&等操作。要这个有啥用呢? 首先,如果你想要解析一包网络数据里面的一段信息,一般一包数据的发送都是以大端发送,若涉及8bit以上的包解析,你肯定要用到位运算,故用lua你就要想别的办法解决。
在wireshark里面的接口和lua的环境没任何关系,你只能用wireshark调试,比较麻烦。
使用lua写wireshark插件
先看代码和解析,然后再去后面看接口相应文档:
首先打开文本编辑器,新建一个(你想写的名字).lua的文件。加入以下代码:
local _808_proto = Proto ("2013","2013","Self-defined Protocol")
--以下根据协议定义消息字段--
--标识符
local _808_message_flag_start= ProtoField.uint8("_808_message_flag_start", "start_flag", base.HEX) -- 消息标识符
local _808_message_flag_end = ProtoField.uint8("_808._message_flag_end", "end_flag", base.HEX)
--消息头
local _808_message_id = ProtoField.uint16("_808.messageid", "Message ID", base.HEX) -- 消息id
local _808_message_property = ProtoField.uint16("_808_message_property", "Message Property", base.HEX) --消息体
-- 将字段添加都协议中
_808_proto.fields = {
_808_message_flag_start,
_808_message_flag_end,
_808_message_id,
_808_message_property,
}
怎么让它在后面显示你想解析的字段:
function _808_proto.dissector(tvb, pinfo, treeitem)
这个函数是用来解析报文用的,参数tvb里面放了有用的报文,wireshark自动帮你过滤了tcp/ip报头,tvb从0开始就是你要抓得有用数据。但是tvb并非数组,本菜鸟后来也没有摸清里面的数据结构,反正也不是字符串。解析完成后,用tvb(x,y)的形式取出数据。x指起始位,(从0开始)y指从x起向后几位。
Lua 变量
变量在使用前,需要在代码中进行声明,即创建该变量。
编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值。
Lua 变量有三种类型:全局变量、局部变量、表中的域。
Lua 中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量。
局部变量的作用域为从声明位置开始到所在语句块结束。
变量的默认值均为 nil。
代码实现
-- 创建一个名为MyProtocol的协议
local my_protocol = Proto("MyProtocol", "My Protocol")
-- 定义解析函数
function my_protocol.dissector(buffer, pkt, tree)
-- 获取记录类型
local typer = buffer(0, 1):uint() -- 记录类型在数据包头部
local sh_ty = buffer(5, 1):uint() -- 记录子类型
local dsc = buffer(6, 1):uint() -- 描述
-- 根据记录类型标识解析信息
if typer == 0x14 then
pkt.cols.protocol:set("TLS-change cipher spec") -- 设置协议名称为"TLS-change cipher spec"
elseif typer == 0x15 then
pkt.cols.protocol:set("TLS-Alert") -- 设置协议名称为"TLS-Alert"
if sh_ty == 0x02 then
pkt.cols.info:set("Level:Fatal") -- 设置详情为"Level:Fatal"
if dsc == 0x46 then
pkt.cols.info:append(" - Description:Protocol Version") -- 追加详情为" - Description:Protocol Version"
end
end
elseif typer == 0x16 then
pkt.cols.protocol:set("TLS-Handshake") -- 设置协议名称为"TLS-Handshake"
if sh_ty == 0x01 then
pkt.cols.info:set("Client Hello") -- 设置详情为"Client Hello"
elseif sh_ty == 0x02 then
pkt.cols.info:set("Server Hello") -- 设置详情为"Server Hello"
local is_cer = buffer(0x5c,1):uint() -- 根据偏移量获取相关信息
if is_cer == 0x0b then
pkt.cols.info:append(" - Certificate") -- 追加详情为" - Certificate"
end
elseif sh_ty == 0x10 then
pkt.cols.info:set("Key Exchange") -- 设置详情为"Key Exchange"
local is_cc = buffer(0x010b,1):uint() -- 根据偏移量获取相关信息
if is_cc == 0x14 then
pkt.cols.info:append(" - Change Cipher Spec") -- 追加详情为" - Change Cipher Spec"
end
end
elseif typer == 0x17 then
pkt.cols.protocol:set("TLS-Application Data") -- 设置协议名称为"TLS-Application Data"
end
end
-- 将协议与TCP端口进行关联
local tcp_table = DissectorTable.get("tcp.port")
tcp_table:add(443, my_protocol) -- 将自定义解析器与TLS默认端口443关联
运行插件后