Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.40.6 #208

Merged
merged 12 commits into from
Oct 24, 2022
Merged

4.40.6 #208

merged 12 commits into from
Oct 24, 2022

Conversation

lifehackjim
Copy link
Contributor

4.40.6

Feature: Run Enforcement against manual selection of Asset IDs

Axonshell changes

New commands added to groups axonshell devices, axonshell users,
and axonshell vulnerabilities:

  • run-enforcement-from-jsonl: Grab Asset IDs from a JSONL file and run
    an Enforcement Set against them.
# Notes:
# 1) --path must be a JSONL file with one dictionary per line

# Example:
# 1) Get assets in JSONL format:
axonshell devices get --export-format json --json-flat
  --export-file data.jsonl --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the JSON file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test --verified
  • run-enforcement-from-json: Grab Asset IDs from a JSON file and run an
    Enforcement Set against them.
# Notes:
# 1) --path must be a JSON file containing a list of dictionaries

# Example:
# 1) Get assets in JSON format:
axonshell devices get --export-format json
  --export-file data.json --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the JSON file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-json --path data.json --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-json --path data.json --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-json --path data.json --eset test --verified
  • run-enforcement-from-csv: Grab Asset IDs from a CSV file and run an
    Enforcement Set against them.
# Notes:
# 1) --path must be a CSV file with headers

# Example:
# 1) Get assets in CSV format:
axonshell devices get --export-format csv
  --export-file data.csv --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the CSV file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-csv --path data.csv --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-csv --path data.csv --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-csv --path data.csv --eset test --verified
  • run-enforcement-from-text: Grab Asset IDs from any old text file and run an
    Enforcement Set against them.
# Notes:
# 1) --path must be a text file with valid asset IDs
# 2) All lines will have any non alpha-numeric characters removed from them and
#    if a 32 character alpha numeric string is found it is considered an Asset ID.

# Example:
# 1) Get assets in JSON format then use jq to extract the IDs to a text file:
axonshell devices get --export-format json
  --export-file data.json --export-overwrite --wiz simple 'os.type equals windows'
jq '.[].internal_axon_id' data.json > data.txt
# 2) Run an enforcement set against the asset IDs in the text file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-text --path data.txt --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-text --path data.txt --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-text --path data.txt --eset test --verified

API Client library changes

New Methods for client.devices/client.users/client.vulnerabilities:

  • run_enforcement: Run an enforcement set against a manually selected list of assets.
'''Get a list of assets from a query and manually extract the IDs.
We know assets are valid because we just got them, so we pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
ITEMS = apiobj.get(wiz_entries=WIZ)
IDS = [x['internal_axon_id'] for x in ITEMS]
runner = apiobj.run_enforcement(eset=ESET, ids=IDS, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=None,
)
'''
  • run_enforcement_from_items: Get Asset IDs from a list of dicts or strs and run
    an Enforcement Set against them.
'''Get a list of assets from a query and use the grabber get the IDs.
We know assets are valid because we just got them, so we pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
ITEMS = apiobj.get(wiz_entries=WIZ)
runner = apiobj.run_enforcement_from_items(eset=ESET, items=ITEMS, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source=None,
),
)
'''
  • run_enforcement_from_json: Get Asset IDs from a JSON string with a list of
    dicts and run an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a JSON str
then run an enforcement against all asset IDs from the JSON str.
We know assets are valid because we just got them, so we pass verified=True.
'''
import io
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
FH = io.StringIO()
z = apiobj.get(wiz_entries=WIZ, export="json", export_fd=FH, export_fd_close=False)
FH.seek(0)
ITEMS = FH.getvalue()
runner = apiobj.run_enforcement_from_json(eset=ESET, items=ITEMS, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_json items type=str, length=15519 post_load type=list, length=31',
),
)
'''
'''Get a list of assets from a query and export the assets to a JSON file
then run an enforcement against all asset IDs from the JSON file.
We know assets are valid because we just got them, so we pass verified=True.
'''
import pathlib
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
PATH = pathlib.Path("data.json")
z = apiobj.get(wiz_entries=WIZ, export="json", export_file=PATH, export_overwrite=True)
runner = apiobj.run_enforcement_from_json(eset=ESET, items=PATH, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_json items type=PosixPath, length=None post_load type=list, length=31',
),
)
'''
  • run_enforcement_from_jsonl: Get Asset IDs from a JSONL string with one dict
    per line and run an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a JSONL str
then run an enforcement against all asset IDs from the JSONL str.
We know assets are valid because we just got them, so we pass verified=True.
'''
import io
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
FH = io.StringIO()
z = apiobj.get(
  wiz_entries=WIZ, export="json", json_flat=True, export_fd=FH, export_fd_close=False)
FH.seek(0)
runner = apiobj.run_enforcement_from_jsonl(eset=ESET, items=FH, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_jsonl items type=StringIO, length=None post_load type=list, length=31',
),
)
'''
'''Get a list of assets from a query and export the assets to a JSONL file
then run an enforcement against all asset IDs from the JSONL file.
We know assets are valid because we just got them, so we pass verified=True.
'''
import pathlib
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
PATH = pathlib.Path("data.jsonl")
z = apiobj.get(
  wiz_entries=WIZ, export="json", json_flat=True, export_file=PATH, export_overwrite=True)
runner = apiobj.run_enforcement_from_jsonl(eset=ESET, items=PATH, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_jsonl items type=PosixPath, length=None post_load type=list, length=31',
),
)
'''
  • run_enforcement_from_csv: Get Asset IDs from a CSV string and run
    an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a JSONL str
then run an enforcement against all asset IDs from the JSONL str.
We know assets are valid because we just got them, so we pass verified=True.
'''
from axonius_api_client.tools import bom_strip
import io
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
FH = io.StringIO()
z = apiobj.get(wiz_entries=WIZ, export="csv", export_fd=FH, export_fd_close=False)
FH.seek(0)
ITEMS = bom_strip(FH.getvalue())
runner = apiobj.run_enforcement_from_csv(eset=ESET, items=ITEMS, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=33,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_csv items type=str, length=6556 post_load type=list, length=33',
),
)
'''
'''Get a list of assets from a query and export the assets to a CSV file
then run an enforcement against all asset IDs from the CSV file.
We can also use a CSV file exported from the GUI.
We know assets are valid because we just got them, so we pass verified=True.
'''
import pathlib
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
PATH = pathlib.Path("data.csv")
z = apiobj.get(wiz_entries=WIZ, export="csv", export_file=PATH, export_overwrite=True)
runner = apiobj.run_enforcement_from_csv(eset=ESET, items=PATH, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=33,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_csv items type=PosixPath, length=None post_load type=list, length=33',
),
)
'''
  • run_enforcement_from_text: Get Asset IDs from a text string and run
    an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a text file
then run an enforcement against all asset IDs from the text file.
All lines will have any non alpha-numeric characters removed from them and if a
32 character alpha numeric string is found it is considered an Asset ID.
We know assets are valid because we just got them, so we pass verified=True.
'''
import pathlib
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows"  # "query of assets to target"
ESET = "test"  # "name or uuid of enforcement set"
PATH = pathlib.Path("data.txt")
ASSETS = apiobj.get(wiz_entries=WIZ)
IDS = [x['internal_axon_id'] for x in ASSETS]
PATH.write_text('\n'.join(IDS))
runner = apiobj.run_enforcement_from_text(eset=ESET, items=PATH, verified=True)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_text items type=PosixPath, length=None',
),
)
'''
  • run_enforcement_from_json_path: Get Asset IDs from a JSON file with a list of
    dicts and run an Enforcement Set against them.
'''Run an enforcement against all asset IDs from a JSON file.
We are unsure if Asset IDs are still valid for this instance so
we do not pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
PATH = "data.json"
ESET = "test"  # "name or uuid of enforcement set"
runner = apiobj.run_enforcement_from_json_path(eset=ESET, path=PATH)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=31,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_json_path /Users/jimbo/gh/Axonius/axonapi/data.json /
from_json items type=PosixPath, length=None post_load
type=list, length=31',
),
)
'''
  • run_enforcement_from_jsonl_path: Get Asset IDs from a JSONL file with one
    dict per line and run an Enforcement Set against them.
'''Run an enforcement against all asset IDs from a JSONL file.
We are unsure if Asset IDs are still valid for this instance so
we do not pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
PATH = "data.jsonl"
ESET = "test"  # "name or uuid of enforcement set"
runner = apiobj.run_enforcement_from_jsonl_path(eset=ESET, path=PATH)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=31,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_jsonl_path /Users/jimbo/gh/Axonius/axonapi/data.jsonl /
from_jsonl items type=PosixPath, length=None post_load type=list, length=31',
),
)
'''
  • run_enforcement_from_csv_path: Get Asset IDs from a CSV file and run
    an Enforcement Set against them.
'''Run an enforcement against all asset IDs from a JSONL file.
We are unsure if Asset IDs are still valid for this instance so
we do not pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
PATH = "data.csv"
ESET = "test"  # "name or uuid of enforcement set"
runner = apiobj.run_enforcement_from_csv_path(eset=ESET, path=PATH)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=31,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=33,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_csv_path /Users/jimbo/gh/Axonius/axonapi/data.csv /
from_csv items type=PosixPath, length=None post_load type=list, length=33',
),
)
'''
  • run_enforcement_from_text_path: Get Asset IDs from a text file and run
    an Enforcement Set against them.
'''Run an enforcement against all asset IDs from a text file.
All lines will have any non alpha-numeric characters removed from them and if a
32 character alpha numeric string is found it is considered an Asset ID.
We are unsure if Asset IDs are still valid for this instance so
we do not pass verified=True.
'''
client = globals()['client']  # instance of axonius_api_client.Connect
apiobj = client.devices  # client.devices, client.users, or client.vulnerabilities
PATH = "data.txt"
ESET = "test"  # "name or uuid of enforcement set"
runner = apiobj.run_enforcement_from_text_path(eset=ESET, path=PATH)
print(runner)
'''
Runner(
  state='Ran Enforcement Set against 31 supplied Asset IDs',
  eset='test',
  executed=True,
  count_ids=31,
  count_result=None,
  verified=True,
  verify_count=True,
  prompt=False,
  grabber=Grabber(
  count_supplied=31,
  count_found=31,
  do_echo=True,
  do_raise=False,
  source='from_text_path /Users/jimbo/gh/Axonius/axonapi/data.txt /
from_text items type=PosixPath, length=None post_load type=generator, length=None',
),
)
'''
  • _run_enforcement: Direct API method to run an Enforcement Set against a
    list of Asset IDs

New classes:

  • axonius_api_client.api.assets.runner.Runner: verify Asset IDs and run
    an enforcement set against them
  • axonius_api_client.parsers.grabber.Grabber: grab asset IDs from various
    export formats (csv, json, jsonl, text)
  • axonius_api_client.constants.fields.AXID: global constant for working with
    Asset IDs (ala internal_axon_id)

New Schemas:

  • axonius_api_client.api.json_api.assets.RunEnforcementRequestSchema
  • axonius_api_client.api.json_api.assets.RunEnforcementRequest
  • axonius_api_client.api.json_api.selection.IdSelectionSchema
  • axonius_api_client.api.json_api.selection.IdSelection

Feature: support semi-colon instead of comma as CSV delimiter for env vars

  • prepending the env var value with "semi:" will now
    use ; instead of , as the delimiter for CSV strings passed to AX_COOKIES
    and AX_HEADERS, i.e.:
export AX_HEADERS="semi:key1=value1;key2=value2"

Bugfix: Role permissions throw KeyError for some RBAC category actions

  • Fallback to False if an action for an RBAC category is not defined on a roles permissions

Bugfix: Reduce log output

  • Reduced log spam from Http to make logs easier to read

Jim Olsen and others added 12 commits September 16, 2022 12:07
- New module: axonius_api_client.api.assets.runner
- fix for RBAC permissions when an action for a category exists but is not defined in role
- reduce log spam from certificates/etc
- New commands for axonshell devices/users/vulnerabilities:
 - run-enforcement-from-jsonl
 - run-enforcement-from-json
 - run-enforcement-from-csv
 - run-enforcement-from-text
…election

Feature/enforcement run manual selection
@lifehackjim lifehackjim merged commit 91f4a10 into master Oct 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants