kismetwireless / kismet

Github mirror of official Kismet repository
Other
1.61k stars 306 forks source link

Field simplification for collections (arrays, vectors) #531

Open yurybelevskiy opened 2 months ago

yurybelevskiy commented 2 months ago

I am pulling the JSON of devices using Kismet API and I am trying to extract some fields from the collections objects such as:

"dot11.device": { ....., "dot11.device.advertised_ssid_map: [ { ......, "dot11.advertisedssid.wps_device_name": "Asus Router", ...... } ], ..... }

I have tried using following string in my "fields" array: "dot11.device/dot11.device.responded_ssid_map/dot11.advertisedssid.wps_device_name" and it didn't produce any result.

Expected result

Provided I put following in my "fields" array: "fields": ["dot11.device/dot11.device.responded_ssid_map/dot11.advertisedssid.wps_device_name"]

I am expecting to get back the following structure: "dot11.device": { ..... "dot11.device.advertised_ssid_map: [ { "dot11.advertisedssid.wps_device_name": "Asus Router", }, { "dot11.advertisedssid.wps_device_name": "Another Router", }, { "dot11.advertisedssid.wps_device_name": "And another Router", } ] ..... }

Please let me know if that is something Kismet supports. I didn't find any examples or mentions of this functionality in documentation, yet it seems when using regex filtering for fields, something like that would work.

itdojo commented 1 month ago

Here is a snip of what the API returns from the /devices/views/phydot11_accesspoints/devices.json endpoint:

{
    "kismet.device.base.macaddr": "AA:BB:CC:0F:47:D5",
    "dot11.device": {
        "dot11.device.last_bssid": "AA:BB:CC:0F:47:D5",
        "dot11.device.responded_ssid_map": [
            {
                "dot11.advertisedssid.wps_device_name": "Xfinity Wireless Gateway",
            }
        ],
        "dot11.device.last_beacon_timestamp": 1727982007,
        "dot11.device.last_probed_ssid_record": {
            "dot11.probedssid.last_time": 1727981980,
            "dot11.probedssid.ssid": "MYSSID",
        },
        "dot11.device.num_associated_clients": 51,
        "dot11.device.advertised_ssid_map": [
            {
                "dot11.advertisedssid.ssidlen": 7,
                "dot11.advertisedssid.maxrate": 144.400000,
            }
        ],
        "dot11.device.client_disconnects": 1,
    },
    "kismet.device.base.manuf": "Vantiva USA LLC",
}

This works (example):

{"fields":["dot11.device/dot11.device.last_probed_ssid_record/dot11.probedssid.ssid"]}

This does not work (example):

{"fields":["dot11.device/dot11.device.responded_ssid_map/dot11.advertisedssid.wps_device_name"]}

HTTP response is 200 but the API returns keys that have a 0 value.

You are trying to drill down into dot11.device/dot11.device.responded_ssid_map/dot11.advertisedssid.wps_device_name and Kismet does not appear to support doing that (I have spent hours trying).
Speaking in python: Notice that the key (dot11.device.responded_ssid_map contains a list which has a single dictionary entry whereas dot11.device.last_probed_ssid_record has another dictionary as its value (not a list).)

Having tried and tried it seems you have to return dot11.device/dot11.device.responded_ssid_map ({"fields":["dot11.device/dot11.device.responded_ssid_map"]}) and parse it in your app to get to dot11.advertisedssid.wps_device_name.

Kismet's docs do not seem to address this.

All of this is no help to you, just validation that you do not appear to be doing anything wrong. With a little luck, the post after this one will be someone swooping in to dunk on me and say, "No, you just need to do this...".

Using the snip above, I can get to every individual value that has a ✅. Everything with a ❌ requires me to get the parent and parse it.

{
✅    "kismet.device.base.macaddr": "AA:BB:CC:0F:47:D5",  
✅    "dot11.device": {
✅        "dot11.device.last_bssid": "AA:BB:CC:0F:47:D5",
✅       "dot11.device.responded_ssid_map": [
            {
❌                "dot11.advertisedssid.wps_device_name": "Xfinity Wireless Gateway",
            }
        ],
✅      "dot11.device.last_beacon_timestamp": 1727982007,
✅      "dot11.device.last_probed_ssid_record": {
✅          "dot11.probedssid.last_time": 1727981980,
✅          "dot11.probedssid.ssid": "MYSSID",
        },
✅        "dot11.device.num_associated_clients": 51,
✅      "dot11.device.advertised_ssid_map": [
            {
❌              "dot11.advertisedssid.ssidlen": 7,
❌              "dot11.advertisedssid.maxrate": 144.400000,
            }
        ],
✅      "dot11.device.client_disconnects": 1,
    },
✅    "kismet.device.base.manuf": "Vantiva USA LLC",
}
yurybelevskiy commented 1 month ago

Hello @itdojo, thank you for the detailed response. I expected that it is something Kismet wouldn't support, but I wanted to double-check with the community, perhaps, there was some undocumented way of getting these fields. At the moment, I am following the approach you suggested which is retrieving the entire parent structure and parsing out the field individually, yet when you are dealing with many access points and low bandwidth internet connection, my goal was to reduce traffic as I could by minimizing amount of fields sent.