Processing JSON
Press (X). "JASON!" Press (X). "JASON!"
JSON basics
JSON (JavaScript Object Notation) is a lightweight data interchange format that is easy for humans to read and write and easy for machines to parse and generate. It's a text-based format that uses a simple syntax to represent data objects in a hierarchical structure.
JSON documents consist of key-value pairs, where each key is a string and the value can be a string, number, boolean, null, array, or another JSON object.
JSON is widely used for transmitting data between web servers and clients, as well as for storing data in databases and files. It is a popular alternative to XML because it is simpler and more compact, making it easier to parse and generate.
JSON documents are often used in web development for AJAX (Asynchronous JavaScript and XML) applications, which allow web pages to update content dynamically without reloading the entire page. JSON is also commonly used in web APIs for exchanging data between different systems.
JSON documents can be an excellent way to store configuration values:
Parsing JSON from payloads
Payloads can process JSON using the jshn
tool.
jshn
is a simple way to create and process JSON files, and is built into the Packet Squirrel.
Including jshn in a payload
jshn
is included using the source
command in Bash. This is a feature we have not covered before: The source
command (or simply .
) includes another script and interprets it immediately. If you are familiar with other programming languages, this is similar to an include
, use
, or import
statement.
By importing the jshn
library from the system, we now have access to a new set of functions for processing JSON files.
Initializing the library
Before doing anyting else, jshn
should be initialized. This is simply:
This ensures no partial JSON data is held.
Loading data
To use a JSON document via jshn
first it has to be loaded with json_load
. This function parses the JSON and prepares it for all the other functions.
Content can also be loaded from a file, using the json_load_file
function:
Getting basic data
At the simplest, jshn
allows us to extract content from a JSON document. The json_get_var
function takes two arguments: the name of the variable to fill, and the name of the JSON field to fetch.
Putting this together with the previous examples:
Notice the use of single quotes when defining static JSON here: This keeps Bash from interpreting the braces and quotes. See the Quotes and Expansions chapter for more information.
Getting complex data
jshn
can parse more complex documents as well, of course.
You can navigate into nested objects with the json_select {name}
function, and navigate to the previous level of the document with json_select ..
For example, given a more complex JSON document:
We could then extract values using jshn
via:
Handling multiple objects
Since JSON can contain arrays, jshn
provides methods for iterating over lists of items. The function json_for_each_item
takes the name of a function and the JSON value, and calls that function for each value.
Given an example JSON with a list of URLs to fetch in a payload:
We could then fetch each file with:
Loading JSON from the web
As one of the main places JSON is used is in web services, it would be nice if we could load our JSON data directly.
Fortunately, this is (of course) possible!
To accomplish this, we combine jshn
with wget
.
Here we combine wget
outputting to stdout
, suppress the status by sending stderr
to /dev/null
, and we use the $(..)
construct to retrieve the output of wget
.
Notice how we enclosed the wget
command in quotes! This is vital; otherwise spaces and other special characters in the returned data will break the JSON parsing.
Creating JSON in payloads
The jshn
tool can also be used to create JSON files.
Creating a JSON file can be useful for saving states, or creating requests to API endpoints that expect JSON.
You can, of course, create JSON manually:
In simpler payloads, manually creating JSON may make the most sense.
jshn creation functions
For more complex payloads and JSON documents, using the jshn
creation framework can eliminate common trouble spots and simplify creating elements like arrays.
jshn
provides several creation functions:
json_add_object
to create a JSON object or dictionary (balanced byjson_close_object
)json_add_array
to create a JSON array (balanced byjson_close_array
)json_add_boolean
to create a true/false valuejson_add_int
to create a numberjson_add_string
to create a stringjson_dump
to create the JSON itself
Lets recreate the document above using jshn
functions:
This would print out the JSON string:
Bringing it all together
For a complete example, we'll create a payload that goes into BRIDGE
mode then fetches a list of ports and filters to monitor.
We'll use this as our configuration JSON file, hosted on a server:
To handle this, we'll put together several examples so far. Our payload might look like:
There's a lot going on here! Let's break it down:
We define a payload like usual, and set the network mode
We wait 10 seconds to get an IP because we want to use the network
We initialize the
jshn
libraryWe use the
wget
command to download our configuration payloadWe extract some variables from the JSON payload and set the LED color
We define a function that gets called for each object in the
streams
element.We use the second argument of the function, which is the index value, to descend into the nested object to obtain the port and match values.
We launch
MATCHSTREAM
in the backgroundWe use a command group to run the
MATCHSTREAM
commands and wait for any of them to completeThe device is placed in
JAIL
mode and the payload exits.
Last updated