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)
    session.put_file((path['name'], open(path['path'], 'rb')),
                     destination_path)
    return f'File: {file_id} is successfully put to the remote destination {destination_path}'
Example #2
0
def 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 Func Test Feed",
        "owner": "DevRel",
        "provider_url": "https://developer.carbonblack.com",
        "summary": "BAT functional test feed",
        "category": "None",
        "access": "private"
    }
    feed_dict = {"feedinfo": feedinfo, "reports": []}
    test_feed = cb.create(Feed, feed_dict)
    try:
        test_feed.save()
    except ServerError:
        for feed in cb.select(Feed):
            if feed.name == feedinfo["name"]:
                feed.delete()

        test_feed.save()
    yield test_feed
    delete_feed(auth_token, test_feed._info["id"])
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,
    )
Example #4
0
def delete_feed(auth_token, feed_id):
    """Delete Feed after it's used for testing"""
    cb = CBCloudAPI(url="https://defense-eap01.conferdeploy.net",
                    token=auth_token,
                    org_key="WNEXFKQ7")
    feed = cb.select(Feed, feed_id)
    feed.delete()
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 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,
    )
Example #7
0
def get_reports_from_feed(auth_token, feed_id):
    """GET to /feed/{feed_id}/reports to verify reports were sent"""
    cb = CBCloudAPI(url="https://defense-eap01.conferdeploy.net",
                    token=auth_token,
                    org_key="WNEXFKQ7")
    feed = cb.select(Feed, feed_id)
    results = {"results": [report._info for report in feed.reports]}
    return results
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.'
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 get_feed_ids():
    """Read and log all the feed IDs from the default server."""
    cb = CBCloudAPI()
    feeds = cb.select(Feed)
    if not feeds:
        log.info("No feeds are available for the org key {}".format(
            cb.credentials.org_key))
    else:
        for feed in feeds:
            log.info("Feed name: {:<20} \t Feed ID: {:>20}".format(
                feed.name, feed.id))
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 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,
    )
            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 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}.'
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.'
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.'
Example #20
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}")
Example #21
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}")