Esempio n. 1
0
def put_file_command(api_client: CBCloudAPI, device_id: str,
                     destination_path: str, file_id: str):
    session = api_client.select(platform.Device, device_id).lr_session()
    path = demisto.getFilePath(file_id)
    with open(path['path'], 'rb') as _file:
        session.put_file((path['name'], _file), destination_path)
    return f'File: {file_id} is successfully put to the remote destination {destination_path}'
def list_processes_command(api_client: CBCloudAPI, device_id: str,
                           limit: Union[int, str]):
    session = api_client.select(platform.Device, device_id).lr_session()
    processes = session.list_processes()
    if not processes:
        return 'There is no active processes in the remote device'

    processes, partial_res_msg = get_limited_results(
        original_results=processes, limit=limit)

    headers = ['path', 'pid', 'command_line', 'username']
    processes_readable = [
        dict(path=process['process_path'],
             pid=process['process_pid'],
             command_line=process['process_cmdline'],
             user_name=process['process_username']) for process in processes
    ]
    context_entry = dict(device_id=device_id, processes=processes)

    readable_output = tableToMarkdown(
        f'Carbon Black Defense Live Response Processes{partial_res_msg}',
        headers=headers,
        t=processes_readable,
        headerTransform=string_to_table_header,
        removeNull=True)
    return CommandResults(
        'CarbonBlackDefenseLR.Processes',
        outputs_key_field='device_id',
        outputs=context_entry,
        readable_output=readable_output,
        raw_response=processes,
    )
def get_reg_values_command(api_client: CBCloudAPI, device_id: str,
                           reg_path: str, limit: Union[int, str]):
    """Get the values of the given registry key in the remote device"""
    session = api_client.select(platform.Device, device_id).lr_session()
    values = session.list_registry_values(reg_path)
    if not values:
        return f'The key: {reg_path} does not contain any value'

    values, partial_res_msg = get_limited_results(original_results=values,
                                                  limit=limit)

    context_entry = dict(key=reg_path, values=values, device_id=device_id)
    human_readable = [
        dict(name=val['registry_name'],
             type=val['registry_type'],
             data=val['registry_data']) for val in values
    ]

    readable_output = tableToMarkdown(
        f'Carbon Black Defense Live Response Registry key values{partial_res_msg}',
        human_readable,
        headers=['name', 'type', 'data'],
        headerTransform=string_to_table_header,
        removeNull=True)

    return CommandResults(
        outputs_prefix='CarbonBlackDefenseLR.RegistryValues',
        outputs_key_field=['device_id', 'key'],
        outputs=context_entry,
        readable_output=readable_output,
        raw_response=values,
    )
def list_directory_command(api_client: CBCloudAPI, device_id: str,
                           directory_path: str, limit: Union[int, str]):
    """
       Get list of directory entries in the remote device

       :param api_client: The API client

       :param device_id: The device id

       :param directory_path: Directory to list. This parameter should end with the path separator

       :param limit: Limit the result entries count to be the given limit

       :return: CommandResult represent the API command result
       :rtype: ``CommandResults``
    """
    session = api_client.select(platform.Device, device_id).lr_session()
    items = [
        item for item in session.list_directory(directory_path)
        if item['filename'] not in IGNORED_FILES_IN_DIR
    ]
    items, partial_res_msg = get_limited_results(original_results=items,
                                                 limit=limit)

    directories_readable = []
    context_entry_items = []
    headers = ['name', 'type', 'date_modified', 'size']
    for item in items:
        context_entry_items.append(item)
        directories_readable.append({
            'name':
            item['filename'],
            'type':
            'Directory' if item['attributes']
            and 'DIRECTORY' in item['attributes'] else 'File',
            'date_modified':
            item['last_write_time'],
            'size':
            item['size'],
        })

    context_entry = dict(content=context_entry_items,
                         device_id=device_id,
                         directory_path=directory_path)

    readable_output = tableToMarkdown(
        f'Directory of {directory_path}{partial_res_msg}',
        t=directories_readable,
        headers=headers,
        headerTransform=string_to_table_header,
        removeNull=True)

    return CommandResults(
        outputs_prefix='CarbonBlackDefenseLR.Directory',
        outputs_key_field=['device_id', 'directory_path'],
        outputs=context_entry,
        readable_output=readable_output,
        raw_response=items,
    )
def kill_process_command(api_client: CBCloudAPI, device_id: str,
                         pid: Union[int, str]):
    session = api_client.select(platform.Device, device_id).lr_session()
    success = session.kill_process(arg_to_number(
        pid))  # the API returns True if success, False if failure
    if not success:
        return_error(f'Can not kill the process: {pid}')

    return f'The process: {pid} was killed successfully.'
Esempio n. 6
0
def _create_feed(auth_token):
    """Create a Feed to use for testing"""
    cb = CBCloudAPI(url="https://defense-eap01.conferdeploy.net",
                    token=auth_token,
                    org_key="WNEXFKQ7")
    # Feed Creation
    feedinfo = {
        "name": "Temporary BAT Load Test Feed",
        "owner": "DevRel",
        "provider_url": "https://developer.carbonblack.com",
        "summary": "BAT Load test feed",
        "category": "None",
        "access": "private"
    }
    feed_dict = {"feedinfo": feedinfo, "reports": []}
    feed = cb.create(Feed, feed_dict)
    feed.save()
    return feed._info
    def _init_components(self):
        """
        Initialize the components of the toolkit, injecting their dependencies as they're created.

        Returns:
            dict: A dict containing all the references to the top-level components.

        """
        try:
            state_manager = StateManager(self.config)
        except:
            log.error(
                "Failed to create State Manager. Check your configuration")
            log.debug(traceback.format_exc())
            state_manager = None

        cbc_api = self.cbc_api
        if cbc_api is None:
            cbc_api = CBCloudAPI(
                url=self.config.get("carbonblackcloud.url"),
                org_key=self.config.get("carbonblackcloud.org_key"),
                token=self.config.get("carbonblackcloud.api_token"),
                ssl_verify=self.config.get("carbonblackcloud.ssl_verify"))

        deduplicate = DeduplicationComponent(self.config, state_manager)
        ingest = IngestionComponent(self.config, cbc_api, state_manager)

        results_engine = EngineResults(self.config.get("engine.name"),
                                       state_manager, cbc_api)
        if self.config.get("engine.type") == "local":
            try:
                engine_manager = LocalEngineManager(self.config)
            except:
                log.error(
                    "Failed to create Local Engine Manager. Check your configuration"
                )
                log.debug(traceback.format_exc())
                engine_manager = None
        else:
            engine_manager = None

        return {
            "deduplicate":
            deduplicate,
            "ingest":
            ingest,
            "engine_manager":
            engine_manager,
            "results_engine":
            results_engine,
            "state_manager":
            state_manager,
            "success":
            True if state_manager is not None and engine_manager is not None
            else False
        }
def set_reg_value_command(api_client: CBCloudAPI, device_id: str,
                          reg_path: str, value_data: Any, value_type: str,
                          overwrite: Union[bool, str]):

    session = api_client.select(platform.Device, device_id).lr_session()
    session.set_registry_value(reg_path,
                               value_data,
                               overwrite=argToBoolean(overwrite),
                               value_type=value_type)
    return f'Value was set to the reg key: {reg_path} successfully.'
def delete_reg_key_command(api_client: CBCloudAPI,
                           device_id: str,
                           reg_path: str,
                           force: Union[bool, str] = False):
    """Delete a registry key on the remote machine, the key must be without any sub keys"""

    session = api_client.select(platform.Device, device_id).lr_session()
    if argToBoolean(force):
        delete_reg_key_recursive(session, reg_path)
    else:
        session.delete_registry_key(reg_path)

    return f'Registry key: {reg_path} was deleted successfully.'
def get_file_command(api_client: CBCloudAPI,
                     device_id: str,
                     source_path: str,
                     timeout: Union[int, str] = None,
                     delay: Union[float, str] = None):
    session = api_client.select(platform.Device, device_id).lr_session()

    if delay:
        delay = float(delay)
    file_data = session.get_file(file_name=source_path,
                                 timeout=arg_to_number(timeout),
                                 delay=delay)
    file_name = ntpath.split(source_path)[1]
    return fileResult(file_name, file_data)
def get_cb_cloud_object(args):
    """
    Based on parsed command line arguments, create and return a CBCloudAPI object.

    Args:
        args (Namespace): Arguments parsed from the command line.

    Returns:
        CBCloudAPI: The CBCloudAPI object.
    """
    if args.verbose:
        logging.basicConfig()
        logging.getLogger("cbc_sdk").setLevel(logging.DEBUG)
        logging.getLogger("__main__").setLevel(logging.DEBUG)

    if args.cburl and args.apitoken and args.orgkey:
        cb = CBCloudAPI(url=args.cburl,
                        token=args.apitoken,
                        org_key=args.orgkey,
                        ssl_verify=(not args.no_ssl_verify))
    else:
        cb = CBCloudAPI(profile=args.profile)

    return cb
def main():
    commands = {
        'test-module': command_test_module,
        f'{CBD_LR_PREFIX}-file-put': put_file_command,
        f'{CBD_LR_PREFIX}-file-get': get_file_command,
        f'{CBD_LR_PREFIX}-file-delete': delete_file_command,
        f'{CBD_LR_PREFIX}-reg-key-create': create_reg_key_command,
        f'{CBD_LR_PREFIX}-reg-value-set': set_reg_value_command,
        f'{CBD_LR_PREFIX}-reg-sub-keys': list_reg_sub_keys_command,
        f'{CBD_LR_PREFIX}-reg-get-values': get_reg_values_command,
        f'{CBD_LR_PREFIX}-reg-value-delete': delete_reg_value_command,
        f'{CBD_LR_PREFIX}-reg-key-delete': delete_reg_key_command,
        f'{CBD_LR_PREFIX}-directory-listing': list_directory_command,
        f'{CBD_LR_PREFIX}-ps': list_processes_command,
        f'{CBD_LR_PREFIX}-kill': kill_process_command,
        f'{CBD_LR_PREFIX}-execute': create_process_command,
        f'{CBD_LR_PREFIX}-memdump': memdump_command
    }

    params = demisto.params()
    url = params.get('url')
    cb_custom_key = params.get('custom_key')
    cb_custom_id = params.get('custom_id')
    cb_org_key = params.get('org_key')
    verify_certificate = not params.get('insecure', True)
    handle_proxy()

    command = demisto.command()
    if command not in commands:
        raise NotImplementedError(f'Command: {command} not implemented')
    demisto.debug(f'Command being called is {command}')
    try:
        credentials = dict(url=url,
                           ssl_verify=verify_certificate,
                           token=f'{cb_custom_key}/{cb_custom_id}',
                           org_key=cb_org_key)
        api = CBCloudAPI(**credentials)
        result = commands[command](api_client=api,
                                   **demisto.args())  # type: ignore
        return_results(result)

    # Log exceptions and return errors
    except Exception as e:
        demisto.error(traceback.format_exc())  # print the traceback
        return_error(f'Failed to execute {command} command.\nError:\n{str(e)}')
def create_process_command(api_client: CBCloudAPI,
                           device_id: str,
                           command_string: str,
                           wait_timeout: Union[int, str] = 30,
                           wait_for_output: Union[bool, str] = True,
                           wait_for_completion: Union[bool, str] = True,
                           **additional_params):
    # additional_param may include: remote_output_file_name: str, working_directory: str

    session = api_client.select(platform.Device, device_id).lr_session()
    process_results_bytes = session.create_process(
        command_string=command_string,
        wait_timeout=arg_to_number(wait_timeout),
        wait_for_output=argToBoolean(wait_for_output),
        wait_for_completion=argToBoolean(wait_for_completion),
        **additional_params,
    )
    process_results_str = None
    if wait_for_output and process_results_bytes:
        process_results_str = process_results_bytes.decode('utf-8')
        human_readable = process_results_str
    else:
        human_readable = f'Process: {command_string} was successfully executed.'

    context_output = dict(
        return_value=process_results_str,
        device_id=device_id,
        command_string=command_string,
    )

    return CommandResults(
        outputs_prefix='CarbonBlackDefenseLR.ExecuteProcess',
        outputs_key_field=['device_id', 'command_string'],
        outputs=context_output,
        readable_output=human_readable,
        raw_response=process_results_str,
    )
def list_reg_sub_keys_command(api_client: CBCloudAPI, device_id: str,
                              reg_path: str, limit: Union[int, str]):
    session = api_client.select(platform.Device, device_id).lr_session()
    sub_keys = session.list_registry_keys_and_values(reg_path).get(
        'sub_keys', [])
    if not sub_keys:
        return f'The key: {reg_path} does not contain any sub keys'

    sub_keys, partial_res_msg = get_limited_results(original_results=sub_keys,
                                                    limit=limit)

    context_entry = dict(sub_keys=sub_keys, device_id=device_id, key=reg_path)
    human_readable = tableToMarkdown(
        name=
        f'Carbon Black Defense Live Response Registry sub keys{partial_res_msg}',
        t=sub_keys,
        headers=['Sub keys'])
    return CommandResults(
        outputs_prefix='CarbonBlackDefenseLR.RegistrySubKeys',
        outputs_key_field=['device_id', 'key'],
        outputs=context_entry,
        readable_output=human_readable,
        raw_response=sub_keys,
    )
def cbc_cloud_api():
    """Create CBCloudAPI singleton."""
    return CBCloudAPI(url="https://example.com",
                      org_key="test",
                      token="abcd/1234",
                      ssl_verify=False)
def delete_file_command(api_client: CBCloudAPI, device_id: str,
                        source_path: str):
    session = api_client.select(platform.Device, device_id).lr_session()
    session.delete_file(filename=source_path)
    return f'The file: {source_path} was deleted successfully.'
def memdump_command(api_client: CBCloudAPI, device_id: str, target_path: str):
    session = api_client.select(platform.Device, device_id).lr_session()
    session.start_memdump(remote_filename=target_path).wait()
    return f'Memory was successfully dumped to {target_path}.'
Esempio n. 18
0
from cbc_sdk import CBCloudAPI
from cbapi.psc.defense import *


##### Call Yaml for configs #####

# Call yaml to pull in configs for proper hygiene
with open('servicenow.yaml') as f:
    y = yaml.load(f)

###### Creds From Yaml #######

# Input your cbapi profile from yaml - make sure the connector type is 'SIEM'

#!!! Use the below if using the new cb-sdk -- recommended !!!#
cb = CBCloudAPI(profile=y['creds']['cb']['cb_profile'])

#!!! Use the below profile, and comment out the above, if using the legacy cbapi !!!#
#cb = CbDefenseAPI(profile=y['creds']['cb']['cb_profile'])

# SN user and password
user = y['creds']['sn']['sn_user']
pwd = y['creds']['sn']['sn_pwd']

###### Variables ######

# SN inbound webservice api url
sn_url = y['creds']['sn']['sn_url']

# Set proper headers
headers = {"Content-Type":"application/json","Accept":"application/json"}
# CBC SDK Base
from cbc_sdk import CBCloudAPI

BOLD = "\033[1m"
UNBOLD = "\033[0m"
"""Setup"""

logging.basicConfig(
    filename="cloud_products_example_log.txt",
    format=
    '%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s',
    datefmt='%Y-%m-%d:%H:%M:%S',
    level=logging.INFO)

# API keys with relevant permissions
audit_remediation_api = CBCloudAPI(profile='audit_remediation')  # Live Query
live_response_api = CBCloudAPI(profile='live_response')  # Live Response
endpoint_standard_api = CBCloudAPI(profile='endpoint_standard')
enterprise_edr_api = CBCloudAPI(profile='enterprise_edr')
platform_api = CBCloudAPI(profile='platform')


def platform():
    """
    Platform Alerts and Devices operations, using research from TAU.

    1. Find Alerts matching Egregor ransomware, then
    2. Find Alerts matching a harmless query (demonstration purposes).
    """
    # Egregor ransomware tactics, techniques, and procedures (TTPs) identified by TAU
    egregor_ttps = (
Esempio n. 20
0
 def __init__(self):
     """Initialize the ThreatIntel class."""
     self.cb = CBCloudAPI(timeout=200)
            log.debug(json.dumps(res))
            return res
        elif res["status"] == "error":
            raise LiveResponseError(res)
        else:
            time.sleep(delay)

    raise TimeoutError(uri=url, message="timeout polling for Live Response")


if __name__ == "__main__":
    from cbc_sdk import CBCloudAPI
    from cbc_sdk.platform import Device
    import logging

    root = logging.getLogger()
    root.addHandler(logging.StreamHandler())

    logging.getLogger("cbc_sdk").setLevel(logging.DEBUG)

    c = CBCloudAPI()
    j = GetFileJob(r"c:\test.txt")
    with c.select(Device, 3).lr_session() as lr_session:
        file_contents = lr_session.get_file(r"c:\test.txt")

    future = c.live_response.submit_job(j.run, 3)
    wait([
        future,
    ])
    print(future.result())
def create_reg_key_command(api_client: CBCloudAPI, device_id: str,
                           reg_path: str):
    session = api_client.select(platform.Device, device_id).lr_session()
    session.create_registry_key(reg_path)
    return f'Reg key: {reg_path}, was created successfully.'
Esempio n. 23
0
def main():
    """Script entry point"""
    cb = CBCloudAPI(url=url, token=token, org_key=org_key, proxy=proxy, ssl_verify=False)

    assert type(cb.select(Device).first()) is Device
    print(f"Successfully fetched Device using proxy: {proxy}")
def delete_reg_value_command(api_client: CBCloudAPI, device_id: str,
                             reg_path: str):
    session = api_client.select(platform.Device, device_id).lr_session()
    session.delete_registry_value(reg_path)
    return f'Registry value: {reg_path} was deleted successfully.'
Esempio n. 25
0
class ThreatIntel:
    """Object handling Threat Intelligence."""
    def __init__(self):
        """Initialize the ThreatIntel class."""
        self.cb = CBCloudAPI(timeout=200)

    def verify_feed_exists(self, feed_id):
        """Verify that a Feed exists."""
        try:
            feed = self.cb.select(Feed, feed_id)
            return feed
        except ApiError:
            raise ApiError

    def push_to_cb(self, feed_id, results):
        """Send result.AnalysisResult Reports or a Report dictionary to a Feed."""
        feed = self.verify_feed_exists(feed_id)  # will raise an ApiError if the feed cannot be found
        if not feed:
            return
        report_list_to_send = []
        reports = []
        malformed_reports = []

        for result in results:
            report_dict = {}
            # convert to a dictionary if necessary
            if isinstance(result, AnalysisResult):
                try:
                    report_dict = {
                        "id": str(result.id),
                        "timestamp": int(result.timestamp.timestamp()),
                        "title": str(result.title),
                        "description": str(result.description),
                        "severity": int(result.severity),
                        "iocs_v2": [ioc_v2.as_dict() for ioc_v2 in result.iocs_v2]
                    }
                except Exception as e:
                    log.error(f"Failed to create a report dictionary from result object. {e}")
            # no conversion to dictionary needed
            elif isinstance(result, dict):
                report_dict = result
            try:
                ReportSchema.validate(report_dict)
                # create Enterprise EDR Report object
                report = Report(self.cb, initial_data=report_dict, feed_id=feed_id)
                report_list_to_send.append(report)
                reports.append(report_dict)
            except SchemaError as e:
                log.warning(f"Report Validation failed. Saving report to file for reference. Error: {e}")
                malformed_reports.append(report_dict)

        log.debug(f"Num Reports: {len(report_list_to_send)}")
        try:
            with open('reports.json', 'w') as f:
                json.dump(reports, f, indent=4)
        except Exception as e:
            log.error(f"Failed to write reports to file: {e}")

        log.debug("Sending results to Carbon Black Cloud.")

        if report_list_to_send:
            try:
                feed.append_reports(report_list_to_send)
                log.info(f"Appended {len(report_list_to_send)} reports to Enterprise EDR Feed {feed_id}")
            except Exception as e:
                log.debug(f"Failed sending {len(report_list_to_send)} reports: {e}")

        if malformed_reports:
            log.warning("Some report(s) failed validation. See malformed_reports.json for reports that failed.")
            try:
                with open('malformed_reports.json', 'w') as f:
                    json.dump(malformed_reports, f, indent=4)
            except Exception as e:
                log.error(f"Failed to write malformed_reports to file: {e}")