如何在链式Lua dissector中访问已提取的MQTT payload字段?
编写Wireshark Lua链式Dissector解密MQTT Payload
核心思路
直接用Post-Dissector,它会在Wireshark自带的MQTT dissector之后运行,能直接获取已解析完成的MQTT payload,不用自己从原始数据包里定位,这是最高效的方式,完全无需字段提取器从头捞数据。
完整示例代码
-- 替换成你的实际解密逻辑,比如AES/自定义加密算法 local function decrypt_payload(encrypted_data) -- 示例:这里仅返回占位内容,实际需替换为你的解密代码 -- 例如用Wireshark自带的openssl库实现AES解密: -- local openssl = require("openssl") -- local key = mqtt_decrypt_dissector.prefs.decrypt_key -- local iv = mqtt_decrypt_dissector.prefs.decrypt_iv -- local cipher = openssl.cipher.get("aes-128-cbc") -- local decrypted = cipher:decrypt(key, iv, encrypted_data, false) return "解密后的内容示例" end -- 注册自定义协议 dissector local mqtt_decrypt_dissector = Proto("mqtt_decrypt", "MQTT 解密Payload") -- 定义要在协议树中显示的字段 local f_decrypted_payload = ProtoField.string("mqtt_decrypt.payload", "解密后的Payload") mqtt_decrypt_dissector.fields = {f_decrypted_payload} -- 添加首选项(可选):让用户输入解密密钥/初始化向量 mqtt_decrypt_dissector.prefs.decrypt_key = Pref.string("解密密钥", "", "MQTT Payload解密密钥") mqtt_decrypt_dissector.prefs.decrypt_iv = Pref.string("初始化向量(IV)", "", "加密算法所需IV") -- 核心解析函数 function mqtt_decrypt_dissector.dissector(tvb, pinfo, tree) -- 仅处理MQTT PUBLISH消息(消息类型值为3) local msg_type = pinfo.fields["mqtt.msgtype"] if not msg_type or msg_type.value ~= 3 then return end -- 获取已解析的MQTT payload字段 local mqtt_payload = pinfo.fields["mqtt.payload"] if not mqtt_payload then return end -- 提取payload的原始字节数据 local encrypted_bytes = mqtt_payload.value:raw() -- 执行解密 local decrypted_content = decrypt_payload(encrypted_bytes) -- 在Wireshark协议树中添加解密结果节点 local subtree = tree:add(mqtt_decrypt_dissector, tvb(), "MQTT 解密Payload") subtree:add(f_decrypted_payload, decrypted_content) -- 可选:如果解密后是JSON/Protobuf等结构化数据,调用对应dissector继续解析 -- local json_dissector = Dissector.get("json") -- if json_dissector and decrypted_content then -- local decrypted_tvb = ByteArray.tvb(ByteArray.new(decrypted_content)) -- json_dissector:call(decrypted_tvb, pinfo, subtree) -- end end -- 注册为Post-Dissector,确保在MQTT dissector之后运行 register_postdissector(mqtt_decrypt_dissector)
关键说明
- 避免字段提取器的原因:自带的MQTT dissector已经完成了payload的定位和提取,直接通过
pinfo.fields["mqtt.payload"]获取的是处理好的字段对象,调用:raw()就能拿到原始加密字节,省去自己处理MQTT协议头、变长字段等复杂逻辑。 - 针对性过滤:代码中加入了消息类型判断,仅处理PUBLISH消息;如果只需解密特定主题的消息,可新增判断
local topic = pinfo.fields["mqtt.topic"].value,匹配主题后再执行解密。 - 灵活密钥管理:通过Wireshark首选项配置密钥,无需硬编码在代码中,适配不同场景需求。
部署步骤
- 将代码保存为
mqtt_decrypt.lua - 打开Wireshark,进入
编辑->首选项->Lua,将文件添加到「个人Lua脚本」,或放入Wireshark全局插件目录 - 重启Wireshark,抓包或打开已有pcap文件,即可在MQTT PUBLISH消息的协议树中看到「MQTT 解密Payload」节点
内容的提问来源于stack exchange,提问作者jerry
相关产品推荐
相关产品推荐

