Exemple #1
0
    def __new__(mcs, name, bases, clsdict):
        swagger_meta_file = clsdict.pop("swagger_meta_file", None)
        model_data = {}
        if swagger_meta_file:
            model_data = yaml.load(
                open(os.path.join(mcs.model_base_directory, swagger_meta_file), 'rb').read())

        clsdict["__doc__"] = "Represents a %s object in the Carbon Black server.\n\n" % (name,)
        for field_name, field_info in iteritems(model_data.get("properties", {})):
            docstring = field_info.get("description", None)
            if docstring:
                clsdict["__doc__"] += ":ivar %s: %s\n" % (field_name, docstring)

        foreign_keys = clsdict.pop("foreign_keys", {})

        cls = super(CbMetaModel, mcs).__new__(mcs, name, bases, clsdict)
        mcs.model_classes.append(cls)

        cls._valid_fields = []
        cls._required_fields = model_data.get("required", [])
        cls._default_value = {}

        for field_name, field_info in iteritems(model_data.get("properties", {})):
            cls._valid_fields.append(field_name)

            default_value = field_info.get("default", None)
            if default_value:
                cls._default_value[field_name] = default_value

            field_format = field_info.get("type", "string")
            field_format = field_info.get("format", field_format)

            if field_format.startswith('int'):
                setattr(cls, field_name, FieldDescriptor(field_name, coerce_to=int))
            elif field_format == "date-time":
                setattr(cls, field_name, DateTimeFieldDescriptor(field_name))
            elif field_format == "boolean":
                setattr(cls, field_name, FieldDescriptor(field_name, coerce_to=bool))
            elif field_format == "array":
                setattr(cls, field_name, ArrayFieldDescriptor(field_name))
            elif field_format == "object":
                setattr(cls, field_name, ObjectFieldDescriptor(field_name))
            elif field_format == "double":
                setattr(cls, field_name, FieldDescriptor(field_name, coerce_to=float))
            elif field_format == "byte":
                setattr(cls, field_name, BinaryFieldDescriptor(field_name))
            else:
                setattr(cls, field_name, FieldDescriptor(field_name))

        for fk_name, fk_info in iteritems(foreign_keys):
            setattr(cls, fk_name, ForeignKeyFieldDescriptor(fk_name, fk_info[0], fk_info[1]))

        return cls
Exemple #2
0
    def report_result(self, binary, scanResults):
        # We have results. Create our notification
        n = binary.create_notification(data={
            "product": "VirusTotal",
            "malwareName": "",
            "malwareType": ""
        })

        # Let's see if it is malicious. Use some fancy heuristics...
        positivesPerc = 100 * scanResults.get('positives') / scanResults.get(
            'total')
        if positivesPerc > self.malicious_threshold:
            n.analysisResult = Notification.ResultMalicious
            n.severity = "critical"
            n.type = "malicious_file"
        elif positivesPerc > self.potential_threshold:
            n.analysisResult = Notification.ResultPotentialThreat
            n.severity = "high"
            n.type = "potential_risk_file"
        else:
            n.analysisResult = Notification.ResultClean
            n.severity = "low"
            n.type = "clean_file"

        n.externalUrl = scanResults.get('permalink')

        # Enumerate scan results that have detected the issue and build our
        # 'malwareName' string for the notification
        scans = scanResults.get("scans", {})
        malware_type = [
            k + ":" + v["result"] for k, v in iteritems(scans) if v["detected"]
        ]
        malware_name = [
            v["result"] for k, v in iteritems(scans) if v["detected"]
        ]

        n.malwareType = "; ".join(malware_type[:4])
        n.malwareName = "; ".join(malware_name[:4])

        if len(malware_type) > 4:
            n.malwareName += "..."
            n.malwareType += "..."

        # Send notification
        n.save()

        if binary.fileHash in self.awaiting_results:
            del self.awaiting_results[binary.fileHash]

        log.info(
            "VT analysis for %s completed. VT result is %d%% malware (%s). Reporting status: %s"
            % (binary.fileHash, positivesPerc, n.malwareName, n.type))
Exemple #3
0
    def cleanup(self):
        marked_for_deletion = set()

        if self.expiration is None:
            return None
        t = int(time.time())

        # Delete expired
        next_expire = None
        for k, v in iteritems(self.__expire_times):
            if v < t:
                marked_for_deletion.add(k)
            else:
                next_expire = v
                break

        for k in marked_for_deletion:
            self.__delete__(k)

        marked_for_deletion = set()

        # If we have more than self.max_size items, delete the oldest
        if len(self.__values) > self.max_size:
            number_to_delete = len(self.__values) - self.max_size
            marked_for_deletion = [k for k in islice(self.__access_times, number_to_delete)]
            for k in marked_for_deletion:
                self.__delete__(k)

        if not (next_expire is None):
            return next_expire - t
        else:
            return None
def main():
    parser = build_cli_parser("Delete duplicate computers")
    parser.add_argument(
        "--dry-run",
        "-d",
        help="perform a dry run, don't actually delete the computers",
        action="store_true",
        dest="dry_run")

    args = parser.parse_args()
    p = get_cb_protection_object(args)

    computer_list = defaultdict(list)
    for computer in p.select(Computer).where("deleted:false"):
        computer_list[computer.name].append({
            "id": computer.id,
            "offline": computer.daysOffline
        })

    for computer_name, computer_ids in iteritems(computer_list):
        if len(computer_ids) > 1:
            sorted_computers = sorted(computer_ids,
                                      key=lambda x: x["offline"],
                                      reverse=True)
            for computer_id in sorted_computers[:-1]:
                if computer_id["offline"] > 0:
                    print(
                        "deleting computer id %d (offline %d days, hostname %s)"
                        % (computer_id["id"], computer_id["offline"],
                           computer_name))
                    if not args.dry_run:
                        print("deleting from server...")
                        p.select(Computer, computer_id["id"]).delete()
Exemple #5
0
    def cleanup(self):
        marked_for_deletion = set()

        if self.expiration is None:
            return None
        t = int(time.time())

        # Delete expired
        next_expire = None
        for k, v in iteritems(self.__expire_times):
            if v < t:
                marked_for_deletion.add(k)
            else:
                next_expire = v
                break

        for k in marked_for_deletion:
            self.__delete__(k)

        marked_for_deletion = set()

        # If we have more than self.max_size items, delete the oldest
        if len(self.__values) > self.max_size:
            number_to_delete = len(self.__values) - self.max_size
            marked_for_deletion = [
                k for k in islice(self.__access_times, number_to_delete)
            ]
            for k in marked_for_deletion:
                self.__delete__(k)

        if not (next_expire is None):
            return next_expire - t
        else:
            return None
 def raise_unless_json(self, ret, expected):
     if ret.status_code == 200:
         message = ret.json()
         for k, v in iteritems(expected):
             if k not in message or message[k] != v:
                 raise ServerError(ret.status_code, message)
     else:
         raise ServerError(ret.status_code, "".format(ret.content), )
Exemple #7
0
    def reset(self):
        for k, v in iteritems(self._dirty_attributes):
            if v is None:
                del self._info[k]
            else:
                self._info[k] = v

        self._dirty_attributes = {}
 def raise_unless_json(self, ret, expected):
     if ret.status_code == 200:
         message = ret.json()
         for k, v in iteritems(expected):
             if k not in message or message[k] != v:
                 raise ServerError(ret.status_code, message)
     else:
         raise ServerError(ret.status_code, "".format(ret.content), )
Exemple #9
0
def convert_query_params(qd):
    o = []
    for k, v in iteritems(qd):
        if type(v) == list:
            for item in v:
                o.append((k, item))
        else:
            o.append((k, v))

    return o
Exemple #10
0
def convert_query_params(qd):
    o = []
    for k, v in iteritems(qd):
        if type(v) == list:
            for item in v:
                o.append((k, item))
        else:
            o.append((k, v))

    return o
Exemple #11
0
 def _match_query(self, i):
     for k, v in iteritems(self._query):
         if isinstance(v, six.string_types):
             v = v.lower()
         target = getattr(i, k, None)
         if target is None:
             return False
         if str(target).lower() != v:
             return False
     return True
Exemple #12
0
 def _match_query(self, i):
     for k, v in iteritems(self._query):
         if isinstance(v, six.string_types):
             v = v.lower()
         target = getattr(i, k, None)
         if target is None:
             return False
         if str(target).lower() != v:
             return False
     return True
    def report_result(self, binary, scanResults):
        # We have results. Create our notification
        n = binary.create_notification(data={"product": "VirusTotal", "malwareName": "", "malwareType": ""})

        # Let's see if it is malicious. Use some fancy heuristics...
        positivesPerc = 100 * scanResults.get('positives') / scanResults.get('total')
        if positivesPerc > self.malicious_threshold:
            n.analysisResult = Notification.ResultMalicious
            n.severity = "critical"
            n.type = "malicious_file"
        elif positivesPerc > self.potential_threshold:
            n.analysisResult = Notification.ResultPotentialThreat
            n.severity = "high"
            n.type = "potential_risk_file"
        else:
            n.analysisResult = Notification.ResultClean
            n.severity = "low"
            n.type = "clean_file"

        n.externalUrl = scanResults.get('permalink')

        # Enumerate scan results that have detected the issue and build our
        # 'malwareName' string for the notification
        scans = scanResults.get("scans", {})
        malware_type = [k + ":" + v["result"] for k, v in iteritems(scans) if v["detected"]]
        malware_name = [v["result"] for k, v in iteritems(scans) if v["detected"]]

        n.malwareType = "; ".join(malware_type[:4])
        n.malwareName = "; ".join(malware_name[:4])

        if len(malware_type) > 4:
            n.malwareName += "..."
            n.malwareType += "..."

        # Send notification
        n.save()

        if binary.fileHash in self.awaiting_results:
            del self.awaiting_results[binary.fileHash]

        log.info("VT analysis for %s completed. VT result is %d%% malware (%s). Reporting status: %s"
                 % (binary.fileHash, positivesPerc, n.malwareName, n.type))
Exemple #14
0
def main(args):
    parser = argparse.ArgumentParser()
    commands = parser.add_subparsers(dest="command_name", help="CbAPI subcommand")

    for cmd_name, cmd_config in iteritems(command_map):
        cmd_parser = commands.add_parser(cmd_name, help=cmd_config.get("help", None))
        for cmd_arg_name, cmd_arg_config in iteritems(cmd_config.get("extra_args", {})):
            cmd_parser.add_argument(cmd_arg_name, **cmd_arg_config)

    opts = parser.parse_args(args)
    command = command_map.get(opts.command_name)
    if not command:
        parser.print_usage()
        return

    command_method = command.get("method", None)
    if command_method:
        return command_method(opts)
    else:
        parser.print_usage()
Exemple #15
0
def main():
    parser = build_cli_parser("VirusTotal Connector")
    parser.add_argument("--config",
                        "-c",
                        help="Path to configuration file",
                        default="virustotal.ini")
    args = parser.parse_args()

    inifile = RawConfigParser({
        "vt_api_key": None,
        "retrieve_files": "true",
        "upload_binaries_to_vt": "false",
        "connector_name": "VirusTotal",
        "log_file": None,
    })
    inifile.read(args.config)

    config = {}
    config["vt_api_key"] = inifile.get("bridge", "vt_api_key")
    config["retrieve_files"] = inifile.getboolean("bridge", "retrieve_files")
    config["connector_name"] = inifile.get("bridge", "connector_name")
    config["upload_binaries_to_vt"] = inifile.getboolean(
        "bridge", "upload_binaries_to_vt")

    log_file = inifile.get("bridge", "log_file")
    if log_file:
        file_handler = logging.FileHandler(log_file)
        formatter = logging.Formatter('%(asctime)s %(levelname)s:%(message)s')
        file_handler.setFormatter(formatter)
        file_handler.setLevel(logging.DEBUG)
        logging.getLogger().addHandler(file_handler)

    if not config["vt_api_key"]:
        log.fatal("Cannot start without a valid VirusTotal API key, exiting")
        return 1

    log.info("Configuration:")
    for k, v in iteritems(config):
        log.info("    %-20s: %s" % (k, v))

    api = get_cb_protection_object(args)

    vt = VirusTotalConnector(
        api,
        vt_token=config["vt_api_key"],
        allow_uploads=config[
            "upload_binaries_to_vt"],  # Allow VT connector to upload binary files to VirusTotal
        connector_name=config["connector_name"],
    )

    log.info("Starting VirusTotal processing loop")
    vt.run()
Exemple #16
0
    def get_credentials(self, profile=None):
        credential_profile = profile or "default"
        if credential_profile not in self.get_profiles():
            raise CredentialError("Cannot find credential profile '%s' after searching in these files: %s." %
                                  (credential_profile, ", ".join(self.credential_search_path)))

        retval = {}
        for k, v in six.iteritems(default_profile):
            retval[k] = self.credentials.get(credential_profile, k)

        if not retval["url"] or not retval["token"]:
            raise CredentialError("Token and/or URL not available for profile %s" % credential_profile)

        return Credentials(retval)
Exemple #17
0
    def get_credentials(self, profile=None):
        credential_profile = profile or "default"
        if credential_profile not in self.get_profiles():
            raise CredentialError("Cannot find credential profile '%s' after searching in these files: %s." %
                                  (credential_profile, ", ".join(self.credential_search_path)))

        retval = {}
        for k, v in six.iteritems(default_profile):
            retval[k] = self.credentials.get(credential_profile, k)

        if not retval["url"] or not retval["token"]:
            raise CredentialError("Token and/or URL not available for profile %s" % credential_profile)

        return Credentials(retval)
def main():
    parser = build_cli_parser()
    args = parser.parse_args()
    c = get_cb_response_object(args)

    hostname_user_pairs = defaultdict(ItemCount)
    username_activity = defaultdict(ItemCount)

    for proc in c.select(Process).where("process_name:explorer.exe"):
        hostname_user_pairs[proc.hostname].add(proc.username)
        username_activity[proc.username].add(proc.hostname)

    for hostname, user_activity in iteritems(hostname_user_pairs):
        print("For host {0:s}:".format(hostname))
        for username, count in user_activity.report():
            print("  %-20s: logged in %d times" % (username, count))
    def create(self, cls, data=None):
        """Creates a new object.

        :param class cls: The Model class (only some models can be created, for example, Feed, Notification, ...)

        :returns: An empty instance of the Model class
        :raises ApiError: if the Model cannot be created
        """
        if issubclass(cls, CreatableModelMixin):
            n = cls(self)
            if type(data) is dict:
                for k, v in iteritems(data):
                    setattr(n, k, v)
            return n
        else:
            raise ApiError("Cannot create object of type {0:s}".format(cls.__name__))
    def create(self, cls, data=None):
        """Creates a new object.

        :param class cls: The Model class (only some models can be created, for example, Feed, Notification, ...)

        :returns: An empty instance of the Model class
        :raises ApiError: if the Model cannot be created
        """
        if issubclass(cls, CreatableModelMixin):
            n = cls(self)
            if type(data) is dict:
                for k, v in iteritems(data):
                    setattr(n, k, v)
            return n
        else:
            raise ApiError("Cannot create object of type {0:s}".format(cls.__name__))
def main():
    parser = build_cli_parser()
    args = parser.parse_args()
    c = get_cb_response_object(args)

    hostname_user_pairs = defaultdict(ItemCount)
    username_activity = defaultdict(ItemCount)

    for proc in c.select(Process).where("process_name:explorer.exe"):
        hostname_user_pairs[proc.hostname].add(proc.username)
        username_activity[proc.username].add(proc.hostname)

    for hostname, user_activity in iteritems(hostname_user_pairs):
        print("For host {0:s}:".format(hostname))
        for username, count in user_activity.report():
            print("  %-20s: logged in %d times" % (username, count))
def main():
    parser = build_cli_parser("VirusTotal Connector")
    parser.add_argument("--config", "-c", help="Path to configuration file", default="virustotal.ini")
    args = parser.parse_args()

    inifile = RawConfigParser({
        "vt_api_key": None,
        "retrieve_files": "true",
        "upload_binaries_to_vt": "false",
        "connector_name": "VirusTotal",
        "log_file": None,
    })
    inifile.read(args.config)

    config = {}
    config["vt_api_key"] = inifile.get("bridge", "vt_api_key")
    config["retrieve_files"] = inifile.getboolean("bridge", "retrieve_files")
    config["connector_name"] = inifile.get("bridge", "connector_name")
    config["upload_binaries_to_vt"] = inifile.getboolean("bridge", "upload_binaries_to_vt")

    log_file = inifile.get("bridge", "log_file")
    if log_file:
        file_handler = logging.FileHandler(log_file)
        formatter = logging.Formatter('%(asctime)s %(levelname)s:%(message)s')
        file_handler.setFormatter(formatter)
        file_handler.setLevel(logging.DEBUG)
        logging.getLogger().addHandler(file_handler)

    if not config["vt_api_key"]:
        log.fatal("Cannot start without a valid VirusTotal API key, exiting")
        return 1

    log.info("Configuration:")
    for k, v in iteritems(config):
        log.info("    %-20s: %s" % (k,v))

    api = get_cb_protection_object(args)

    vt = VirusTotalConnector(
        api,
        vt_token=config["vt_api_key"],
        allow_uploads=config["upload_binaries_to_vt"],  # Allow VT connector to upload binary files to VirusTotal
        connector_name=config["connector_name"],
    )

    log.info("Starting VirusTotal processing loop")
    vt.run()
Exemple #23
0
    def raise_unless_json(self, ret, expected):
        """
        Raise a ServerError unless we got back an HTTP 200 response with JSON containing all the expected values.

        Args:
            ret (object): Return value to be checked.
            expected (dict): Expected keys and values that need to be found in the JSON response.

        Raises:
            ServerError: If the HTTP response is anything but 200, or if the expected values are not found.
        """
        if ret.status_code == 200:
            message = ret.json()
            for k, v in iteritems(expected):
                if k not in message or message[k] != v:
                    raise ServerError(ret.status_code, message)
        else:
            raise ServerError(
                ret.status_code,
                "{0}".format(ret.content),
            )
def main():
    parser = build_cli_parser("Delete duplicate computers")
    parser.add_argument("--dry-run", "-d", help="perform a dry run, don't actually delete the computers",
                        action="store_true", dest="dry_run")

    args = parser.parse_args()
    p = get_cb_protection_object(args)

    computer_list = defaultdict(list)
    for computer in p.select(Computer).where("deleted:false"):
        computer_list[computer.name].append({"id": computer.id, "offline": computer.daysOffline})

    for computer_name, computer_ids in iteritems(computer_list):
        if len(computer_ids) > 1:
            sorted_computers = sorted(computer_ids, key=lambda x: x["offline"], reverse=True)
            for computer_id in sorted_computers[:-1]:
                if computer_id["offline"] > 0:
                    print("deleting computer id %d (offline %d days, hostname %s)" % (computer_id["id"],
                                                                                      computer_id["offline"],
                                                                                      computer_name))
                    if not args.dry_run:
                        print("deleting from server...")
                        p.select(Computer, computer_id["id"]).delete()
Exemple #25
0
    def create(self, cls, data=None):
        """
        Create a new object.

        Args:
            cls (class): The Model class (only some models can be created, for example, Feed, Notification, ...)
            data (object): The data used to initialize the new object

        Returns:
            Model: An empty instance of the model class.

        Raises:
            ApiError: If the Model cannot be created.
        """
        if issubclass(cls, CreatableModelMixin):
            n = cls(self)
            if type(data) is dict:
                for k, v in iteritems(data):
                    setattr(n, k, v)
            return n
        else:
            raise ApiError("Cannot create object of type {0:s}".format(
                cls.__name__))
Exemple #26
0
    def reset(self):
        """Reset all changes made to this object."""
        for k, v in iteritems(self._dirty_attributes):
            self._info[k] = v

        self._dirty_attributes = {}
Exemple #27
0
    def reset(self):
        for k, v in iteritems(self._dirty_attributes):
            self._info[k] = v

        self._dirty_attributes = {}
Exemple #28
0
    def reset(self):
        for k, v in iteritems(self._dirty_attributes):
            self._info[k] = v

        self._dirty_attributes = {}