示例#1
0
def upload_xml(xml_file, path):
    """
    Updates XML files (rules and decoders)
    :param xml_file: content of the XML file
    :param path: Destination of the new XML file
    :return: Confirmation message
    """
    # path of temporary files for parsing xml input
    tmp_file_path = '{}/tmp/api_tmp_file_{}_{}.xml'.format(
        common.ossec_path, time.time(), random.randint(0, 1000))

    # create temporary file for parsing xml input
    try:
        with open(tmp_file_path, 'w') as tmp_file:
            # beauty xml file
            xml = parseString('<root>' + xml_file + '</root>')
            # remove first line (XML specification: <? xmlversion="1.0" ?>), <root> and </root> tags, and empty lines
            pretty_xml = '\n'.join(
                filter(lambda x: x.strip(),
                       xml.toprettyxml(indent='  ').split('\n')[2:-2])) + '\n'
            # revert xml.dom replacings
            # (https://github.com/python/cpython/blob/8e0418688906206fe59bd26344320c0fc026849e/Lib/xml/dom/minidom.py#L305)
            pretty_xml = pretty_xml.replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", "\"", ) \
                .replace("&gt;", ">").replace('&apos', "'")
            tmp_file.write(pretty_xml)
        chmod(tmp_file_path, 0o640)
    except IOError:
        raise WazuhException(1005)
    except ExpatError:
        raise WazuhException(1113)
    except Exception as e:
        raise WazuhException(1000, str(e))

    try:
        # check xml format
        try:
            load_wazuh_xml(tmp_file_path)
        except Exception as e:
            raise WazuhException(1113, str(e))

        # move temporary file to group folder
        try:
            new_conf_path = join(common.ossec_path, path)
            move(tmp_file_path, new_conf_path)
        except Error:
            raise WazuhException(1016)
        except Exception:
            raise WazuhException(1000)

        return 'File updated successfully'

    except Exception as e:
        # remove created temporary file if an exception happens
        remove(tmp_file_path)
        raise e
示例#2
0
def get_agent_conf_multigroup(group_id=None, offset=0, limit=common.database_limit, filename=None):
    """
    Returns agent.conf as dictionary.

    :return: agent.conf as dictionary.
    """
    if group_id:
        #if not Agent.multi_group_exists(group_id):
            #raise WazuhException(1710, group_id)

        agent_conf = "{0}/{1}".format(common.multi_groups_path, group_id)

    if filename:
        agent_conf_name = filename
    else:
        agent_conf_name = 'agent.conf'

    agent_conf += "/{0}".format(agent_conf_name)

    if not os_path.exists(agent_conf):
        raise WazuhException(1006, agent_conf)

    try:
        # Read XML
        xml_data = load_wazuh_xml(agent_conf)

        # Parse XML to JSON
        data = _agentconf2json(xml_data)
    except Exception as e:
        raise WazuhException(1101, str(e))


    return {'totalItems': len(data), 'items': cut_array(data, offset, limit)}
示例#3
0
def get_ossec_conf(section=None, field=None, conf_file=common.ossec_conf):
    """
    Returns ossec.conf (manager) as dictionary.

    :param section: Filters by section (i.e. rules).
    :param field: Filters by field in section (i.e. included).
    :param conf_file: Path of the configuration file to read.
    :return: ossec.conf (manager) as dictionary.
    """
    try:
        # Read XML
        xml_data = load_wazuh_xml(conf_file)

        # Parse XML to JSON
        data = _ossecconf2json(xml_data)
    except Exception as e:
        raise WazuhException(1101, str(e))

    if section:
        try:
            data = data[section]
        except KeyError as e:
            if section not in conf_sections.keys():
                raise WazuhException(1102, e.args[0])
            else:
                raise WazuhException(1106, e.args[0])

    if section and field:
        try:
            data = data[field]  # data[section][field]
        except:
            raise WazuhException(1103)

    return data
示例#4
0
def get_agent_conf(group_id=None, offset=0, limit=common.database_limit, filename='agent.conf', return_format=None):
    """
    Returns agent.conf as dictionary.

    :return: agent.conf as dictionary.
    """
    agent_conf = os_path.join(common.shared_path, group_id if group_id is not None else '', filename)

    if not os_path.exists(agent_conf):
        raise WazuhException(1006, agent_conf)

    try:
        # Read RAW file
        if filename == 'agent.conf' and return_format and 'xml' == return_format.lower():
            with open(agent_conf, 'r') as xml_data:
                data = xml_data.read().replace('\n', '')
                return data
        # Parse XML to JSON
        else:
            # Read XML
            xml_data = load_wazuh_xml(agent_conf)

            data = _agentconf2json(xml_data)
    except Exception as e:
        raise WazuhException(1101, str(e))

    return {'totalItems': len(data), 'items': cut_array(data, offset, limit)}
示例#5
0
    def __load_decoders_from_file(decoder_file, decoder_path, decoder_status):
        try:
            decoders = []
            position = 0

            root = load_wazuh_xml(
                os.path.join(common.ossec_path, decoder_path, decoder_file))

            for xml_decoder in list(root):
                # New decoder
                if xml_decoder.tag.lower() == "decoder":
                    decoder = Decoder()
                    decoder.path = decoder_path
                    decoder.file = decoder_file
                    decoder.status = decoder_status
                    decoder.name = xml_decoder.attrib['name']
                    decoder.position = position
                    position += 1

                    for k in xml_decoder.attrib:
                        if k != 'name':
                            decoder.details[k] = xml_decoder.attrib[k]

                    for xml_decoder_tags in list(xml_decoder):
                        decoder.add_detail(xml_decoder_tags.tag.lower(),
                                           xml_decoder_tags.text)

                    decoders.append(decoder)
        except Exception as e:
            raise WazuhException(
                1501, "{0}. Error: {1}".format(decoder_file, str(e)))

        return decoders
示例#6
0
    def __load_rules_from_file(rule_file, rule_path, rule_status):
        try:
            rules = []

            root = load_wazuh_xml("{}/{}".format(rule_path, rule_file))

            for xml_group in root.getchildren():
                if xml_group.tag.lower() == "group":
                    general_groups = xml_group.attrib['name'].split(',')
                    for xml_rule in xml_group.getchildren():
                        # New rule
                        if xml_rule.tag.lower() == "rule":
                            groups = []
                            rule = Rule()
                            rule.file = rule_file
                            rule.path = rule_path
                            rule.id = int(xml_rule.attrib['id'])
                            rule.level = int(xml_rule.attrib['level'])
                            rule.status = rule_status

                            for k in xml_rule.attrib:
                                if k != 'id' and k != 'level':
                                    rule.details[k] = xml_rule.attrib[k]

                            for xml_rule_tags in xml_rule.getchildren():
                                tag = xml_rule_tags.tag.lower()
                                value = xml_rule_tags.text
                                if value == None:
                                    value = ''
                                if tag == "group":
                                    groups.extend(value.split(","))
                                elif tag == "description":
                                    rule.description += value
                                elif tag == "field":
                                    rule.add_detail(
                                        xml_rule_tags.attrib['name'], value)
                                else:
                                    rule.add_detail(tag, value)

                            # Set groups
                            groups.extend(general_groups)

                            pci_groups = []
                            ossec_groups = []
                            for g in groups:
                                if 'pci_dss_' in g:
                                    pci_groups.append(g.strip()[8:])
                                else:
                                    ossec_groups.append(g)

                            rule.set_group(ossec_groups)
                            rule.set_pci(pci_groups)

                            rules.append(rule)
        except Exception as e:
            raise WazuhException(1201,
                                 "{0}. Error: {1}".format(rule_file, str(e)))

        return rules
示例#7
0
def upload_xml(xml_file, path):
    """
    Upload XML files (rules and decoders)
    :param xml_file: content of the XML file
    :param path: Destination of the new XML file
    :return: Confirmation message
    """
    # -- characters are not allowed in XML comments
    xml_file = replace_in_comments(xml_file, '--', '%wildcard%')

    # path of temporary files for parsing xml input
    tmp_file_path = '{}/tmp/api_tmp_file_{}_{}.xml'.format(
        common.ossec_path, time.time(), random.randint(0, 1000))

    # create temporary file for parsing xml input
    try:
        with open(tmp_file_path, 'w') as tmp_file:
            # beauty xml file
            xml = parseString('<root>' + xml_file + '</root>')
            # remove first line (XML specification: <? xmlversion="1.0" ?>), <root> and </root> tags, and empty lines
            indent = '  '  # indent parameter for toprettyxml function
            pretty_xml = '\n'.join(
                filter(
                    lambda x: x.strip(),
                    xml.toprettyxml(indent=indent).split('\n')[2:-2])) + '\n'
            # revert xml.dom replacings
            # (https://github.com/python/cpython/blob/8e0418688906206fe59bd26344320c0fc026849e/Lib/xml/dom/minidom.py#L305)
            pretty_xml = pretty_xml.replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", "\"", ) \
                .replace("&gt;", ">").replace('&apos;', "'")
            # delete two first spaces of each line
            final_xml = re.sub(fr'^{indent}',
                               '',
                               pretty_xml,
                               flags=re.MULTILINE)
            final_xml = replace_in_comments(final_xml, '%wildcard%', '--')
            tmp_file.write(final_xml)
        chmod(tmp_file_path, 0o660)
    except IOError:
        raise WazuhException(1005)
    except ExpatError:
        raise WazuhException(1113)
    except Exception as e:
        raise WazuhException(1000, str(e))

    try:
        # check xml format
        try:
            load_wazuh_xml(tmp_file_path)
        except Exception as e:
            raise WazuhException(1113, str(e))

        # move temporary file to group folder
        try:
            new_conf_path = join(common.ossec_path, path)
            safe_move(tmp_file_path, new_conf_path, permissions=0o660)
        except Error:
            raise WazuhException(1016)
        except Exception:
            raise WazuhException(1000)

        return 'File updated successfully'

    except Exception as e:
        # remove created temporary file if an exception happens
        remove(tmp_file_path)
        raise e
示例#8
0
    def __load_rules_from_file(rule_file, rule_path, rule_status):
        try:
            rules = []

            root = load_wazuh_xml(
                os.path.join(common.ossec_path, rule_path, rule_file))

            for xml_group in root.getchildren():
                if xml_group.tag.lower() == "group":
                    general_groups = xml_group.attrib['name'].split(',')
                    for xml_rule in xml_group.getchildren():
                        # New rule
                        if xml_rule.tag.lower() == "rule":
                            groups = []
                            rule = Rule()
                            rule.file = rule_file
                            rule.path = rule_path
                            rule.id = int(xml_rule.attrib['id'])
                            rule.level = int(xml_rule.attrib['level'])
                            rule.status = rule_status

                            for k in xml_rule.attrib:
                                if k != 'id' and k != 'level':
                                    rule.details[k] = xml_rule.attrib[k]

                            for xml_rule_tags in xml_rule.getchildren():
                                tag = xml_rule_tags.tag.lower()
                                value = xml_rule_tags.text
                                if value == None:
                                    value = ''
                                if tag == "group":
                                    groups.extend(value.split(","))
                                elif tag == "description":
                                    rule.description += value
                                elif tag == "field":
                                    rule.add_detail(
                                        xml_rule_tags.attrib['name'], value)
                                elif tag in ("list", "info"):
                                    list_detail = {'name': value}
                                    for attrib, attrib_value in xml_rule_tags.attrib.items(
                                    ):
                                        list_detail[attrib] = attrib_value
                                    rule.add_detail(tag, list_detail)
                                # show rule variables
                                elif tag in {
                                        'regex', 'match', 'user', 'id'
                                } and value != '' and value[0] == "$":
                                    for variable in filter(
                                            lambda x: x.get('name') == value[1:
                                                                             ],
                                            root.findall('var')):
                                        rule.add_detail(tag, variable.text)
                                else:
                                    rule.add_detail(tag, value)

                            # Set groups
                            groups.extend(general_groups)

                            pci_groups = []
                            gdpr_groups = []
                            ossec_groups = []
                            for g in groups:
                                if 'pci_dss_' in g:
                                    pci_groups.append(g.strip()[8:])
                                elif 'gdpr_' in g:
                                    gdpr_groups.append(g.strip()[5:])
                                else:
                                    ossec_groups.append(g)

                            rule.set_group(ossec_groups)
                            rule.set_pci(pci_groups)
                            rule.set_gdpr(gdpr_groups)

                            rules.append(rule)
        except Exception as e:
            raise WazuhException(1201,
                                 "{0}. Error: {1}".format(rule_file, str(e)))

        return rules
示例#9
0
def upload_group_configuration(group_id, xml_file):
    """
    Updates group configuration
    :param group_id: Group to update
    :param xml_file: File contents of the new configuration in string.
    :return: Confirmation message.
    """
    # check if the group exists
    if not Agent.group_exists(group_id):
        raise WazuhException(1710)

    # path of temporary files for parsing xml input
    tmp_file_path = '{}/tmp/api_tmp_file_{}.xml'.format(
        common.ossec_path,
        datetime.strftime(datetime.utcnow(), '%Y-%m-%d-%m-%s'))

    # create temporary file for parsing xml input
    try:
        with open(tmp_file_path, 'w') as tmp_file:
            # beauty xml file
            xml = parseString('<root>' + xml_file + '</root>')
            # remove first line (XML specification: <? xmlversion="1.0" ?>), <root> and </root> tags, and empty lines
            pretty_xml = '\n'.join(
                filter(lambda x: x.strip(),
                       xml.toprettyxml(indent='  ').split('\n')[2:-2])) + '\n'
            # revert xml.dom replacings
            # (https://github.com/python/cpython/blob/8e0418688906206fe59bd26344320c0fc026849e/Lib/xml/dom/minidom.py#L305)
            pretty_xml = pretty_xml.replace("&amp;", "&").replace("&lt;", "<").replace("&quot;", "\"",)\
                                   .replace("&gt;", ">")
            tmp_file.write(pretty_xml)
    except Exception as e:
        raise WazuhException(1113, str(e))

    try:
        # check xml format
        try:
            load_wazuh_xml(tmp_file_path)
        except Exception as e:
            raise WazuhException(1113, str(e))

        # check Wazuh xml format
        try:
            subprocess.check_output([
                '{}/bin/verify-agent-conf'.format(common.ossec_path), '-f',
                tmp_file_path
            ],
                                    stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            # extract error message from output.
            # Example of raw output
            # 2019/01/08 14:51:09 verify-agent-conf: ERROR: (1230): Invalid element in the configuration: 'agent_conf'.\n2019/01/08 14:51:09 verify-agent-conf: ERROR: (1207): Syscheck remote configuration in '/var/ossec/tmp/api_tmp_file_2019-01-08-01-1546959069.xml' is corrupted.\n\n
            # Example of desired output:
            # Invalid element in the configuration: 'agent_conf'. Syscheck remote configuration in '/var/ossec/tmp/api_tmp_file_2019-01-08-01-1546959069.xml' is corrupted.
            output_regex = re.findall(
                pattern=
                r"\d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2} verify-agent-conf: ERROR: "
                r"\(\d+\): ([\w \/ \_ \- \. ' :]+)",
                string=e.output)
            raise WazuhException(1114, ' '.join(output_regex))
        except Exception as e:
            raise WazuhException(1743, str(e))

        # move temporary file to group folder
        try:
            new_conf_path = "{}/{}/agent.conf".format(common.shared_path,
                                                      group_id)
            move(tmp_file_path, new_conf_path)
        except Exception as e:
            raise WazuhException(1017, str(e))

        return 'Agent configuration was updated successfully'
    except Exception as e:
        # remove created temporary file
        remove(tmp_file_path)
        raise e