Kismet helper tools are external programs which Kismet uses; splitting functionality into an external helper can be for several reasons:
- Security. By moving operations into external tools, Kismet can avoid requiring root / administrative privileges itself. Almost any capture from a network interface will require root, both to configure the interface and to initiate the packet capture.
- Enabling other languages. Kismet is written in C++, but this isn’t necessarily the best language for all situations. Kismet uses pure C for capture tools to minimize the runtime library requirements, and other components may best be implemented in a language like Python.
- Plugin functionality. Some plugins need to manage long running tools, or the author may wish to avoid C++ for whatever reason.
- Process management. Some plugins and capture methods demand their own lifecycle loops. While it would likely be possible to encapsulate these in a thread, using process separation ensures no crossover problems.
External Interface Protocol
Kismet uses a flexible protocol to communicate with external tools. Built around Google Protobuf, each top-level message is bundled in a network frame for delivery, and contains:
- The command type; an arbitrary string which defines the type, such as “MESSAGE” or “CONFIGURE”.
- A unique sequence number, which is used to respond to commands or return errors.
- The payload of the command, as a string. The payload should typically be a Protobuf serialized message. While, technically, a custom command could encode any data, implementations are strongly encouraged to use the Protobuf framework.
The top-level protocol defines a few key commands and their payloads:
MESSAGE (KismetExternal.MsgbusMessage) Helper -> Kismet
Prints a message via the MessageBus system; these messages are printed to the Kismet console, displayed in the Messages section of the UI, and logged to the Messages section of the Kismet log.
|msgtype||MessageType||Type of message (Info, Debug, Alert, Etc.)|
PING (KismetExternal.Ping) Bidirectional
A ping message acts as a keepalive signal which expects an answering
PONG (KismetExternal.Pong) Bidirectional
Answering packet to a
PING, which must include the sequence number of the
PONG responses should be sent immediately.
SHUTDOWN (KismetExternal.Shutdown) Bidirectional
Either side of the connection can request the connection be shut down; upon receiving a
SHUTDOWN message the external helper will be terminated.
SYSTEMREGISTER (KismetExternal.SystemRegister) Helper -> Kismet
When using network sockets to connect external helpers, the Kismet listening socket may be multiplexed across many different handlers. The external helper can identify itself with the
SYSTEMREGISTER message so that it may be dispatched to the proper handler.
KismetExternal Eventbus Proxy
Kismet implements a serializable eventbus internally to pass messages among disparate parts of the codebase and to provide an event-based API. Events include phy layer handler creation, datasource status, new device creation, and more.
A kismetexternal tool may subscribe to the eventbus, and publish basic events.
EVENTBUSREGISTER (KismetEventbus.EventbusRegister) Helper -> Kismet
To receive events, a tool must register with Kismet.
Events may be specified as specific events, or
"*" for all events.
|event||string||Repeating list of events to subscribe to|
EVENTBUSPUBLISH (KismetEventbus.EventbusPublishEvent) Helper -> Kismet
Tools may publish basic eventbus events. These events should not overlap with existing Kismet events, and may only contain JSON content. This content will not be turned into complex C++ objects inside Kismet, but will be available to C++ code as a JSON structure.
Content published will be inserted into the event content under the key
|event_type||string||Event type / name|
|event_content||string||Event JSON content which will be inserted into the
KismetExternal HTTP Proxy
The Kismet external protocol has hooks for extending the web server functionality to external tools, regardless of the language they are written in.
HTTPREQUESTAUTH (KismetExternalHttp.HttpAuthTokenRequest) Helper -> Kismet
External tools may request a HTTP authorization token; instead of transmitting the Kismet admin username and password, a web session cookie is generated and returned in a
HTTPAUTH (KismetExternalHttp.HttpAuthToken) Kismet -> Helper
Once Kismet has generated a HTTP authentication token it is sent to the helper in a
HTTPAUTH response. The session hash is suitable for use as the
KISMET cookie in HTTP communication.
|token||string||HTTP auth token|
HTTPREGISTERURI (KismetExternalHttp.HttpRegisterUri) Helper -> Kismet
A helper can create endpoints in the Kismet server by registering the URI. The URI can be registered as a GET or PUSH, and can specify if there just be an authenticated login.
Kismet will handle the incoming web request and authentication validation.
|uri||string||Full path and file extension URI to register|
|method||string||HTTP method (currently GET and POST are supported)|
|auth_required||boolean||Indicates if a valid HTTP session is required|
2019-04-git Kismet requires authentication for all API calls, and this parameter is now ignored.
HTTPREQUESTCANCEL (KismetExternalHttp.HttpRequestCancel) Kismet->Helper
If a HTTP request is closed by the client before the external helper has sent a
HTTPRESPONSE message with
close_connection, Kismet will send a
HTTPREQUESTCANCEL to the helper. The helper should stop processing this request.
|req_id||uint32||Session ID to be cancelled|
HTTPREQUEST (KismetExternalHttp.HttpRequest) Kismet -> Helper
When an incoming request is received by the web server which matches a registered URI, Kismet will send a request packet to the helper with a unique connection ID and any form post variables.
If the URI requires a login, Kismet will only send the
HTTPREQUEST to the helper tool if there is a valid login session.
|req_id||uint32||Unique request ID,
|uri||string||Full path and file extension of the URI|
|post_data||SubHttpPostData||Optional Array of HTTP Post variables|
HTTP POST variables are transmitted as an array of HttpPostData.
|field||string||POST variable field|
|content||string||POST variable content|
HTTPRESPONSE (KismetExternalHttp.HttpResponse) Helper -> Kismet
Multiple response frames may be sent for any request; request responses may include custom HTTP headers, fixed content or streaming data, and external helpers may keep the connection open in a streaming mode to continually send streaming real-time data.
Internally, the web proxy system uses the Kismet chained buffer system; this sends the buffer to the web client as quickly as possible while it is still being populated; if the client is fast enough, the buffer will never grow beyond the basic size, but if the client is not keeping up with the buffer, it will grow automatically. The external tool can pass data as quickly as it can be generated without concern for the web budgeting system.
Generally, an external tool should limit the data per frame to a reasonable amount (1kB would be a reasonable size); if a packet is larger than the buffer allocated in Kismet it will not be properly received and Kismet may be running on an extremely memory-constrained system. Large amounts of data can be sent by sending multiple response frames.
The helper may include additional data in the
HTTPRESPONSE such as custom HTTP headers, and the helper may change the HTTP result code. Headers may only be sent before or with the first
|req_id||uint32||Unique session ID (from
|header_content||SubHttpHeader||Optional Array of custom headers to send. May only be sent with the first
|content||bytes||Optional HTTP content. Messages should be limited to
|resultcode||uint32||Optional HTTP numeric result code. Connections closed with no
|close_response||boolean||Optional This is the last
HTTP header values to be transmitted at the beginning of the connection.