firepit package

Subpackages

Submodules

firepit.deref module

firepit.deref.auto_deref(store, view, ignore=None, paths=None)[source]

Automatically resolve refs for backward compatibility.

If paths is specified, only follow/deref those specific paths/properties.

Use auto_deref_cached if you already have col_dict in memory.

firepit.deref.auto_deref_cached(view, cols, col_dict, ignore=None, paths=None)[source]

Automatically resolve refs for backward compatibility.

If paths is specified, only follow/deref those specific paths/properties.

firepit.deref.unresolve(objects)[source]

Do the opposite of auto_deref: split out reference objects

firepit.exceptions module

exception firepit.exceptions.DatabaseMismatch(dbversion, expected)[source]

Bases: Exception

exception firepit.exceptions.DuplicateTable[source]

Bases: Exception

exception firepit.exceptions.IncompatibleType[source]

Bases: Exception

exception firepit.exceptions.InvalidAttr(msg)[source]

Bases: Exception

exception firepit.exceptions.InvalidObject(msg)[source]

Bases: Exception

exception firepit.exceptions.InvalidStixPath[source]

Bases: Exception

exception firepit.exceptions.InvalidViewname[source]

Bases: Exception

exception firepit.exceptions.SessionExists[source]

Bases: Exception

exception firepit.exceptions.SessionNotFound[source]

Bases: Exception

exception firepit.exceptions.StixPatternError(stix)[source]

Bases: Exception

exception firepit.exceptions.UnexpectedError[source]

Bases: Exception

exception firepit.exceptions.UnknownViewname[source]

Bases: Exception

firepit.generator module

firepit.pgcommon module

Some common PostgreSQL stuff used by both pgstorage.py (the normal interface) and aio.asyncpgstorage.py (the async interface).

firepit.pgcommon.pg_shorten(key)[source]

firepit.pgstorage module

firepit.props module

Utility functions for STIX properties

firepit.props.auto_agg(sco_type, prop, col_type)[source]

Infer an aggregation function based on column name and type

firepit.props.auto_agg_tuple(sco_type, prop, col_type)[source]

Infer an aggregation function based on column name and type

firepit.props.get_last(prop)[source]
firepit.props.is_ref(name)[source]
firepit.props.parse_path(path)[source]
firepit.props.parse_prop(sco_type, prop)[source]
firepit.props.path_metadata(path)[source]

Get metadata for a STIX object path

firepit.props.primary_prop(sco_type)[source]

Returns the “primary” property name for each SCO type

firepit.props.prop_metadata(sco_type, prop)[source]

Get metadata for a STIX object property

firepit.props.ref_type(sco_type, part)[source]

Get STIX SCO type for reference prop part

firepit.query module

Utilities for generating SQL while avoiding SQL injection vulns

class firepit.query.Aggregation(aggs)[source]

Bases: object

Aggregate rows

render(_placeholder, _dialect=None)[source]
class firepit.query.BinnedColumn(prop: str, n: int, unit: Optional[str] = None, table: Optional[str] = None, alias: Optional[str] = None)[source]

Bases: Column

Bin (or “bucket”) column values, persumably for easier grouping

render(_placeholder, dialect=None)[source]
class firepit.query.CoalescedColumn(names, alias)[source]

Bases: object

First non-null column from a list - used after a JOIN

class firepit.query.Column(name, table=None, alias=None)[source]

Bases: object

SQL Column name

endswith(s)[source]
class firepit.query.Count[source]

Bases: object

Count the rows in a result set

render(_placeholder, _dialect=None)[source]
class firepit.query.CountUnique(cols=None)[source]

Bases: object

Unique count of the rows in a result set

render(_placeholder, _dialect=None)[source]
class firepit.query.Filter(preds, op=' AND ')[source]

Bases: object

Alternative SQL WHERE clause

AND = ' AND '
OR = ' OR '
render(placeholder, _dialect=None)[source]
set_table(table)[source]

Specify table for ALL Predicates in Filter

class firepit.query.Group(cols)[source]

Bases: object

SQL GROUP clause

render(_placeholder, _dialect=None)[source]
exception firepit.query.InvalidAggregateFunction[source]

Bases: Exception

exception firepit.query.InvalidComparisonOperator[source]

Bases: Exception

exception firepit.query.InvalidJoinOperator[source]

Bases: Exception

exception firepit.query.InvalidPredicateOperand[source]

Bases: Exception

exception firepit.query.InvalidPredicateOperator[source]

Bases: Exception

exception firepit.query.InvalidQuery[source]

Bases: Exception

class firepit.query.Join(name, left_col=None, op=None, right_col=None, preds=None, how='INNER', alias=None, lhs=None)[source]

Bases: object

Join 2 tables

render(placeholder, _dialect=None)[source]
class firepit.query.Limit(num)[source]

Bases: object

SQL row count

render(_placeholder, _dialect=None)[source]
class firepit.query.Offset(num)[source]

Bases: object

SQL row offset

render(_placeholder, _dialect=None)[source]
class firepit.query.Order(cols)[source]

Bases: object

SQL ORDER BY clause

ASC = 'ASC'
DESC = 'DESC'
render(_placeholder, _dialect=None)[source]
class firepit.query.Predicate(lhs, op, rhs)[source]

Bases: object

Row value predicate

render(placeholder, _dialect=None)[source]
set_table(table)[source]

Specify table for ALL columns in Predicate

class firepit.query.Projection(cols)[source]

Bases: object

SQL SELECT (really projection - pick column subset) clause

render(placeholder, dialect=None)[source]
class firepit.query.Query(arg=None)[source]

Bases: object

SQL Query statement

SQL order of evaluations: FROM, including JOINs WHERE GROUP BY HAVING WINDOW functions SELECT (projection) DISTINCT UNION ORDER BY LIMIT and OFFSET

append(stage)[source]
extend(stages)[source]
render(placeholder, dialect=None)[source]
class firepit.query.Table(name)[source]

Bases: object

SQL Table selection

render(_placeholder, _dialect=None)[source]
class firepit.query.Unique[source]

Bases: object

Reduce the rows in a result set to unique tuples

render(placeholder, dialect=None)[source]

firepit.schemas module

firepit.sqlitestorage module

class firepit.sqlitestorage.SQLiteStorage(dbname)[source]

Bases: SqlStorage

columns(viewname)[source]

Get the column names (properties) of viewname

delete()[source]

Delete ALL data in this store

schema(viewname=None)[source]

Get the schema (names and types) of table/view viewname or all tables if not specified

tables()[source]

Get all table names

types(private=False)[source]

Get all table names that correspond to SCO types

firepit.sqlitestorage.get_storage(path)[source]
firepit.sqlitestorage.row_factory(cursor, row)[source]

firepit.sqlstorage module

class firepit.sqlstorage.SqlStorage[source]

Bases: object

assign(viewname, on, op=None, by=None, ascending=True, limit=None)[source]

DEPRECATED: Perform (unary) operation op on on and store result as viewname

assign_query(viewname, query, sco_type=None)[source]

Create a new view viewname defined by query

cache(query_id, bundles, batchsize=2000, **kwargs)[source]

Cache the result of a query/dataset

Takes the observed-data SDOs from bundles and “flattens” them, splits out SCOs by type, and inserts into a database with 1 table per type.

Accepts some keyword args for runtime options, some of which may depend on what database type is in use (e.g. sqlite3, postgresql, …)

Args:

query_id (str): a unique identifier for this set of bundles

bundles (list): STIX bundles (either in-memory Python objects or filename paths)

batchsize (int): number of objects to insert in 1 batch (defaults to 2000)

close()[source]
columns(viewname)[source]

Get the column names (properties) of viewname

count(viewname)[source]

Get the count of objects (rows) in viewname

delete()[source]

Delete ALL data in this store

extract(viewname, sco_type, query_id, pattern)[source]

Extract all sco_type object from the results of query_id and store as viewname

extract_observeddata_attribute(viewname, name_of_attribute, path=None, value=None, limit=None, run=True)[source]

Get the observations of value in viewname.`path` Returns list of dicts like {‘name_of_attribute’: ‘…’, ‘{column}’: ‘…’} name_of_attribute can be a str or list of str (to get multiple attrs)

filter(viewname, sco_type, input_view, pattern)[source]

Extract all sco_type object from input_view and store as viewname

finish(index=True)[source]

Do any DB-specific post-caching/insertion activity, such as indexing

get_appdata(viewname)[source]

Retrieve app-specific data for a viewname

get_view_data(viewnames=None)[source]

Retrieve information about one or more viewnames

group(newname, viewname, by, aggs=None)[source]

Create new view newname defined by grouping viewname by by

join(viewname, l_var, l_on, r_var, r_on)[source]

Join vars l_var and r_var and store result as viewname

load(viewname, objects, sco_type=None, query_id=None, preserve_ids=True)[source]

Import objects as type sco_type and store as viewname

lookup(viewname, cols='*', limit=None, offset=None, col_dict=None)[source]

Get the value of viewname

merge(viewname, input_views)[source]
number_observed(viewname, path, value=None)[source]

Get the count of observations of value in viewname.`path` Returns integer count

path_joins(viewname, sco_type, column)[source]

Determine if column has implicit Joins and return them if so

reassign(viewname, objects)[source]

Replace objects (or insert them if they’re not there)

remove_view(viewname)[source]

Remove view viewname

rename_view(oldname, newname)[source]

Rename view oldname to newname

run_query(query)[source]
schema(viewname=None)[source]

Get the schema (names and types) of table/view viewname or all tables if not specified

set_appdata(viewname, data)[source]

Attach app-specific data to a viewname

summary(viewname, path=None, value=None)[source]

Get the first and last observed time and number observed for observations of viewname, optionally specifying path and value. Returns list of dicts like {‘first_observed’: ‘2021-10-…’, ‘last_observed’: ‘2021-10-…’, ‘number_observed’: N}

table_type(viewname)[source]

Get the SCO type for table/view viewname

tables()[source]

Get all table names

timestamped(viewname, path=None, value=None, timestamp='first_observed', limit=None, run=True)[source]

Get the timestamped observations of value in viewname.`path` Returns list of dicts like {‘timestamp’: ‘2021-10-…’, ‘{column}’: ‘…’}

types(private=False)[source]

Get all table names that correspond to SCO types

upsert(cursor, tablename, obj, query_id, schema)[source]
upsert_many(cursor, tablename, objs, query_id, schema)[source]
value_counts(viewname, path)[source]

Get the count of observations of each value in viewname.`path` Returns list of dicts like {‘{column}’: ‘…’, ‘count’: 1}

values(path, viewname)[source]

Get the values of STIX object path path (a column) from viewname

views()[source]

Get all view names

firepit.sqlstorage.get_path_joins(viewname, sco_type, column)[source]

Determine if column has implicit Joins and return them if so

firepit.sqlstorage.infer_type(key, value)[source]

firepit.stix20 module

firepit.stix20.comp2sql(sco_type, prop, op, value, dialect)[source]
firepit.stix20.get_grammar()[source]
firepit.stix20.path2sql(sco_type, path)[source]
firepit.stix20.stix2sql(pattern, sco_type, dialect='sqlite3')[source]
firepit.stix20.summarize_pattern(pattern)[source]

firepit.stix21 module

firepit.stix21.makeid(sco, obs=None)[source]

firepit.timestamp module

firepit.timestamp.timefmt(t, prec=3)[source]

Format Python datetime t in RFC 3339-format

firepit.timestamp.to_datetime(timestamp)[source]

Convert RFC 3339-format timestamp to Python datetime

firepit.validate module

STIX and SQL identifier validators

firepit.validate.validate_name(name)[source]

Make sure name is a valid (SQL) identifier

firepit.validate.validate_path(path)[source]

Make sure path is a valid STIX object path or property name

firepit.woodchipper module

class firepit.woodchipper.FlatJsonMapper[source]

Bases: Mapper

convert(event)[source]
detect(event)[source]
class firepit.woodchipper.IscHoneypotJsonMapper[source]

Bases: Mapper

convert(event)[source]
detect(event)[source]
mapping = {'dest': 'network-traffic:dst_ref.value', 'dport': 'network-traffic:dst_port', 'proto': 'network-traffic:protocols', 'source': 'network-traffic:src_ref.value', 'sport': 'network-traffic:src_port', 'ts': ['first_observed', 'last_observed'], 'url': 'url:value', 'user_agent': "network-traffic:extensions.'http-request-ext'.request_header.'User-Agent'"}
class firepit.woodchipper.Mapper[source]

Bases: object

convert(event)[source]
detect(event)[source]
class firepit.woodchipper.SdsMapper[source]

Bases: Mapper

common_mapping = {'@timestamp': ['first_observed', 'last_observed'], 'Application': <function split_image>, 'Category': <function to_cat_list>, 'Channel': 'x-oca-event:module', 'EventID': <function to_action_code>, 'Hostname': 'x-oca-asset:hostname', 'Message': <function SdsMapper.<lambda>>, 'ProcessGuid': 'process:x_unique_id', 'ProcessId': 'process:pid', 'ProcessName': <function split_image>, 'SourceName': 'x-oca-event:provider', 'TimeCreated': ['first_observed', 'last_observed']}
convert(event)[source]
detect(event)[source]
static enhanced_action(message)[source]
event_types = {'ConnectPipe': 18, 'CreateKey': 12, 'CreatePipe': 17, 'DeleteKey': 12, 'DeleteValue': 12, 'SetValue': 13}
class firepit.woodchipper.ZeekCsvMapper[source]

Bases: Mapper

convert(event)[source]
detect(event)[source]
zeek_mapping = {'id.orig_h': 'network-traffic:src_ref.value', 'id.orig_p': 'network-traffic:src_port', 'id.resp_h': 'network-traffic:dst_ref.value', 'id.resp_p': 'network-traffic:dst_port', 'orig_ip_bytes': 'network-traffic:src_byte_count', 'orig_pkts': 'network-traffic:src_packets', 'proto': 'network-traffic:protocols', 'resp_ip_bytes': 'network-traffic:dst_byte_count', 'resp_pkts': 'network-traffic:dst_packets', 'ts': <function from_unix_time>}
class firepit.woodchipper.ZeekJsonMapper[source]

Bases: Mapper

common_mapping = {'id_orig_h': 'network-traffic:src_ref.value', 'id_orig_p': 'network-traffic:src_port', 'id_resp_h': 'network-traffic:dst_ref.value', 'id_resp_p': 'network-traffic:dst_port', 'proto': 'network-traffic:protocols', 'ts': <function from_unix_time>}
convert(event)[source]
detect(event)[source]
static process_answers(answers)[source]
zeek_mapping = {'conn': {'orig_ip_bytes': 'network-traffic:src_byte_count', 'orig_l2_addr': 'network-traffic:src_ref.resolves_to_refs[0].value', 'orig_pkts': 'network-traffic:src_packets', 'resp_ip_bytes': 'network-traffic:dst_byte_count', 'resp_l2_addr': 'network-traffic:dst_ref.resolves_to_refs[0].value', 'resp_pkts': 'network-traffic:dst_packets'}, 'dns': {'answers': <function ZeekJsonMapper.<lambda>>, 'query': 'domain-name:value'}}
firepit.woodchipper.convert(input_file, output_file=None)[source]
firepit.woodchipper.convert_to_stix(input_file)[source]
firepit.woodchipper.detect_filetype(input_file)[source]
firepit.woodchipper.dict2observation(creator, row)[source]
firepit.woodchipper.fixup_hashes(hashes: dict)[source]
firepit.woodchipper.format_val(sco_type, prop, val)[source]
firepit.woodchipper.from_unix_time(ts)[source]
firepit.woodchipper.guess_ref_type(sco_type, prop, val)[source]

Get data type for sco_type:prop reference

firepit.woodchipper.is_file_event(event_id)[source]
firepit.woodchipper.merge_mappings(common, specific, key=None)[source]

Merge common mapping into specific[key] mapping

firepit.woodchipper.process_event(event, mapping, event_id=None)[source]
firepit.woodchipper.process_events(events, mappers, ident)[source]
firepit.woodchipper.process_mapping(event, mapping)[source]
firepit.woodchipper.read_csv(fp, mappers, ident)[source]
firepit.woodchipper.read_json(fp, mappers, ident)[source]
firepit.woodchipper.read_log(fp, mappers, ident)[source]
firepit.woodchipper.recreate_dict(obj, prop, rest, val)[source]
firepit.woodchipper.set_obs_prop(observable, path, val, scos, key)[source]
firepit.woodchipper.split_file_hash(hash_string: str)[source]
firepit.woodchipper.split_file_path(abs_name: str, prefix='file:')[source]
firepit.woodchipper.split_hash(hash_string: str, prefix: str, tag: str = '')[source]
firepit.woodchipper.split_image(abs_name: str, prefix='process:')[source]
firepit.woodchipper.split_image_hash(hash_string: str)[source]
firepit.woodchipper.split_image_loaded(abs_name: str)[source]
firepit.woodchipper.split_loaded_hash(hash_string: str)[source]
firepit.woodchipper.split_parent_image(abs_name: str)[source]
firepit.woodchipper.split_reg_key_value(path: str)[source]
firepit.woodchipper.to_action_code(event_id)[source]

Convert windows event ID to x-oca-event action and code

firepit.woodchipper.to_cat_list(category)[source]
firepit.woodchipper.to_payload_bin(value)[source]
firepit.woodchipper.to_protocol(value)[source]

Module contents

Top-level package for STIX Columnar Storage.

firepit.get_storage(url, session_id=None)[source]

Get a storage object for firepit. url will determine the type; a file path means sqlite3. session_id is used in the case of postgresql to partition your data.