app.service namespace

Subpackages

Submodules

app.service.app_svc module

class app.service.app_svc.AppService(application)

Bases: AppServiceInterface, BaseService

property errors

Locate a given link by its unique property :param unique: :return:

Retrieves the operation that a link_id belongs to. Will search currently running operations first.

get_loaded_plugins()
async load_plugin_expansions(plugins=())
async load_plugins(plugins)

Store all plugins in the data store :return:

async register_contact_tunnels(contact_svc)
async register_contacts()
register_subapp(path: str, app: Application)

Registers a web application under the root application.

Requests under path will be routed to this app.

async resume_operations()

Resume all unfinished operations :return: None

async retrieve_compiled_file(name, platform, location='')
async run_scheduler()

Kick off all scheduled jobs, as their schedule determines :return:

async start_sniffer_untrusted_agents()

Cyclic function that repeatedly checks if there are agents to be marked as untrusted :return: None

async teardown(main_config_file='default')
async update_operations_with_untrusted_agent(untrusted_agent)
async validate_requirement(requirement, params)
async validate_requirements()
async watch_ability_files()
class app.service.app_svc.Error(name, msg, optional)

Bases: tuple

msg

Alias for field number 1

name

Alias for field number 0

optional

Alias for field number 2

app.service.auth_svc module

class app.service.auth_svc.AuthService

Bases: AuthServiceInterface, BaseService

class User(username, password, permissions)

Bases: tuple

password

Alias for field number 1

permissions

Alias for field number 2

username

Alias for field number 0

async apply(app, users)

Set up security on server boot :param app: :param users: :return: None

async check_permissions(group, request)

Check if a request is allowed based on the user permissions :param group: :param request: :return: None

async create_user(username, password, group)
property default_login_handler
async get_permissions(request)
async handle_successful_login(request, username)
async is_request_authenticated(request)
async login_redirect(request, use_template=True)

Redirect user to login page using the configured login handler. Will fall back to the default login handler if an unexpected exception is raised.

Parameters:
  • request

  • use_template (bool, optional) – Determines if the login handler should return an html template rather than raise an HTTP redirect, if applicable. Defaults to True.

async login_user(request)

Log a user in and save the session

Parameters:

request

Raises:
  • web.HTTPRedirection – the HTTP response/location of where the user is trying to navigate

  • web.HTTPUnauthorized – HTTP unauthorized response as provided by the login handler.

  • web.HTTPForbidden – HTTP forbidden response as provided by the login handler.

  • web.HTTPSuccessful – HTTP successful response as provided by the login handler.

async static logout_user(request)

Log the user out :param request: :return: None

request_has_valid_api_key(request)
async request_has_valid_user_session(request)
async set_login_handlers(services, primary_handler=None)

Sets the default login handler for the auth service, as well as the custom login handler if specified in the primary_handler parameter or in the config file. The custom login handler will take priority for login methods during login_user and redirects during check_permissions.

If no login handler was specified in the config file or via the primary_handler parameter, the auth service will use only the default handler.

Parameters:
  • services (dict) – services used to set up the login handlers.

  • primary_handler (LoginHandlerInterface, optional) – Login handler for the auth service. If None, the config file will be used to load the primary login handler. Must implement the LoginHandlerInterface. Defaults to None.

Raises:

TypeError – The provided login handler does not implement the LoginHandlerInterface.

class app.service.auth_svc.DictionaryAuthorizationPolicy(user_map)

Bases: AbstractAuthorizationPolicy

async authorized_userid(identity)

Retrieve authorized user id. Return the user_id of the user identified by the identity or ‘None’ if no user exists related to the identity.

async permits(identity, permission, context=None)

Check user permissions. Return True if the identity is allowed the permission in the current context, else return False.

app.service.auth_svc.check_authorization(func)

Authorization Decorator This requires that the calling class have self.auth_svc set to the authentication service.

app.service.auth_svc.for_all_public_methods(decorator)

class decorator – adds decorator to all public methods

app.service.contact_svc module

class app.service.contact_svc.ContactService

Bases: ContactServiceInterface, BaseService

async build_filename()
async deregister_contacts()
async get_contact(name)
async get_tunnel(name)
async handle_heartbeat(**kwargs)

Accept all components of an agent profile and save a new agent or register an updated heartbeat. :return: the agent object, instructions to execute

async register_contact(contact)
async register_tunnel(tunnel)
app.service.contact_svc.report(func)

app.service.data_svc module

class app.service.data_svc.DataService

Bases: DataServiceInterface, BaseService

async apply(collection)

Add a new collection to RAM

Parameters:

collection

Returns:

async convert_v0_ability_executor(ability_data: dict)

Checks if ability file follows v0 executor format, otherwise assumes v1 ability formatting.

async convert_v0_ability_requirements(requirements_data: list)

Checks if ability file follows v0 requirement format, otherwise assumes v1 ability formatting.

convert_v0_ability_technique_id(ability_data: dict)

Checks if ability file follows v0 technique_id format, otherwise assumes v1 ability formatting.

convert_v0_ability_technique_name(ability_data: dict)

Checks if ability file follows v0 technique_name format, otherwise assumes v1 ability formatting.

async create_or_update_everything_adversary()
async static destroy()

Reset the caldera data directory and server state.

This creates a gzipped tarball backup of the data files tracked by caldera. Paths are preserved within the tarball, with all files having “data/” as the root.

async get_facts_from_source(fact_source_id)
async load_ability_file(filename, access)
async load_adversary_file(filename, access)
async load_data(plugins=())

Non-blocking read all the data sources to populate the object store

Returns:

None

async load_executors_from_list(executors: list)
async load_executors_from_platform_dict(platforms)
async load_objective_file(filename, access)
async load_requirements_from_list(requirements: list)
async load_source_file(filename, access)
async load_yaml_file(object_class, filename, access)
async locate(object_name, match=None)

Find all c_objects which match a search. Return all c_objects if no match.

Parameters:
  • object_name

  • match – dict()

Returns:

a list of c_object types

async reload_data(plugins=())

Blocking read all the data sources to populate the object store

Returns:

None

async remove(object_name, match)

Remove any c_objects which match a search

Parameters:
  • object_name

  • match – dict()

Returns:

async restore_state()

Restore the object database

Returns:

async save_state()

Save stored data to disk :return:

async search(value, object_name)
async store(c_object)

Accept any c_object type and store it (create/update) in RAM

Parameters:

c_object

Returns:

a single c_object

app.service.event_svc module

class app.service.event_svc.EventService

Bases: EventServiceInterface, BaseService

async fire_event(exchange=None, queue=None, timestamp=True, **callback_kwargs)

Fire an event :param event: The event topic and (optional) subtopic, separated by a ‘/’ :param callback_kwargs: Any additional parameters to pass to the event handler :return: None

async handle_exceptions(awaitable)
async notify_global_event_listeners(event, **callback_kwargs)

Notify all registered global event listeners when an event is fired.

Parameters:

event (str) – Event string (i.e. ‘<exchange>/<queue>’)

async observe_event(callback, exchange=None, queue=None)

Register a callback for a certain event. Callback is fired when an event of that type is observed.

Parameters:
  • callback (function) – Callback function

  • exchange (str) – event exchange

  • queue (str) – event queue

async register_global_event_listener(callback)

Register a global event listener that is fired when any event is fired.

Parameters:

callback (function) – Callback function

app.service.file_svc module

class app.service.file_svc.FileSvc

Bases: FileServiceInterface, BaseService

async add_special_payload(name, func)

Call a special function when specific payloads are downloaded

Parameters:
  • name

  • func

Returns:

static add_xored_extension(filename)
async compile_go(platform, output, src_fle, arch='amd64', ldflags='-s -w', cflags='', buildmode='', build_dir='.', loop=None)

Dynamically compile a go file :param platform: :param output: :param src_fle: :param arch: Compile architecture selection (defaults to AMD64) :param ldflags: A string of ldflags to use when building the go executable :param cflags: A string of CFLAGS to pass to the go compiler :param buildmode: GO compiler buildmode flag :param build_dir: The path to build should take place in :return:

async create_exfil_operation_directory(dir_name, agent_name)
async create_exfil_sub_directory(dir_name)
async find_file_path(name, location='')

Find the location on disk of a file by name. :param name: :param location: :return: a tuple: the plugin the file is found in & the relative file path

async get_file(headers)

Retrieve file :param headers: headers dictionary. The file key is REQUIRED. :type headers: dict or dict-equivalent :return: File contents and optionally a display_name if the payload is a special payload :raises: KeyError if file key is not provided, FileNotFoundError if file cannot be found

get_payload_name_from_uuid(payload)
get_payload_packer(packer)
static is_extension_xored(filename)
list_exfilled_files(startdir=None)
async read_file(name, location='payloads')

Open a file and read the contents :param name: :param location: :return: a tuple (file_path, contents)

read_result_file(link_id, location='data/results')

Read a result file. If file encryption is enabled, this method will return the plaintext content. Returns contents as a base64 encoded dictionary. :param link_id: The id of the link to return results from. :param location: The path to results directory. :return:

static remove_xored_extension(filename)
async save_file(filename, payload, target_dir, encrypt=True, encoding=None)
async save_multipart_file_upload(request, target_dir, encrypt=True)

Accept a multipart file via HTTP and save it to the server :param request: :param target_dir: The path of the directory to save the uploaded file to.

async static walk_file_path(path, target)
write_result_file(link_id, output, location='data/results')

Writes the results of a link execution to disk. If file encryption is enabled, the results file will contain ciphertext. :param link_id: The link id of the result being written. :param output: The content of the link’s output. :param location: The path to the results directory. :return:

app.service.knowledge_svc module

class app.service.knowledge_svc.KnowledgeService

Bases: KnowledgeServiceInterface, BaseService

async add_fact(fact, constraints=None)

Add a fact to the internal store

Parameters:
  • fact – Fact to add

  • constraints – any potential constraints

async add_relationship(relationship, constraints=None)

Add a relationship to the internal store

Parameters:
  • relationship – Relationship object to add

  • constraints – optional constraints on the use of the relationship

async add_rule(rule, constraints=None)

Add a rule to the internal store

Parameters:
  • rule – Rule object to add

  • constraints – dictionary containing fields to match on

async check_fact_exists(fact, listing=None)

Check to see if a fact already exists in the knowledge store, or if a listing is provided, in said listing

Parameters:
  • fact – The fact to check for

  • listing – Optional specific listing to examine

Returns:

Bool indicating whether or not the fact is already present

async delete_fact(criteria)

Delete a fact from the internal store

Parameters:

criteria – dictionary containing fields to match on

async delete_relationship(criteria)

Remove a relationship from the internal store

Parameters:

criteria – dictionary containing fields to match on

async delete_rule(criteria)

Remove a rule from the internal store

Parameters:

criteria – dictionary containing fields to match on

async destroy()

Clear out all data :return:

async get_fact_origin(fact)

Identify the place where a fact originated, either the source that loaded it or its original link

Parameters:

fact – Fact to get origin for (can be either a trait string or a full blown fact)

Returns:

tuple - (String of either origin source id or origin link id, fact origin type)

async get_facts(criteria, restrictions=None)

Retrieve a fact from the internal store

Parameters:

criteria – dictionary containing fields to match on

Returns:

list of facts matching the criteria

async get_meta_facts(meta_fact=None, agent=None, group=None)

Returns the complete set of facts associated with a meta-fact construct [In Development]

async get_relationships(criteria, restrictions=None)

Retrieve relationships from the internal store

Parameters:

criteria – dictionary containing fields to match on

Returns:

list of matching relationships

async get_rules(criteria, restrictions=None)

Retrieve rules from the internal store

Parameters:

criteria – dictionary containing fields to match on

Returns:

list of matching rules

async restore_state()

Load data from disk :return:

async save_state()

Save stored data to disk :return:

async update_fact(criteria, updates)

Update a fact in the internal store

Parameters:
  • criteria – dictionary containing fields to match on

  • updates – dictionary containing fields to replace

async update_relationship(criteria, updates)

Update a relationship in the internal store

Parameters:
  • criteria – dictionary containing fields to match on

  • updates – dictionary containing fields to modify

app.service.learning_svc module

class app.service.learning_svc.LearningService

Bases: LearningServiceInterface, BaseService

static add_parsers(directory)
async build_model()

The model is a static set of all variables used inside all ability commands This can be used to determine which facts - when found together - are more likely to be used together :return:

async learn(facts, link, blob, operation=None)

app.service.planning_svc module

class app.service.planning_svc.PlanningService(global_variable_owners=None)

Bases: PlanningServiceInterface, BasePlanningService

async add_ability_to_bucket(ability, bucket)

Adds bucket tag to ability

Parameters:
  • ability (Ability) – Ability to add bucket to

  • bucket (string) – Bucket to add to ability

async check_stopping_conditions(stopping_conditions, operation)

Check operation facts against stopping conditions

Checks whether an operation has collected the at least one of the facts required to stop the planner. Operation facts are checked against the list of facts provided by the stopping conditions. Facts will be validated based on the unique property, which is a combination of the fact trait and value.

Parameters:
  • stopping_conditions (list(Fact)) – List of facts which, if collected, should be used to terminate the planner

  • operation (Operation) – Operation to check facts on

Returns:

True if all stopping conditions have been met, False if all stopping conditions have not been met

Return type:

bool

async default_next_bucket(current_bucket, state_machine)

Returns next bucket in the state machine

Determine and return the next bucket as specified in the given bucket state machine. If the current bucket is the last in the list, the bucket order loops from last bucket to first.

Parameters:
  • current_bucket (string) – Current bucket execution is on

  • state_machine (list) – A list containing bucket strings

Returns:

Bucket name to execute

Return type:

string

async execute_planner(planner, publish_transitions=True)

Execute planner.

This method will run the planner, progressing from bucket to bucket, as specified by the planner.

Will stop execution for these conditions:
  • All buckets have been executed.

  • Planner stopping conditions have been met.

  • Operation was halted from external/UI input.

NOTE: Do NOT call wait-for-link-completion functions here. Let the planner decide to do that within its bucket functions, and/or there are other planning_svc utilities for the bucket functions to use to do so.

Parameters:
  • planner (LogicalPlanner) – Planner to run

  • publish_transitions (bool) – flag to publish bucket transitions as events to the event service

async exhaust_bucket(planner, bucket, operation, agent=None, batch=False, condition_stop=True)

Apply all links for specified bucket

Blocks until all links are completed, either after batch push, or separately for every pushed link.

Parameters:
  • planner (LogicalPlanner) – Planner to check for stopping conditions on

  • bucket (string) – Bucket to pull abilities from

  • operation (Operation) – Operation to run links on

  • agent (Agent, optional) – Agent to run links on, defaults to None

  • batch (bool, optional) – Push all bucket links immediately. Will check if operation has been stopped (by user) after all bucket links complete. ‘False’ will push links one at a time, and wait for each to complete. Will check if operation has been stopped (by user) after each single link is completed. Defaults to False

  • condition_stop (bool, optional) – Enable stopping of execution if stopping conditions are met. If set to False, the bucket will continue execution even if stopping conditions are met. defaults to True

Generate new links based on abilities

Creates new links based on given operation, agent, and abilities. Optionally, trim links using trim_links() to return only valid links with completed facts.

Parameters:
  • operation (Operation) – Operation to generate links on

  • agent (Agent) – Agent to generate links on

  • abilities (list(Ability)) – Abilities to generate links for

  • trim (bool, optional) – call trim_links() on list of links before returning, defaults to True

Returns:

A list of links

Return type:

list(Links)

Generate cleanup links

Generates cleanup links for given operation and agent. If no agent is provided, cleanup links will be generated for all agents in an operation.

Parameters:
  • operation (Operation) – Operation to generate links on

  • agent (Agent, optional) – Agent to generate links on, defaults to None

Returns:

a list of links

Generate links for use in an operation

For an operation and agent combination, create links (that can be executed). When no agent is supplied, links for all agents are returned.

Parameters:
  • operation (Operation) – Operation to generate links for

  • buckets (list(string), optional) – Buckets containing abilities. If ‘None’, get all links for given operation, agent, and trim setting. If a list of buckets is provided, then get links for specified buckets for given operation and trim setting. Defaults to None.

  • agent (Agent, optional) – Agent to generate links for, defaults to None

  • trim (bool, optional) – call trim_links() on list of links before returning, defaults to True

Returns:

a list of links sorted by score and atomic ordering

Sort links by score and atomic ordering in adversary profile

Parameters:

links (list(Link)) – List of links to sort

Returns:

Sorted links

Return type:

list(Link)

async update_stopping_condition_met(planner, operation)

Update planner stopping_condition_met property

Parameters:
  • planner (LogicalPlanner) – Planner to check stopping conditions and update

  • operation (Operation) – Operation to check facts on

Wait for link completion, update stopping conditions and (optionally) stop bucket execution if stopping conditions are met.

Parameters:
  • planner (LogicalPlanner) – Planner to check for stopping conditions on

  • operation (Operation) – Operation running links

  • link_ids (list(string)) – Links IDS to wait for

  • condition_stop (bool, optional) – Check and respect stopping conditions

Returns:

True if planner stopping conditions are met

Return type:

bool

app.service.rest_svc module

class app.service.rest_svc.RestService

Bases: RestServiceInterface, BaseService

async add_manual_command(access, data)
async build_potential_abilities(operation)
async construct_agents_for_group(group)
async create_operation(access, data)
async create_schedule(access, data)
async delete_ability(data)
async delete_adversary(data)
async delete_agent(data)
async delete_operation(data)
async display_objects(object_name, data)
async display_operation_report(data)
async display_result(data)
async download_contact_report(contact)
async find_abilities(paw)
async get_agent_configuration(data)
async list_exfil_files(data)
async list_payloads()
async persist_ability(access, data)

Persist abilities. Accepts single ability or bulk set of abilities. For bulk, supply dict of form {“bulk”: [{<ability>}, {<ability>},…]}.

async persist_adversary(access, data)

Persist adversaries. Accepts single adversary or bulk set of adversaries. For bulk, supply dict of form {“bulk”: [{<adversary>}, {<adversary>},…]}.

async persist_objective(access, data)

Persist objectives. Accepts single objective or a bulk set of objectives. For bulk, supply dict of form {“bulk”: [{objective}, …]}.

async persist_source(access, data)

Persist sources. Accepts single source or bulk set of sources. For bulk, supply dict of form {“bulk”: [{<sourc>}, {<source>},…]}.

async task_agent_with_ability(paw, ability_id, obfuscator, facts=())
async update_agent_data(data)
async update_chain_data(data)
async update_config(data)
async update_operation(op_id, state=None, autonomous=None, obfuscator=None)
async update_planner(data)

Update a new planner from either the GUI or REST API with new stopping conditions. This overwrites the existing YML file. :param data: :return: the ID of the created adversary