关于lua:Wireshark:显示过滤器与嵌套解剖器

Wireshark: display filters vs nested dissectors

我有一个通过AMQP发送JSON对象的应用程序,我想用Wireshark检查网络流量。 AMQP解剖器在字段amqp.payload中将有效载荷作为一系列字节提供给我,但是我想提取并过滤JSON对象中的特定字段,因此我试图为此在Lua中编写一个插件。

Wireshark已经对JSON进行了剖析,因此我希望对此有所支持,而不必自己处理JSON。

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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部分:

1
2
3
4
5
6
7
8
9
10
11
12
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.stringamqp_json.result的行为不同?我该如何实现自己想要的? (似乎我确实需要自定义解剖器,就像使用json.value.string一样,我只能筛选具有特定值的任何成员,而不一定是result。)

我在wireshark-dev邮件列表上找到了一个线程(" Lua post-dissector未获取字段值",2009-09-17、2009-09-22、2009-09-23),该线程指向interesting_hfids哈希表,但此后代码似乎发生了很大变化。

如果您想尝试一下,这是我的PCAP文件,以base64编码,包含一个数据包:

1
2
3
1MOyoQIABAAAAAAAAAAAAAAABAAAAAAAjBi1WfYOCgBjAAAAYwAAAB4AAABgBMEqADcGQA
AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAB/tcWKO232y46mkSqgBgxtgA/AAAB
AQgKRjDNvkYwzb4DAAEAAAAPeyJyZXN1bHQiOiJvayJ9zg==

使用base64 -d(在Linux上)或base64 -d(在OSX上)进行解码。


事实证明,我不应该尝试比较json.member字段的display属性。 有时它是由JSON解剖器设置的,有时它只是保持为Member

正确的解决方案将涉及检查json.key字段的值,但是由于我一直在寻找的键永远不会被转义,因此我可以在成员字段的range属性中寻找字符串文字 。

所以代替:

1
            if member.display == 'result' then

我有:

1
            if member.range:range(1, 6):string() == 'result' then

现在过滤和列都可以使用。