Canary Console API Python Client v1¶
Main Interface¶
- class Console(domain=None, api_key=None, timezone=<UTC>, debug=False, debug_level=10)¶
Initialize Console object. All API calls are made with this object
- Parameters:
domain – The domain of the Canary console
api_key – The API key received on your Canary console
timezone – The timezone to be used when displaying objects with datetime information.
pytztimezones to be useddebug – Debug flag for debugging requests/responses
debug_level – Debug level.
loggingdebug level used.logging.DEBUGwill display all requests and responses as well as response data.logging.INFOwill only log the requests and responses. The default islogging.DEBUG
- Raises:
ConfigurationError – Domain and/or API auth token not set
Usage:
>>> import canarytools >>> console = canarytools.Console(domain='console_domain', api_key='test_key') >>> import canarytools >>> import logging >>> console = canarytools.Console(debug=True)
- ping()¶
Tests the connection to the Canary Console
- Returns:
Returns
Trueif a connection could be established andFalseotherwise- Return type:
bool
Usage:
>>> import canarytools >>> console = canarytools.Console() >>> console.ping() True
Exceptions¶
All endpoints can raise the following errors:
- Errors:
InvalidAuthTokenError – API authorization token is invalid
ConnectionError – A connection error occurred while sending a request to the console
ConsoleError – A general exception occurred
More specific endpoint errors are listed in an endpoint’s documentation.
Devices Interface¶
API calls for managing devices. All methods endpoints are accessed by first initializing a console object and by making calls as follows:
console.devices.dead()
console.devices.get_device('0000000000231c23')
- class Devices(console)¶
Initialize the device
- Parameters:
console – The Console from which API calls are made
- all()¶
Get all registered devices
- Returns:
List of all devices
- Return type:
List of
Deviceobjects
Usage:
>>> import canarytools >>> devices = console.devices.all()
- dead()¶
Get all registered disconnected devices
- Returns:
List of dead devices
- Return type:
List of
Deviceobjects
Usage:
>>> import canarytools >>> devices = console.devices.dead()
- get_device(node_id, settings=False)¶
Get information on a particular device
- Parameters:
node_id – Get device with specific node id
- Returns:
Device with all information
- Return type:
A
Deviceobject- Raises:
DeviceNotFoundError – The device could not be found
Usage:
>>> import canarytools >>> device = console.devices.get_device(node_id='0000000000231c23')
Incidents Interface¶
API calls for managing incidents. All methods endpoints are accessed by first initializing a console object and by making calls as follows:
console.incidents.all()
console.incidents.delete()
- class Incidents(console)¶
Initialize Incidents Object
- acknowledge(node_id=None, src_host=None, older_than=None)¶
- Mark all incidents as acknowledged. Use parameters to filter which
incidents are acknowledged. Calling this method with no parameters specified will acknowledge all incidents.
- Parameters:
node_id (str) – Acknowledge incidents for a specific node NOTE: Cannot be used in conjunction with src_host
src_host (str) – Acknowledge incidents from a specific source IP address NOTE: Cannot be used in conjunction with node_id
older_than (str) – Acknowledge incidents older than the provided period. Periods are “[quantity][unit]”, where “[unit]” is one of ‘h’, ‘d’, ‘w’ (hours, days or weeks) e.g. ‘1h’ or ‘1d’ or ‘1w’
- Returns:
Result indicator of the API call
- Return type:
Resultobject- Raises:
InvalidParameterError – older_than was invalid / src_host and node_id cannot be used together
Usage:
>>> import canarytools >>> result = console.incidents.acknowledge() >>> import canarytools >>> result = console.incidents.acknowledge(older_than='1d')
- acknowledged(node_id=None, event_limit=None, newer_than=None)¶
Get list of all acknowledged incidents for a console.
- Parameters:
node_id – Get all acknowledged incidents for a specific node
event_limit – Specify the maximum number of event logs to be returned with the incident
newer_than (str) – limit to incidents newer than a date like ‘2019-12-25-12:00:00’ (UTC)
- Returns:
Return list of all acknowledged incidents
- Return type:
List of
Incidentobjects
Usage:
>>> import canarytools >>> incidents = console.incidents.acknowledged()
- all(node_id=None, event_limit=None, newer_than=None)¶
Get all incidents for this console.
- Parameters:
node_id – Get all incidents for a specific node
event_limit – Specify the maximum number of event logs to be returned with the incident.
newer_than (str) – limit to incidents newer than a date like ‘2019-12-25-12:00:00’ (UTC)
- Returns:
List of Incident objects
- Return type:
List of
Incidentobjects
Usage:
>>> import canarytools >>> incidents = console.incidents.all()
- delete(node_id=None, src_host=None, older_than=None)¶
- Delete all acknowledged incidents. Use parameters to filter which
incidents are deleted. Calling this method with no parameters specified will delete all acknowledged incidents.
- Parameters:
node_id (str) – Delete acknowledged incidents for a specific node NOTE: Cannot be used in conjunction with src_host
src_host (str) – Delete acknowledged incidents from a specific source IP address NOTE: Cannot be used in conjunction with node_id
older_than (str) – Delete acknowledged incidents older than the provided period. Periods are “[quantity][unit]”, where “[unit]” is one of ‘h’, ‘d’, ‘w’ (hours, days or weeks) e.g. ‘1h’ or ‘1d’ or ‘1w’
- Returns:
Result indicator of the API call
- Return type:
Resultobject- Raises:
InvalidParameterError – older_than was invalid / src_host and node_id cannot be used together
Usage:
>>> import canarytools >>> result = console.incidents.delete() >>> import canarytools >>> result = console.incidents.delete(node_id='00000000042c23a')
- get_incident(incident_id)¶
Get an Incident.
- Parameters:
incident – The id of the Incident
- Returns:
An Incident object
- Return type:
Incidentobject- Raises:
IncidentNotFoundError – Could not find incident with this id
Usage:
>>> import canarytools >>> incident = console.incidents.get_incident(incident_id='incident:ftplogin:0e4b47')
- unacknowledge(node_id=None, src_host=None, older_than=None)¶
- Mark all incidents as unacknowledged. Use parameters to filter which
incidents are unacknowledged. Calling this method with no parameters specified will unacknowledge all incidents.
- Parameters:
node_id (str) – Unacknowledge incidents for a specific node NOTE: Cannot be used in conjunction with src_host
src_host (str) – Unacknowledge incidents from a specific source IP address NOTE: Cannot be used in conjunction with node_id
older_than (str) – Unacknowledge incidents older than the provided period. Periods are “[quantity][unit]”, where “[unit]” is one of ‘h’, ‘d’, ‘w’ (hours, days or weeks) e.g. ‘1h’ or ‘1d’ or ‘1w’
- Returns:
Result indicator of the API call
- Return type:
Resultobject- Raises:
InvalidParameterError – older_than was invalid / src_host and node_id cannot be used together
Usage:
>>> import canarytools >>> result = console.incidents.unacknowledge() >>> import canarytools >>> result = console.incidents.unacknowledge(src_host='10.0.0.2')
- unacknowledged(node_id=None, event_limit=None, newer_than=None)¶
Get list of all unacknowledged incidents for a console.
- Parameters:
node_id – Get all unacknowledged incidents for a specific node
event_limit – Specify the maximum number of event logs to be returned with the incident.
newer_than (str) – limit to incidents newer than a date like ‘2019-12-25-12:00:00’ (UTC)
- Returns:
Return list of all unacknowledged Incidents
- Return type:
List of
Incidentobjects
Usage:
>>> import canarytools >>> incidents = console.incidents.unacknowledged()
Canarytokens Interface¶
API calls for managing Canarytokens. All methods endpoints are accessed by first initializing a console object and by making calls as follows:
console.tokens.all()
canarytools.tokens.create(memo='Desktop Token', kind=canarytools.CanaryTokenKinds.DOC_MSWORD)
- class CanaryTokens(console)¶
Initialize CanaryToken
- Parameters:
console – The Console object from which API calls are made
- all(include_endpoints=True)¶
Fetch all Canarytokens
- Returns:
A list of Canarytoken objects
- Return type:
List of
CanaryTokenobjects- Raises:
CanaryTokenError – Something went wrong while getting the CanaryTokens
Usage:
>>> import canarytools >>> tokens = console.tokens.all()
- create(memo, kind, flock_id=None, web_image=None, mimetype=None, cloned_web=None, browser_redirect_url=None, s3_source_bucket=None, s3_log_bucket=None, process_name=None, expected_referrer=None)¶
Create a new Canarytoken
- Parameters:
memo – Use this to remind yourself where you placed the Canarytoken
flock_id – Create token in different flock. Defaults to: ‘flock:default’
kind – The type of Canarytoken. Supported classes currently are: aws-id, cloned-web, cloned-css, dns, doc-msword, http, doc-msexcel, msexcel-macro, doc-msword, msword-macro, pdf-acrobat-reader, qr-code, sensitive-cmd, signed-exe, slack-api, web-image, windows-dir, wireguard
web_image – The path to an image file for use with web-image tokens.
mimetype – The type of image specified in web_image. e.g. ‘image/png’
cloned_web – Domain to be used in cloned-web tokens
browser_redirect_url – URL to redirect attackers to after triggering token (required when creating fast-redirect and slow-redirect tokens)
s3_source_bucket – S3 bucket to monitor for access (required when creating aws-s3 tokens)
s3_log_bucket – S3 bucket where logs will be stored (required when creating aws-s3 tokens)
process_name – Name of the process you want to monitor (required when creating sensitive-cmd tokens)
expected_referrer – Domain to be used in cloned-css tokens
- Returns:
A Result object
- Return type:
Resultobject- Raises:
InvalidParameterError – One of the parameters was invalid
CanaryTokenError – Something went wrong while creating the CanaryToken
Usage:
>>> import canarytools >>> result = console.tokens.create(memo='Desktop Token', kind=canarytools.CanaryTokenKinds.DOC_MSWORD)
- get_token(canarytoken)¶
Gets a single Canarytoken
- Parameters:
canarytoken – The key specifying a unique Canarytoken
- Returns:
A Canarytoken object
- Return type:
CanaryTokenobject- Raises:
CanaryTokenError – Could not find the CanaryToken
Usage:
>>> import canarytools >>> token = console.tokens.get_token(canarytoken='gv3xjl75b3nr7vwsmvxexcle0')
Flocks Interface¶
API calls for managing Flocks. All methods endpoints are accessed by first initializing a console object and by making calls as follows:
console.flocks.all()
canarytools.flocks.create(name='Cape Town')
- class Flocks(console)¶
Initialize Flock
- Parameters:
console – The Console object from which API calls are made
- all()¶
Fetch all Flocks
- Returns:
A list of Flock objects
- Return type:
List of
Flockobjects- Raises:
FlockError – Something went wrong while getting the Flocks
Usage:
>>> import canarytools >>> flocks = console.flocks.all()
- create(name)¶
Create a new Flock
- Parameters:
name – Use this to give your Flock a human readable name
- Returns:
A Result object
- Return type:
Resultobject- Raises:
FlockError – Something went wrong while creating the Flock
Usage:
>>> import canarytools >>> result = console.flocks.create(name='Cape Town')
Settings Interface¶
- class Settings(console)¶
Initialize Settings object
- Parameters:
console – The Console from which API calls are made
- is_ip_whitelisted(src_ip)¶
Is IP address Whitelisted
- Parameters:
src_ip – The IP address to be checked
- Returns:
Result object
- Return type:
Resultobject
Usage:
>>> import canarytools >>> devices = canarytools.settings.is_ip_whitelisted(src_ip='10.0.0.2')
- whitelist_ip_port(src_ip, dst_port=None)¶
Whitelist IP address and port
- Parameters:
src_ip – The IP to be whitelisted
dst_port – The destination port
- Returns:
Result object
- Return type:
Resultobject
Usage:
>>> import canarytools >>> devices = canarytools.settings.whitelist_ip_port(src_ip='10.0.0.2', dst_port='5000')
Updates Interface¶
- class Updates(console)¶
Initialize Update object
- Parameters:
console – The Console from which API calls are made
- list_updates()¶
List of available updates
- Returns:
List of Update objects
- Return type:
List of
Updateobjects
Usage:
>>> import canarytools >>> updates = canarytools.updates.list_updates()
- update_device(node_id, update_tag)¶
Update the device
- Parameters:
node_id – The node_id of the device to be updated
update_tag – The tag of the update to be updated to
- Returns:
A Result object
- Return type:
Resultobject- Raises:
UpdateError – Device update not permitted. Automatic updates are not configured. Or the update tag does not exist.
Usage:
>>> import canarytools >>> result = canarytools.updates.update_device(node_id='00000000ff798b93', update_tag='4ae023bdf75f14c8f08548bf5130e861')
Returned Classes¶
This section describes the objects returned from the various interfaces described above. These objects
represent console entities. For example, the Device object encapsulates all the information related to
a specific device. Operations can be performed on these objects too. See below for more information.
- class Device(console, data)¶
DeviceInitialize a Device object- Parameters:
console – The Console from which API calls are made
data – JSON data
- Attributes:
id (str) – The device identification code
name (str) – The name of the device
description (str) – Device description
uptime_age (datetime) – The amount of time the device has been online for
first_seen (datetime) – The first time the device came online
last_heartbeat_age (str) – Time since device last communicated with the console
uptime (long) – The amount of time (in seconds) the device has been online
need_reboot (bool) – Has the device been scheduled for a reboot?
reconnect_count (int) – Number of times the device has reconnected to the console
live (bool) – Is the device online?
mac_address (str) – The MAC address of the device
ignore_notifications_disconnect (bool) – Should the console ignore disconnects?
notify_after_horizon_reconnect (bool) – Notify console after horizon reconnects
sensor (str) – The sensor of the device
first_seen_age (str) – Time since the device was first seen i.e ‘2 days’
ignore_notifications_general (bool) – Ignore all notifications
device_id_hash (str) – Hash of the devices ID
service_count (int) – Number of services running on the device
ip_address (str) – The IP address of the device
ippers (str) – Personality(s) of the device
ghost (bool) – Is this a ghost device? i.e the device has been registered but hasn’t come online
unacknowleged_incidents (list) – List of unacknowledged incidents for the device
last_seen (datetime) – Time the device was last seen
- list_databundles()¶
Lists all DataBundles
- Returns:
List of DataBundle objects
- Return type:
List of
DataBundle
Usage:
>>> import canarytools >>> device = console.devices.get_device(node_id='0000000000231c23') >>> databundles = device.list_databundles()
- reboot()¶
Reboot the device
- Returns:
Result object
- Return type:
Resultobject- Raises:
DeviceNotFoundError – The device could not be found
Usage:
>>> import canarytools >>> device = console.devices.get_device(node_id='0000000000231c23') >>> result = device.reboot()
- refresh()¶
Refresh a Device object by pulling all changes
- Raises:
DeviceNotFoundError – The device could not be found
Usage:
>>> import canarytools >>> device = console.devices.get_device(node_id='0000000000231c23') >>> device.refresh()
- update(update_tag)¶
Update the device
- Parameters:
update_tag – The tag of the update
- Returns:
Result object
- Return type:
Resultobject- Raises:
UpdateError – Device update not permitted. Automatic updates are not configured. Or the update tag does not exist.
DeviceNotFoundError – The device could not be found
Usage:
>>> import canarytools >>> device = console.devices.get_device(node_id='0000000000231c23') >>> result = device.update(update_tag='4ae023bdf75f14c8f08548bf5130e861')
- class Incident(console, data)¶
Initialize Incident Object
- Attributes:
id (str) – The identification code of the incident
description (str) – The event description of the incident
flock_id (str) – The id of the flock this incident belongs to
acknowledged (bool) – Has the incident been acknowledged?
events (list) – List of events
logtype (str) – Log type
summary (str) – The event description of the incident
- Subclasses:
List of classes which extend this base class.
IncidentDeviceReconnected,IncidentDeviceDied,IncidentFTPLogin,IncidentHTTPLogin,IncidentHTTPLoad,IncidentSSHLogin,IncidentTelnetLogin,IncidentHTTPProxyRequest,IncidentMySQLLogin,IncidentMSSQLLogin,IncidentTFTPRequest,IncidentNmapOSScan,IncidentNmapNULLScan,IncidentNmapXMASScan,IncidentNTPMonlist,IncidentVNCLogin,IncidentGitCloneRequest,IncidentTCPBannerRequest,IncidentModbusRequest,IncidentRedisCommand,IncidentUser,IncidentSNMPRequest,IncidentSIPRequest,IncidentSMBFileOpen,IncidentCanarytokenTriggered,IncidentHostPortScan,IncidentNetworkPortScan,IncidentConsolidatedNetworkPortScan
- acknowledge()¶
Mark incident as acknowledged
- Returns:
Result indicator of the API call
- Return type:
Resultobjects
Usage:
>>> import canarytools >>> incident = console.incidents.get_incident(incident_id='incident:ftplogin:0e4b47') >>> result = incident.acknowledge()
- delete()¶
Delete incident
- Returns:
Result indicator of the API call
- Return type:
Resultobject
Usage:
>>> import canarytools >>> incident = console.incidents.get_incident(incident_id='incident:ftplogin:0e4b47') >>> result = incident.delete()
- refresh()¶
Refresh object after API calls to keep up-to-date
Usage:
>>> import canarytools >>> incident = console.incidents.get_incident(incident_id='incident:ftplogin:0e4b47') >>> incident.refresh()
- class CanaryToken(console, data)¶
Initialize a CanaryToken object
- Parameters:
console – The Console from which the API calls are made
data – JSON data containing CanaryToken attributes
- delete()¶
Delete a Canarytoken
- Returns:
A Result object
- Return type:
Resultobject- Raises:
CanaryTokenError – Something went wrong while deleting the CanaryToken
Usage:
>>> import canarytools >>> token = console.tokens.get_token(canarytoken='gv3xjl75b3nr7vwsmvxexcle0') >>> result = token.delete()
- disable()¶
Disable a Canarytoken
- Returns:
A Result object
- Return type:
Resultobject- Raises:
CanaryTokenError – Something went wrong while disabling the CanaryToken
Usage:
>>> import canarytools >>> token = console.tokens.get_token(canarytoken='gv3xjl75b3nr7vwsmvxexcle0') >>> result = token.disable()
- download(filename=None)¶
Download a Canarytoken
- Parameters:
filename – Optional target filename. The console should provide a default value.
- Returns:
The filename written to.
- Return type:
str- Raises:
CanaryTokenError – Something went wrong while downloading the CanaryToken.
ValueError – This token doesn’t have a default filename, you need to provide one.
Usage:
>>> import canarytools >>> token = console.tokens.create(memo="Excel file on Jim's Laptop", kind="doc-msexcel") >>> token.download(filename="Payroll.xslx") OR >>> filename = token.download()
- enable()¶
Enable a Canarytoken
- Returns:
A Result object
- Return type:
Resultobject- Raises:
CanaryTokenError – Something went wrong while enabling the CanaryToken
Usage:
>>> import canarytools >>> token = console.tokens.get_token(canarytoken='gv3xjl75b3nr7vwsmvxexcle0') >>> result = token.enable()
- update(memo)¶
Update a Canarytoken memo
- Parameters:
memo – The new memo to be used
- Returns:
A Result object
- Return type:
Resultobject- Raises:
CanaryTokenError – Something went wrong while updating the CanaryToken
InvalidParameterError – The memo parameter is invalid
Usage:
>>> import canarytools >>> token = console.tokens.get_token(canarytoken='gv3xjl75b3nr7vwsmvxexcle0') >>> result = token.update(memo='Token in downloads folder')
- class Flock(console, data)¶
Initialize a Flock object
- Attributes:
flock_id (str) – The id the flock
name (str) – The name of the flock
- Parameters:
console – The Console from which the API calls are made
data – JSON data containing Flock attributes
- delete()¶
Delete a Flock
- Returns:
A Result object
- Return type:
Resultobject- Raises:
FlockError – Something went wrong while deleting the Flock
Usage:
>>> import canarytools >>> result = console.flocks.delete()
- rename(name)¶
Rename a Flock
- Parameters:
name – The new name to be used
- Returns:
A Result object
- Return type:
Resultobject- Raises:
FlockError – Something went wrong while updating the Flock
Usage:
>>> import canarytools >>> flocks = console.flocks.all() >>> for flock in flocks: >>> if flock.flock_id == 'flock:id_im_looking_to_rename': >>> flock.rename("New name")
- class Update(console, data)¶
Initialize an Update object
- Parameters:
console – The Console from which API calls are made
data – JSON data
- Attributes:
supported_versions (list) –List of Canary versions that support this update
description (str) – Description of the update
filename (str) – Name of update file
ignore (bool) – Should this update be ignored?
tag (str) – Update tag. Used to uniquely identify an update.
version (str) – Version to which the Canary is updated.
- class DataBundle(console, data)¶
Initilaize a DataBundle object
- Parameters:
console – The Console from which API calls are made
data – JSON data
- Attributes:
settings_key (str) – Key that identifies this DataBundle
req_len (str) – The length of the request
bytes_copied (int) – Number of bytes sent in this DataBundle
name (str) – The name or type of this DataBundle
checksum (str) – Checksum of the DataBundle
ended_time (int) – Time the DataBundle completed in epoch time
tag (str) – The DataBundles tag
type_ (str) – The type of the DataBundle
bundle_size (int) – Size of theD DataBundle in bytes
state (str) – The state the DataBundle is in
node_id (str) – The id of the device for which this DataBundle is sent
started_time (int) – Time the DataBundle started being sent, in epoch time
created_time (int) – Time the DataBundle was created, in epoch time
updated_time (int) – Time of the update in epoch time
- class Result(console, data)¶
Initialize Result. To be used as a result indicator
- Parameters:
console – The Console from which API calls are made
data – JSON data
- Attributes:
result – The result of the call. Usually ‘success’ or ‘error’.
- class Event(console, data)¶
An event contains all the details relating to a incident occurence.
- Parameters:
console – The Console from which API calls are made
data – JSON data
For a more detailed list of event attributes see Incidents and event attributes