Wireshark:显示过滤器与嵌套分解器 [英] Wireshark: display filters vs nested dissectors
问题描述
我有一个通过AMQP发送JSON对象的应用程序,我想用Wireshark检查网络流量. AMQP解剖器在字段amqp.payload
中将有效负载作为一系列字节提供给我,但是我想提取并过滤JSON对象中的特定字段,因此我试图为此在Lua中编写一个插件. /p>
Wireshark已经有一个JSON解析器,所以我希望背负这一点,而不必自己处理JSON解析.
这是我的代码:
local amqp_json_p = Proto("amqp_json", "AMQP JSON payload")
local amqp_json_result = ProtoField.string("amqp_json.result", "Result")
amqp_json_p.fields = { amqp_json_result }
register_postdissector(amqp_json_p)
local amqp_payload_f = Field.new("amqp.payload")
local json_dissector = Dissector.get("json")
local json_member_f = Field.new("json.member")
local json_string_f = Field.new("json.value.string")
function amqp_json_p.dissector(tvb, pinfo, tree)
local amqp_payload = amqp_payload_f()
if amqp_payload then
local payload_tvbrange = amqp_payload.range
if payload_tvbrange:range(0,1):string() == "{" then
json_dissector(payload_tvbrange:tvb(), pinfo, tree)
-- So far so good. Let's look at what the JSON dissector came up with.
local members = { json_member_f() }
local strings = { json_string_f() }
local subtree = tree:add(amqp_json_p)
for k, member in pairs(members) do
if member.display == 'result' then
for _, s in ipairs(strings) do
-- Find the string value inside this member
if not (s < member) and (s <= member) then
subtree:add(amqp_json_result, s.range)
break
end
end
end
end
end
end
end
(首先,我只是查看result
字段,而我正在测试的有效负载是{"result":"ok"}
.)
它使我半途而废.数据包剖析显示了以下内容,而没有我的插件,我只能得到AMQP部分:
Advanced Message Queueing Protocol
Type: Content body (3)
Channel: 1
Length: 15
Payload: 7b22726573756c74223a226f6b227d
JavaScript Object Notation
Object
Member Key: result
String value: ok
Key: result
AMQP JSON payload
Result: "ok"
现在,我希望能够将这些新字段用作显示过滤器,并将它们添加为Wireshark中的列.两者的以下工作:
-
json
(当添加为列时显示为Yes
) -
json.value.string
(我也可以使用json.value.string == "ok"
进行过滤) -
amqp_json
但是amqp_json.result
不起作用:如果我将其用作显示过滤器,则Wireshark不会显示任何数据包,并且如果将其用作列,则该列为空.
为什么json.value.string
和amqp_json.result
的行为不同?我该如何实现自己想要的? (似乎我确实需要自定义解剖器,就像使用json.value.string
一样,我只能过滤具有特定值的任何成员,而不一定是result
.)
我发现在wirehark-dev邮件列表("Lua后解剖器未获取字段值",2009-09-17、2009-09-22、2009-09-23)指向了interesting_hfids
哈希表,但此后似乎代码发生了很大变化.
如果您想尝试一下,这是我的PCAP文件,以base64编码,包含一个数据包:
1MOyoQIABAAAAAAAAAAAAAAABAAAAAAAjBi1WfYOCgBjAAAAYwAAAB4AAABgBMEqADcGQA
AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB/tcWKO232y46mkSqgBgxtgA/AAAB
AQgKRjDNvkYwzb4DAAEAAAAPeyJyZXN1bHQiOiJvayJ9zg==
使用base64 -d
(在Linux上)或base64 -D
(在OSX上)进行解码.
事实证明,我不应该尝试比较json.member
字段的display
属性.有时它是由JSON解剖器设置的,有时它只是保持为Member
.
正确的解决方案将涉及检查json.key
字段的值,但是由于我一直在寻找的键永远不会转义,因此我可以在range
属性的字符串文字中查找内容成员字段.
所以代替:
if member.display == 'result' then
我有:
if member.range:range(1, 6):string() == 'result' then
现在过滤和列都可以使用.
I have an application that sends JSON objects over AMQP, and I want to inspect the network traffic with Wireshark. The AMQP dissector gives the payload as a series of bytes in the field amqp.payload
, but I'd like to extract and filter on specific fields in the JSON object, so I'm trying to write a plugin in Lua for that.
Wireshark already has a dissector for JSON, so I was hoping to piggy-back on that, and not have to deal with JSON parsing myself.
Here is my code:
local amqp_json_p = Proto("amqp_json", "AMQP JSON payload")
local amqp_json_result = ProtoField.string("amqp_json.result", "Result")
amqp_json_p.fields = { amqp_json_result }
register_postdissector(amqp_json_p)
local amqp_payload_f = Field.new("amqp.payload")
local json_dissector = Dissector.get("json")
local json_member_f = Field.new("json.member")
local json_string_f = Field.new("json.value.string")
function amqp_json_p.dissector(tvb, pinfo, tree)
local amqp_payload = amqp_payload_f()
if amqp_payload then
local payload_tvbrange = amqp_payload.range
if payload_tvbrange:range(0,1):string() == "{" then
json_dissector(payload_tvbrange:tvb(), pinfo, tree)
-- So far so good. Let's look at what the JSON dissector came up with.
local members = { json_member_f() }
local strings = { json_string_f() }
local subtree = tree:add(amqp_json_p)
for k, member in pairs(members) do
if member.display == 'result' then
for _, s in ipairs(strings) do
-- Find the string value inside this member
if not (s < member) and (s <= member) then
subtree:add(amqp_json_result, s.range)
break
end
end
end
end
end
end
end
(To start with, I'm just looking at the result
field, and the payload I'm testing with is {"result":"ok"}
.)
It gets me halfway there. The following shows up in the packet dissection, whereas without my plugin I only get the AMQP section:
Advanced Message Queueing Protocol
Type: Content body (3)
Channel: 1
Length: 15
Payload: 7b22726573756c74223a226f6b227d
JavaScript Object Notation
Object
Member Key: result
String value: ok
Key: result
AMQP JSON payload
Result: "ok"
Now I want to be able to use these new fields as display filters, and also to add them as columns in Wireshark. The following work for both:
json
(shows up asYes
when added as a column)json.value.string
(I can also filter withjson.value.string == "ok"
)amqp_json
But amqp_json.result
doesn't work: if I use it as a display filter, Wireshark doesn't show any packets, and if I use it as a column, the column is empty.
Why does it behave differently for json.value.string
and amqp_json.result
? And how can I achieve what I want? (It seems like I do need a custom dissector, as with json.value.string
I can only filter on any member having a certain value, not necessarily result
.)
I found a thread on the wireshark-dev mailing list ("Lua post-dissector not getting field values", 2009-09-17, 2009-09-22, 2009-09-23), that points to the interesting_hfids
hash table, but it seems like the code has changed a lot since then.
If you'd like to try this, here is my PCAP file, base64-encoded, containing a single packet:
1MOyoQIABAAAAAAAAAAAAAAABAAAAAAAjBi1WfYOCgBjAAAAYwAAAB4AAABgBMEqADcGQA
AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB/tcWKO232y46mkSqgBgxtgA/AAAB
AQgKRjDNvkYwzb4DAAEAAAAPeyJyZXN1bHQiOiJvayJ9zg==
Decode with base64 -d
(on Linux) or base64 -D
(on OSX).
It turns out I shouldn't have tried to compare the display
property of the json.member
field. Sometimes it gets set by the JSON dissector, and sometimes it just stays as Member
.
The proper solution would involve checking the value of the json.key
field, but since the key I'm looking for presumably would never get escaped, I can get away with looking for the string literal in the range
property of the member field.
So instead of:
if member.display == 'result' then
I have:
if member.range:range(1, 6):string() == 'result' then
and now both filtering and columns work.
这篇关于Wireshark:显示过滤器与嵌套分解器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!