wireshark中没有portal协议,我们在抓包时候在这里输入portal,显示没有插件。我们需要使用wireshark的插件,wireshark的插件是使用lua语言开发的,wireshark并未内置 Portal协议,可解析Portal协议。
话不多说
第一步:将下面的插件脚本复制保存为portal.lua文件
--[[
code
--]]
do
--[[
创建一个新的协议结构 portal_proto
第一个参数是协议名称会体现在过滤器中
第二个参数是协议的描述信息,无关紧要
--]]
local portal_proto = Proto("portal", "Portal Protocol")
local attribute_proto = Proto("attribute", "Portal Attributes:")
--[[
下面定义字段
--]]
local portal_types = {
[1]="REQ_CHALLENGE",
[2]="ACK_CHALLENGE",
[3]="REQ_AUTH",
[4]="ACK_AUTH",
[5]="REQ_LOGOUT",
[6]="ACK_LOGOUT",
[7]="AFF_ACK_AUTH",
[8]="NTF_LOGOUT",
[9]="REQ_INFO",
[10]="ACK_INFO"
}
local version = ProtoField.uint8("portal.version", "Version", base.DEC, {[1]="Version 1", [2]="Version 2"}, 0x00)
local code_type = ProtoField.uint8("portal.type", "Type", base.DEC, portal_types)
local pap_chap = ProtoField.uint8("portal.papchap", "Pap/Chap", base.DEC, {[0]="CHAP",[1]="PAP"}, 0x00)
local reserved = ProtoField.uint8("portal.reserved", "Rsvd", base.DEC)
local serial_no = ProtoField.uint16("portal.serialno", "SerialNo", base.HEX)
local req_id = ProtoField.uint16("portal.reqid", "ReqID", base.HEX)
local user_ip = ProtoField.ipv4("portal.userip", "UserIP")
local user_port = ProtoField.uint16("portal.userport", "UserPort", base.HEX)
local err_code = ProtoField.uint8("portal.errcode", "ErrCode", base.DEC)
local attr_num = ProtoField.uint8("portal.attrnum", "AttrNum", base.DEC)
local authenticator = ProtoField.bytes("portal.authenticator", "Authenticator")
local user_name = ProtoField.string("portal.username", "UserName")
local user_password = ProtoField.string("portal.password", "Password")
local user_chappasswd = ProtoField.bytes("portal.chappasswd", "ChapPasswd")
local challenge = ProtoField.bytes("portal.challenge", "Challenge")
-- 将字段添加都协议中
portal_proto.fields = {
version,
code_type,
pap_chap,
reserved,
serial_no,
req_id,
user_ip,
user_port,
err_code,
attr_num,
authenticator,
user_name,
user_password,
user_chappasswd,
challenge
}
--[[
下面定义 portal 解析器的主函数,这个函数由 wireshark调用
第一个参数是 Tvb 类型,表示的是需要此解析器解析的数据
第二个参数是 Pinfo 类型,是协议解析树上的信息,包括 UI 上的显示
第三个参数是 TreeItem 类型,表示上一级解析树
--]]
function portal_proto.dissector(tvb, pinfo, treeitem)
-- 设置一些 UI 上面的信息
pinfo.cols.protocol:set("Portal")
local offset = 0
local tvb_len = tvb:len()
-- 在上一级解析树上创建 portal 的根节点
local portal_tree = treeitem:add(portal_proto, tvb:range(offset))
-- 下面是向该根节点上添加子节点,也就是自定义协议的各个字段
-- 注意 range 这个方法的两个参数的意义,第一个表示此时的偏移量
-- 第二个参数代表的是字段占用数据的长度
portal_tree:add(version, tvb:range(offset, 1))
local ver_value = tvb(offset, 1):uint()
offset = offset + 1
local req_type = tvb(offset, 1):uint()
portal_tree:add(code_type, tvb:range(offset, 1))
if req_type == 1 then
pinfo.cols.info:set("REQ_CHALLENGE")
end
if req_type == 2 then
pinfo.cols.info:set("ACK_CHALLENGE")
end
if req_type == 3 then
pinfo.cols.info:set("REQ_AUTH")
end
if req_type == 4 then
pinfo.cols.info:set("ACK_AUTH")
end
if req_type == 5 then
pinfo.cols.info:set("REQ_LOGOUT")
end
if req_type == 6 then
pinfo.cols.info:set("ACK_LOGOUT")
end
if req_type == 7 then
pinfo.cols.info:set("AFF_ACK_AUTH")
end
if req_type == 8 then
pinfo.cols.info:set("NTF_LOGOUT")
end
if req_type == 9 then
pinfo.cols.info:set("REQ_INFO")
end
if req_type == 10 then
pinfo.cols.info:set("Portal ACK_INFO")
end
offset = offset + 1
portal_tree:add(pap_chap, tvb:range(offset, 1))
offset = offset + 1
portal_tree:add(reserved, tvb:range(offset, 1))
offset = offset + 1
portal_tree:add(serial_no, tvb:range(offset, 2))
offset = offset + 2
portal_tree:add(req_id, tvb:range(offset, 2))
offset = offset + 2
portal_tree:add(user_ip, tvb:range(offset, 4))
offset = offset + 4
portal_tree:add(user_port, tvb:range(offset, 2))
offset = offset + 2
portal_tree:add(err_code, tvb:range(offset, 1))
offset = offset + 1
portal_tree:add(attr_num, tvb:range(offset, 1))
local attr_num = tvb(offset, 1):uint()
offset = offset + 1
if ver_value == 0x02 then
if tvb_len - offset >= 16 then
portal_tree:add(authenticator, tvb:range(offset, 16))
end
offset = offset + 16
end
if attr_num > 0 then
local attribute_tree = portal_tree:add(attribute_proto, tvb:range(offset))
attribute_tree:set_text("Attributes:")
local attr_type = tvb(offset, 1):uint()
if attr_type == 1 then
local length = tvb(offset + 1, 1):uint()
attribute_tree:add(user_name, tvb:range(offset + 2, length - 2))
offset = offset + length
if tvb_len - offset > 0 then
attr_type = tvb(offset, 1):uint()
end
attribute_tree:append_text("User-Name,")
end
if attr_type == 2 then
local length = tvb(offset + 1, 1):uint()
attribute_tree:add(user_password, tvb:range(offset + 2, length - 2))
offset = offset + length
if tvb_len - offset > 0 then
attr_type = tvb(offset, 1):uint()
end
attribute_tree:append_text("Passowrd")
end
if attr_type == 3 then
local length = tvb(offset + 1, 1):uint()
attribute_tree:add(challenge, tvb:range(offset + 2, length - 2))
offset = offset + length
if tvb_len - offset > 0 then
attr_type = tvb(offset, 1):uint()
end
attribute_tree:append_text("Challenge")
end
if attr_type == 4 then
local length = tvb(offset + 1, 1):uint()
attribute_tree:add(user_chappasswd, tvb:range(offset + 2, length - 2))
offset = offset + length
if tvb_len - offset > 0 then
attr_type = tvb(offset, 1):uint()
end
attribute_tree:append_text("Chap-Password")
end
end
-- for i =1,attr_num do
-- end
end
-- 向 wireshark 注册协议插件被调用的条件
local upd_port_table = DissectorTable.get("udp.port")
upd_port_table:add(2000, portal_proto)
end
第二部:然后放到wireshark安装的目录下
- (macOS)路径为/Applications/Wireshark.app/Contents/Resources/share/wireshark
- (win)路径为安装盘符/wireshark
第三部:找见init.lua文件,末尾添加dofile("portal.lua")
注意:
要保证最上面的disable_lua = false不能是true,否则wireshark就不支持加载lua插件了
(macos如下图,如果是enable_lua=true则不需要改动。)
第四步:重启wireshark
portal协议可用