Wireshark: display filters vs nested dissectors

寵の児 提交于 2020-01-04 06:11:47

问题


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 as Yes when added as a column)
  • json.value.string (I can also filter with json.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).


回答1:


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.



来源:https://stackoverflow.com/questions/46149825/wireshark-display-filters-vs-nested-dissectors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!