mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Branch was auto-updated.
This commit is contained in:
@@ -147,7 +147,6 @@ jobs:
|
||||
source venv/bin/activate
|
||||
python3 contentctl.py --path . --verbose generate --product ESCU --output dist/escu
|
||||
python3 contentctl.py --path . --verbose generate --product SAAWS --output dist/saaws
|
||||
python3 contentctl.py --path . --verbose generate --product DevSecOps --output dist/devsecops
|
||||
python3 contentctl.py --path . --verbose generate --product SSA --output dist/ssa
|
||||
|
||||
- name: Copy lookups .csv files
|
||||
@@ -155,15 +154,12 @@ jobs:
|
||||
# clean up current lookups
|
||||
rm -rf dist/escu/lookups
|
||||
rm -rf dist/saaws/lookups
|
||||
rm -rf dist/devsecops/lookups
|
||||
mkdir dist/escu/lookups
|
||||
mkdir dist/saaws/lookups
|
||||
mkdir dist/devsecops/lookups
|
||||
#copy over lookups
|
||||
cd lookups
|
||||
cp -rv *.csv ../dist/escu/lookups
|
||||
cp -rv *.csv ../dist/saaws/lookups
|
||||
cp -rv *.csv ../dist/devsecops/lookups
|
||||
|
||||
#Tag is '' for non-tagged push and the tag name for a tagged release
|
||||
- name: Set tag
|
||||
@@ -203,9 +199,6 @@ jobs:
|
||||
sed -i "s/version = .*$/version = $CONTENT_VERSION/g" dist/saaws/default/content-version.conf
|
||||
tar -czf content-pack-build-saaws.tar.gz dist/saaws/*
|
||||
|
||||
# update build number and version for devsecops
|
||||
tar -czf content-pack-build-devsecops.tar.gz dist/devsecops/*
|
||||
|
||||
# update build number and version for ssa
|
||||
tar -czf content-pack-build-ssa.tar.gz dist/ssa/*
|
||||
|
||||
@@ -216,7 +209,6 @@ jobs:
|
||||
path: |
|
||||
content-pack-build-escu.tar.gz
|
||||
content-pack-build-saaws.tar.gz
|
||||
content-pack-build-devsecops.tar.gz
|
||||
content-pack-build-ssa.tar.gz
|
||||
|
||||
|
||||
@@ -261,17 +253,14 @@ jobs:
|
||||
cd build
|
||||
tar -zxf content-pack-build-escu.tar.gz
|
||||
tar -zxf content-pack-build-saaws.tar.gz
|
||||
tar -zxf content-pack-build-devsecops.tar.gz
|
||||
tar -zxf content-pack-build-ssa.tar.gz
|
||||
|
||||
mv dist/escu DA-ESS-ContentUpdate
|
||||
mv dist/saaws DA-ESS_AmazonWebServices_Content
|
||||
mv dist/devsecops dev_sec_ops_analytics
|
||||
mv dist/ssa SSA_Content
|
||||
|
||||
slim package -o upload DA-ESS-ContentUpdate
|
||||
slim package -o upload DA-ESS_AmazonWebServices_Content
|
||||
slim package -o upload dev_sec_ops_analytics
|
||||
#slim package -o upload SSA_Content
|
||||
|
||||
cp upload/DA-ESS-ContentUpdate-*.tar.gz DA-ESS-ContentUpdate-latest.tar.gz
|
||||
@@ -280,9 +269,6 @@ jobs:
|
||||
cp upload/DA-ESS_AmazonWebServices_Content-*tar.gz DA-ESS_AmazonWebServices_Content-latest.tar.gz
|
||||
sha256sum DA-ESS_AmazonWebServices_Content-latest.tar.gz >> checksum.txt
|
||||
|
||||
cp upload/dev_sec_ops_analytics-*tar.gz dev_sec_ops_analytics-latest.tar.gz
|
||||
sha256sum dev_sec_ops_analytics-latest.tar.gz >> checksum.txt
|
||||
|
||||
#Do this copy so that we conform as much as possible, and have to make
|
||||
#as few changes as possible, once we start generating this as a real,
|
||||
#properly packaged app
|
||||
@@ -305,7 +291,6 @@ jobs:
|
||||
path: |
|
||||
build/DA-ESS-ContentUpdate-latest.tar.gz
|
||||
build/DA-ESS_AmazonWebServices_Content-latest.tar.gz
|
||||
build/dev_sec_ops_analytics-latest.tar.gz
|
||||
build/SSA_Content-latest.tar.gz
|
||||
build/checksum.txt
|
||||
|
||||
@@ -350,7 +335,6 @@ jobs:
|
||||
#Better not to pass these arguments on the command line, if possible
|
||||
./appinspect.sh ../ DA-ESS-ContentUpdate-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
|
||||
./appinspect.sh ../ DA-ESS_AmazonWebServices_Content-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
|
||||
./appinspect.sh ../ dev_sec_ops_analytics-latest.tar.gz "$APPINSPECT_USERNAME" "$APPINSPECT_PASSWORD"
|
||||
|
||||
- name: Create report artifact
|
||||
if: always()
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
This is where you put any scripts you want to add to this app.
|
||||
Vendored
-112
@@ -1,112 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
""" Sets the packages path and optionally starts the Python remote debugging client.
|
||||
The Python remote debugging client depends on the settings of the variables defined in _pydebug_conf.py. Set these
|
||||
variables in _pydebug_conf.py to enable/disable debugging using either the JetBrains PyCharm or Eclipse PyDev remote
|
||||
debug egg which must be copied to your application's bin directory and renamed as _pydebug.egg.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
settrace = stoptrace = lambda: NotImplemented
|
||||
remote_debugging = None
|
||||
|
||||
|
||||
def initialize():
|
||||
|
||||
from os import path
|
||||
from sys import modules, path as python_path
|
||||
|
||||
import platform
|
||||
|
||||
module_dir = path.dirname(path.realpath(__file__))
|
||||
system = platform.system()
|
||||
|
||||
for packages in path.join(module_dir, 'packages'), path.join(path.join(module_dir, 'packages', system)):
|
||||
if not path.isdir(packages):
|
||||
break
|
||||
python_path.insert(0, path.join(packages))
|
||||
|
||||
configuration_file = path.join(module_dir, '_pydebug_conf.py')
|
||||
|
||||
if not path.exists(configuration_file):
|
||||
return
|
||||
|
||||
debug_client = path.join(module_dir, '_pydebug.egg')
|
||||
|
||||
if not path.exists(debug_client):
|
||||
return
|
||||
|
||||
_remote_debugging = {
|
||||
'client_package_location': debug_client,
|
||||
'is_enabled': False,
|
||||
'host': None,
|
||||
'port': 5678,
|
||||
'suspend': True,
|
||||
'stderr_to_server': False,
|
||||
'stdout_to_server': False,
|
||||
'overwrite_prev_trace': False,
|
||||
'patch_multiprocessing': False,
|
||||
'trace_only_current_thread': False}
|
||||
|
||||
exec(compile(open(configuration_file).read(), configuration_file, 'exec'), {'__builtins__': __builtins__}, _remote_debugging)
|
||||
python_path.insert(1, debug_client)
|
||||
|
||||
from splunklib.searchcommands import splunklib_logger as logger
|
||||
import pydevd
|
||||
|
||||
def _settrace():
|
||||
host, port = _remote_debugging['host'], _remote_debugging['port']
|
||||
logger.debug('Connecting to Python debug server at %s:%d', host, port)
|
||||
|
||||
try:
|
||||
pydevd.settrace(
|
||||
host=host,
|
||||
port=port,
|
||||
suspend=_remote_debugging['suspend'],
|
||||
stderrToServer=_remote_debugging['stderr_to_server'],
|
||||
stdoutToServer=_remote_debugging['stdout_to_server'],
|
||||
overwrite_prev_trace=_remote_debugging['overwrite_prev_trace'],
|
||||
patch_multiprocessing=_remote_debugging['patch_multiprocessing'],
|
||||
trace_only_current_thread=_remote_debugging['trace_only_current_thread'])
|
||||
except SystemExit as error:
|
||||
logger.error('Failed to connect to Python debug server at %s:%d: %s', host, port, error)
|
||||
else:
|
||||
logger.debug('Connected to Python debug server at %s:%d', host, port)
|
||||
|
||||
global remote_debugging
|
||||
remote_debugging = _remote_debugging
|
||||
|
||||
global settrace
|
||||
settrace = _settrace
|
||||
|
||||
global stoptrace
|
||||
stoptrace = pydevd.stoptrace
|
||||
|
||||
remote_debugging_is_enabled = _remote_debugging['is_enabled']
|
||||
|
||||
if isinstance(remote_debugging_is_enabled, (list, set, tuple)):
|
||||
app_name = path.splitext(path.basename(modules['__main__'].__file__))[0]
|
||||
remote_debugging_is_enabled = app_name in remote_debugging_is_enabled
|
||||
|
||||
if remote_debugging_is_enabled is True:
|
||||
settrace()
|
||||
|
||||
return
|
||||
|
||||
initialize()
|
||||
del initialize
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Python library for Splunk."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
from splunklib.six.moves import map
|
||||
__version_info__ = (1, 6, 16)
|
||||
__version__ = ".".join(map(str, __version_info__))
|
||||
-1415
File diff suppressed because it is too large
Load Diff
-3737
File diff suppressed because it is too large
Load Diff
Vendored
-266
@@ -1,266 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""The **splunklib.data** module reads the responses from splunkd in Atom Feed
|
||||
format, which is the format used by most of the REST API.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
from xml.etree.ElementTree import XML
|
||||
from splunklib import six
|
||||
|
||||
__all__ = ["load"]
|
||||
|
||||
# LNAME refers to element names without namespaces; XNAME is the same
|
||||
# name, but with an XML namespace.
|
||||
LNAME_DICT = "dict"
|
||||
LNAME_ITEM = "item"
|
||||
LNAME_KEY = "key"
|
||||
LNAME_LIST = "list"
|
||||
|
||||
XNAMEF_REST = "{http://dev.splunk.com/ns/rest}%s"
|
||||
XNAME_DICT = XNAMEF_REST % LNAME_DICT
|
||||
XNAME_ITEM = XNAMEF_REST % LNAME_ITEM
|
||||
XNAME_KEY = XNAMEF_REST % LNAME_KEY
|
||||
XNAME_LIST = XNAMEF_REST % LNAME_LIST
|
||||
|
||||
# Some responses don't use namespaces (eg: search/parse) so we look for
|
||||
# both the extended and local versions of the following names.
|
||||
|
||||
def isdict(name):
|
||||
return name == XNAME_DICT or name == LNAME_DICT
|
||||
|
||||
def isitem(name):
|
||||
return name == XNAME_ITEM or name == LNAME_ITEM
|
||||
|
||||
def iskey(name):
|
||||
return name == XNAME_KEY or name == LNAME_KEY
|
||||
|
||||
def islist(name):
|
||||
return name == XNAME_LIST or name == LNAME_LIST
|
||||
|
||||
def hasattrs(element):
|
||||
return len(element.attrib) > 0
|
||||
|
||||
def localname(xname):
|
||||
rcurly = xname.find('}')
|
||||
return xname if rcurly == -1 else xname[rcurly+1:]
|
||||
|
||||
def load(text, match=None):
|
||||
"""This function reads a string that contains the XML of an Atom Feed, then
|
||||
returns the
|
||||
data in a native Python structure (a ``dict`` or ``list``). If you also
|
||||
provide a tag name or path to match, only the matching sub-elements are
|
||||
loaded.
|
||||
|
||||
:param text: The XML text to load.
|
||||
:type text: ``string``
|
||||
:param match: A tag name or path to match (optional).
|
||||
:type match: ``string``
|
||||
"""
|
||||
if text is None: return None
|
||||
text = text.strip()
|
||||
if len(text) == 0: return None
|
||||
nametable = {
|
||||
'namespaces': [],
|
||||
'names': {}
|
||||
}
|
||||
|
||||
# Convert to unicode encoding in only python 2 for xml parser
|
||||
if(sys.version_info < (3, 0, 0) and isinstance(text, unicode)):
|
||||
text = text.encode('utf-8')
|
||||
|
||||
root = XML(text)
|
||||
items = [root] if match is None else root.findall(match)
|
||||
count = len(items)
|
||||
if count == 0:
|
||||
return None
|
||||
elif count == 1:
|
||||
return load_root(items[0], nametable)
|
||||
else:
|
||||
return [load_root(item, nametable) for item in items]
|
||||
|
||||
# Load the attributes of the given element.
|
||||
def load_attrs(element):
|
||||
if not hasattrs(element): return None
|
||||
attrs = record()
|
||||
for key, value in six.iteritems(element.attrib):
|
||||
attrs[key] = value
|
||||
return attrs
|
||||
|
||||
# Parse a <dict> element and return a Python dict
|
||||
def load_dict(element, nametable = None):
|
||||
value = record()
|
||||
children = list(element)
|
||||
for child in children:
|
||||
assert iskey(child.tag)
|
||||
name = child.attrib["name"]
|
||||
value[name] = load_value(child, nametable)
|
||||
return value
|
||||
|
||||
# Loads the given elements attrs & value into single merged dict.
|
||||
def load_elem(element, nametable=None):
|
||||
name = localname(element.tag)
|
||||
attrs = load_attrs(element)
|
||||
value = load_value(element, nametable)
|
||||
if attrs is None: return name, value
|
||||
if value is None: return name, attrs
|
||||
# If value is simple, merge into attrs dict using special key
|
||||
if isinstance(value, six.string_types):
|
||||
attrs["$text"] = value
|
||||
return name, attrs
|
||||
# Both attrs & value are complex, so merge the two dicts, resolving collisions.
|
||||
collision_keys = []
|
||||
for key, val in six.iteritems(attrs):
|
||||
if key in value and key in collision_keys:
|
||||
value[key].append(val)
|
||||
elif key in value and key not in collision_keys:
|
||||
value[key] = [value[key], val]
|
||||
collision_keys.append(key)
|
||||
else:
|
||||
value[key] = val
|
||||
return name, value
|
||||
|
||||
# Parse a <list> element and return a Python list
|
||||
def load_list(element, nametable=None):
|
||||
assert islist(element.tag)
|
||||
value = []
|
||||
children = list(element)
|
||||
for child in children:
|
||||
assert isitem(child.tag)
|
||||
value.append(load_value(child, nametable))
|
||||
return value
|
||||
|
||||
# Load the given root element.
|
||||
def load_root(element, nametable=None):
|
||||
tag = element.tag
|
||||
if isdict(tag): return load_dict(element, nametable)
|
||||
if islist(tag): return load_list(element, nametable)
|
||||
k, v = load_elem(element, nametable)
|
||||
return Record.fromkv(k, v)
|
||||
|
||||
# Load the children of the given element.
|
||||
def load_value(element, nametable=None):
|
||||
children = list(element)
|
||||
count = len(children)
|
||||
|
||||
# No children, assume a simple text value
|
||||
if count == 0:
|
||||
text = element.text
|
||||
if text is None:
|
||||
return None
|
||||
text = text.strip()
|
||||
if len(text) == 0:
|
||||
return None
|
||||
return text
|
||||
|
||||
# Look for the special case of a single well-known structure
|
||||
if count == 1:
|
||||
child = children[0]
|
||||
tag = child.tag
|
||||
if isdict(tag): return load_dict(child, nametable)
|
||||
if islist(tag): return load_list(child, nametable)
|
||||
|
||||
value = record()
|
||||
for child in children:
|
||||
name, item = load_elem(child, nametable)
|
||||
# If we have seen this name before, promote the value to a list
|
||||
if name in value:
|
||||
current = value[name]
|
||||
if not isinstance(current, list):
|
||||
value[name] = [current]
|
||||
value[name].append(item)
|
||||
else:
|
||||
value[name] = item
|
||||
|
||||
return value
|
||||
|
||||
# A generic utility that enables "dot" access to dicts
|
||||
class Record(dict):
|
||||
"""This generic utility class enables dot access to members of a Python
|
||||
dictionary.
|
||||
|
||||
Any key that is also a valid Python identifier can be retrieved as a field.
|
||||
So, for an instance of ``Record`` called ``r``, ``r.key`` is equivalent to
|
||||
``r['key']``. A key such as ``invalid-key`` or ``invalid.key`` cannot be
|
||||
retrieved as a field, because ``-`` and ``.`` are not allowed in
|
||||
identifiers.
|
||||
|
||||
Keys of the form ``a.b.c`` are very natural to write in Python as fields. If
|
||||
a group of keys shares a prefix ending in ``.``, you can retrieve keys as a
|
||||
nested dictionary by calling only the prefix. For example, if ``r`` contains
|
||||
keys ``'foo'``, ``'bar.baz'``, and ``'bar.qux'``, ``r.bar`` returns a record
|
||||
with the keys ``baz`` and ``qux``. If a key contains multiple ``.``, each
|
||||
one is placed into a nested dictionary, so you can write ``r.bar.qux`` or
|
||||
``r['bar.qux']`` interchangeably.
|
||||
"""
|
||||
sep = '.'
|
||||
|
||||
def __call__(self, *args):
|
||||
if len(args) == 0: return self
|
||||
return Record((key, self[key]) for key in args)
|
||||
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
return self[name]
|
||||
except KeyError:
|
||||
raise AttributeError(name)
|
||||
|
||||
def __delattr__(self, name):
|
||||
del self[name]
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
self[name] = value
|
||||
|
||||
@staticmethod
|
||||
def fromkv(k, v):
|
||||
result = record()
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in self:
|
||||
return dict.__getitem__(self, key)
|
||||
key += self.sep
|
||||
result = record()
|
||||
for k,v in six.iteritems(self):
|
||||
if not k.startswith(key):
|
||||
continue
|
||||
suffix = k[len(key):]
|
||||
if '.' in suffix:
|
||||
ks = suffix.split(self.sep)
|
||||
z = result
|
||||
for x in ks[:-1]:
|
||||
if x not in z:
|
||||
z[x] = record()
|
||||
z = z[x]
|
||||
z[ks[-1]] = v
|
||||
else:
|
||||
result[suffix] = v
|
||||
if len(result) == 0:
|
||||
raise KeyError("No key or prefix: %s" % key)
|
||||
return result
|
||||
|
||||
|
||||
def record(value=None):
|
||||
"""This function returns a :class:`Record` instance constructed with an
|
||||
initial value that you provide.
|
||||
|
||||
:param `value`: An initial record value.
|
||||
:type `value`: ``dict``
|
||||
"""
|
||||
if value is None: value = {}
|
||||
return Record(value)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
"""The following imports allow these classes to be imported via
|
||||
the splunklib.modularinput package like so:
|
||||
|
||||
from splunklib.modularinput import *
|
||||
"""
|
||||
from .argument import Argument
|
||||
from .event import Event
|
||||
from .event_writer import EventWriter
|
||||
from .input_definition import InputDefinition
|
||||
from .scheme import Scheme
|
||||
from .script import Script
|
||||
from .validation_definition import ValidationDefinition
|
||||
@@ -1,103 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
try:
|
||||
import xml.etree.ElementTree as ET
|
||||
except ImportError:
|
||||
import xml.etree.cElementTree as ET
|
||||
|
||||
class Argument(object):
|
||||
"""Class representing an argument to a modular input kind.
|
||||
|
||||
``Argument`` is meant to be used with ``Scheme`` to generate an XML
|
||||
definition of the modular input kind that Splunk understands.
|
||||
|
||||
``name`` is the only required parameter for the constructor.
|
||||
|
||||
**Example with least parameters**::
|
||||
|
||||
arg1 = Argument(name="arg1")
|
||||
|
||||
**Example with all parameters**::
|
||||
|
||||
arg2 = Argument(
|
||||
name="arg2",
|
||||
description="This is an argument with lots of parameters",
|
||||
validation="is_pos_int('some_name')",
|
||||
data_type=Argument.data_type_number,
|
||||
required_on_edit=True,
|
||||
required_on_create=True
|
||||
)
|
||||
"""
|
||||
|
||||
# Constant values, do not change.
|
||||
# These should be used for setting the value of an Argument object's data_type field.
|
||||
data_type_boolean = "BOOLEAN"
|
||||
data_type_number = "NUMBER"
|
||||
data_type_string = "STRING"
|
||||
|
||||
def __init__(self, name, description=None, validation=None,
|
||||
data_type=data_type_string, required_on_edit=False, required_on_create=False, title=None):
|
||||
"""
|
||||
:param name: ``string``, identifier for this argument in Splunk.
|
||||
:param description: ``string``, human-readable description of the argument.
|
||||
:param validation: ``string`` specifying how the argument should be validated, if using internal validation.
|
||||
If using external validation, this will be ignored.
|
||||
:param data_type: ``string``, data type of this field; use the class constants.
|
||||
"data_type_boolean", "data_type_number", or "data_type_string".
|
||||
:param required_on_edit: ``Boolean``, whether this arg is required when editing an existing modular input of this kind.
|
||||
:param required_on_create: ``Boolean``, whether this arg is required when creating a modular input of this kind.
|
||||
:param title: ``String``, a human-readable title for the argument.
|
||||
"""
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.validation = validation
|
||||
self.data_type = data_type
|
||||
self.required_on_edit = required_on_edit
|
||||
self.required_on_create = required_on_create
|
||||
self.title = title
|
||||
|
||||
def add_to_document(self, parent):
|
||||
"""Adds an ``Argument`` object to this ElementTree document.
|
||||
|
||||
Adds an <arg> subelement to the parent element, typically <args>
|
||||
and sets up its subelements with their respective text.
|
||||
|
||||
:param parent: An ``ET.Element`` to be the parent of a new <arg> subelement
|
||||
:returns: An ``ET.Element`` object representing this argument.
|
||||
"""
|
||||
arg = ET.SubElement(parent, "arg")
|
||||
arg.set("name", self.name)
|
||||
|
||||
if self.title is not None:
|
||||
ET.SubElement(arg, "title").text = self.title
|
||||
|
||||
if self.description is not None:
|
||||
ET.SubElement(arg, "description").text = self.description
|
||||
|
||||
if self.validation is not None:
|
||||
ET.SubElement(arg, "validation").text = self.validation
|
||||
|
||||
# add all other subelements to this Argument, represented by (tag, text)
|
||||
subelements = [
|
||||
("data_type", self.data_type),
|
||||
("required_on_edit", self.required_on_edit),
|
||||
("required_on_create", self.required_on_create)
|
||||
]
|
||||
|
||||
for name, value in subelements:
|
||||
ET.SubElement(arg, name).text = str(value).lower()
|
||||
|
||||
return arg
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from io import TextIOBase
|
||||
from splunklib.six import ensure_text
|
||||
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError as ie:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
class Event(object):
|
||||
"""Represents an event or fragment of an event to be written by this modular input to Splunk.
|
||||
|
||||
To write an input to a stream, call the ``write_to`` function, passing in a stream.
|
||||
"""
|
||||
def __init__(self, data=None, stanza=None, time=None, host=None, index=None, source=None,
|
||||
sourcetype=None, done=True, unbroken=True):
|
||||
"""There are no required parameters for constructing an Event
|
||||
|
||||
**Example with minimal configuration**::
|
||||
|
||||
my_event = Event(
|
||||
data="This is a test of my new event.",
|
||||
stanza="myStanzaName",
|
||||
time="%.3f" % 1372187084.000
|
||||
)
|
||||
|
||||
**Example with full configuration**::
|
||||
|
||||
excellent_event = Event(
|
||||
data="This is a test of my excellent event.",
|
||||
stanza="excellenceOnly",
|
||||
time="%.3f" % 1372274622.493,
|
||||
host="localhost",
|
||||
index="main",
|
||||
source="Splunk",
|
||||
sourcetype="misc",
|
||||
done=True,
|
||||
unbroken=True
|
||||
)
|
||||
|
||||
:param data: ``string``, the event's text.
|
||||
:param stanza: ``string``, name of the input this event should be sent to.
|
||||
:param time: ``float``, time in seconds, including up to 3 decimal places to represent milliseconds.
|
||||
:param host: ``string``, the event's host, ex: localhost.
|
||||
:param index: ``string``, the index this event is specified to write to, or None if default index.
|
||||
:param source: ``string``, the source of this event, or None to have Splunk guess.
|
||||
:param sourcetype: ``string``, source type currently set on this event, or None to have Splunk guess.
|
||||
:param done: ``boolean``, is this a complete ``Event``? False if an ``Event`` fragment.
|
||||
:param unbroken: ``boolean``, Is this event completely encapsulated in this ``Event`` object?
|
||||
"""
|
||||
self.data = data
|
||||
self.done = done
|
||||
self.host = host
|
||||
self.index = index
|
||||
self.source = source
|
||||
self.sourceType = sourcetype
|
||||
self.stanza = stanza
|
||||
self.time = time
|
||||
self.unbroken = unbroken
|
||||
|
||||
def write_to(self, stream):
|
||||
"""Write an XML representation of self, an ``Event`` object, to the given stream.
|
||||
|
||||
The ``Event`` object will only be written if its data field is defined,
|
||||
otherwise a ``ValueError`` is raised.
|
||||
|
||||
:param stream: stream to write XML to.
|
||||
"""
|
||||
if self.data is None:
|
||||
raise ValueError("Events must have at least the data field set to be written to XML.")
|
||||
|
||||
event = ET.Element("event")
|
||||
if self.stanza is not None:
|
||||
event.set("stanza", self.stanza)
|
||||
event.set("unbroken", str(int(self.unbroken)))
|
||||
|
||||
# if a time isn't set, let Splunk guess by not creating a <time> element
|
||||
if self.time is not None:
|
||||
ET.SubElement(event, "time").text = str(self.time)
|
||||
|
||||
# add all other subelements to this Event, represented by (tag, text)
|
||||
subelements = [
|
||||
("source", self.source),
|
||||
("sourcetype", self.sourceType),
|
||||
("index", self.index),
|
||||
("host", self.host),
|
||||
("data", self.data)
|
||||
]
|
||||
for node, value in subelements:
|
||||
if value is not None:
|
||||
ET.SubElement(event, node).text = value
|
||||
|
||||
if self.done:
|
||||
ET.SubElement(event, "done")
|
||||
|
||||
if isinstance(stream, TextIOBase):
|
||||
stream.write(ensure_text(ET.tostring(event)))
|
||||
else:
|
||||
stream.write(ET.tostring(event))
|
||||
stream.flush()
|
||||
@@ -1,87 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
import sys
|
||||
|
||||
from io import TextIOWrapper, TextIOBase
|
||||
from splunklib.six import ensure_str
|
||||
from .event import ET
|
||||
|
||||
try:
|
||||
from splunklib.six.moves import cStringIO as StringIO
|
||||
except ImportError:
|
||||
from splunklib.six import StringIO
|
||||
|
||||
class EventWriter(object):
|
||||
"""``EventWriter`` writes events and error messages to Splunk from a modular input.
|
||||
Its two important methods are ``writeEvent``, which takes an ``Event`` object,
|
||||
and ``log``, which takes a severity and an error message.
|
||||
"""
|
||||
|
||||
# Severities that Splunk understands for log messages from modular inputs.
|
||||
# Do not change these
|
||||
DEBUG = "DEBUG"
|
||||
INFO = "INFO"
|
||||
WARN = "WARN"
|
||||
ERROR = "ERROR"
|
||||
FATAL = "FATAL"
|
||||
|
||||
def __init__(self, output = sys.stdout, error = sys.stderr):
|
||||
"""
|
||||
:param output: Where to write the output; defaults to sys.stdout.
|
||||
:param error: Where to write any errors; defaults to sys.stderr.
|
||||
"""
|
||||
self._out = output
|
||||
self._err = error
|
||||
|
||||
# has the opening <stream> tag been written yet?
|
||||
self.header_written = False
|
||||
|
||||
def write_event(self, event):
|
||||
"""Writes an ``Event`` object to Splunk.
|
||||
|
||||
:param event: An ``Event`` object.
|
||||
"""
|
||||
|
||||
if not self.header_written:
|
||||
self._out.write("<stream>")
|
||||
self.header_written = True
|
||||
|
||||
event.write_to(self._out)
|
||||
|
||||
def log(self, severity, message):
|
||||
"""Logs messages about the state of this modular input to Splunk.
|
||||
These messages will show up in Splunk's internal logs.
|
||||
|
||||
:param severity: ``string``, severity of message, see severities defined as class constants.
|
||||
:param message: ``string``, message to log.
|
||||
"""
|
||||
|
||||
self._err.write("%s %s\n" % (severity, message))
|
||||
self._err.flush()
|
||||
|
||||
def write_xml_document(self, document):
|
||||
"""Writes a string representation of an
|
||||
``ElementTree`` object to the output stream.
|
||||
|
||||
:param document: An ``ElementTree`` object.
|
||||
"""
|
||||
self._out.write(ensure_str(ET.tostring(document)))
|
||||
self._out.flush()
|
||||
|
||||
def close(self):
|
||||
"""Write the closing </stream> tag to make this XML well formed."""
|
||||
self._out.write("</stream>")
|
||||
self._out.flush()
|
||||
@@ -1,60 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError as ie:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from .utils import parse_xml_data
|
||||
|
||||
class InputDefinition:
|
||||
"""``InputDefinition`` encodes the XML defining inputs that Splunk passes to
|
||||
a modular input script.
|
||||
|
||||
**Example**::
|
||||
|
||||
i = InputDefinition()
|
||||
|
||||
"""
|
||||
def __init__ (self):
|
||||
self.metadata = {}
|
||||
self.inputs = {}
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, InputDefinition):
|
||||
return False
|
||||
return self.metadata == other.metadata and self.inputs == other.inputs
|
||||
|
||||
@staticmethod
|
||||
def parse(stream):
|
||||
"""Parse a stream containing XML into an ``InputDefinition``.
|
||||
|
||||
:param stream: stream containing XML to parse.
|
||||
:return: definition: an ``InputDefinition`` object.
|
||||
"""
|
||||
definition = InputDefinition()
|
||||
|
||||
# parse XML from the stream, then get the root node
|
||||
root = ET.parse(stream).getroot()
|
||||
|
||||
for node in root:
|
||||
if node.tag == "configuration":
|
||||
# get config for each stanza
|
||||
definition.inputs = parse_xml_data(node, "stanza")
|
||||
else:
|
||||
definition.metadata[node.tag] = node.text
|
||||
|
||||
return definition
|
||||
@@ -1,85 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
class Scheme(object):
|
||||
"""Class representing the metadata for a modular input kind.
|
||||
|
||||
A ``Scheme`` specifies a title, description, several options of how Splunk should run modular inputs of this
|
||||
kind, and a set of arguments which define a particular modular input's properties.
|
||||
|
||||
The primary use of ``Scheme`` is to abstract away the construction of XML to feed to Splunk.
|
||||
"""
|
||||
|
||||
# Constant values, do not change
|
||||
# These should be used for setting the value of a Scheme object's streaming_mode field.
|
||||
streaming_mode_simple = "SIMPLE"
|
||||
streaming_mode_xml = "XML"
|
||||
|
||||
def __init__(self, title):
|
||||
"""
|
||||
:param title: ``string`` identifier for this Scheme in Splunk.
|
||||
"""
|
||||
self.title = title
|
||||
self.description = None
|
||||
self.use_external_validation = True
|
||||
self.use_single_instance = False
|
||||
self.streaming_mode = Scheme.streaming_mode_xml
|
||||
|
||||
# list of Argument objects, each to be represented by an <arg> tag
|
||||
self.arguments = []
|
||||
|
||||
def add_argument(self, arg):
|
||||
"""Add the provided argument, ``arg``, to the ``self.arguments`` list.
|
||||
|
||||
:param arg: An ``Argument`` object to add to ``self.arguments``.
|
||||
"""
|
||||
self.arguments.append(arg)
|
||||
|
||||
def to_xml(self):
|
||||
"""Creates an ``ET.Element`` representing self, then returns it.
|
||||
|
||||
:returns: an ``ET.Element`` representing this scheme.
|
||||
"""
|
||||
root = ET.Element("scheme")
|
||||
|
||||
ET.SubElement(root, "title").text = self.title
|
||||
|
||||
# add a description subelement if it's defined
|
||||
if self.description is not None:
|
||||
ET.SubElement(root, "description").text = self.description
|
||||
|
||||
# add all other subelements to this Scheme, represented by (tag, text)
|
||||
subelements = [
|
||||
("use_external_validation", self.use_external_validation),
|
||||
("use_single_instance", self.use_single_instance),
|
||||
("streaming_mode", self.streaming_mode)
|
||||
]
|
||||
for name, value in subelements:
|
||||
ET.SubElement(root, name).text = str(value).lower()
|
||||
|
||||
endpoint = ET.SubElement(root, "endpoint")
|
||||
|
||||
args = ET.SubElement(endpoint, "args")
|
||||
|
||||
# add arguments as subelements to the <args> element
|
||||
for arg in self.arguments:
|
||||
arg.add_to_document(args)
|
||||
|
||||
return root
|
||||
-177
@@ -1,177 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from splunklib.six.moves.urllib.parse import urlsplit
|
||||
import sys
|
||||
|
||||
from ..client import Service
|
||||
from .event_writer import EventWriter
|
||||
from .input_definition import InputDefinition
|
||||
from .validation_definition import ValidationDefinition
|
||||
from splunklib import six
|
||||
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
|
||||
class Script(six.with_metaclass(ABCMeta, object)):
|
||||
"""An abstract base class for implementing modular inputs.
|
||||
|
||||
Subclasses should override ``get_scheme``, ``stream_events``,
|
||||
and optionally ``validate_input`` if the modular input uses
|
||||
external validation.
|
||||
|
||||
The ``run`` function is used to run modular inputs; it typically should
|
||||
not be overridden.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._input_definition = None
|
||||
self._service = None
|
||||
|
||||
def run(self, args):
|
||||
"""Runs this modular input
|
||||
|
||||
:param args: List of command line arguments passed to this script.
|
||||
:returns: An integer to be used as the exit value of this program.
|
||||
"""
|
||||
|
||||
# call the run_script function, which handles the specifics of running
|
||||
# a modular input
|
||||
return self.run_script(args, EventWriter(), sys.stdin)
|
||||
|
||||
def run_script(self, args, event_writer, input_stream):
|
||||
"""Handles all the specifics of running a modular input
|
||||
|
||||
:param args: List of command line arguments passed to this script.
|
||||
:param event_writer: An ``EventWriter`` object for writing events.
|
||||
:param input_stream: An input stream for reading inputs.
|
||||
:returns: An integer to be used as the exit value of this program.
|
||||
"""
|
||||
|
||||
try:
|
||||
if len(args) == 1:
|
||||
# This script is running as an input. Input definitions will be
|
||||
# passed on stdin as XML, and the script will write events on
|
||||
# stdout and log entries on stderr.
|
||||
self._input_definition = InputDefinition.parse(input_stream)
|
||||
self.stream_events(self._input_definition, event_writer)
|
||||
event_writer.close()
|
||||
return 0
|
||||
|
||||
elif str(args[1]).lower() == "--scheme":
|
||||
# Splunk has requested XML specifying the scheme for this
|
||||
# modular input Return it and exit.
|
||||
scheme = self.get_scheme()
|
||||
if scheme is None:
|
||||
event_writer.log(
|
||||
EventWriter.FATAL,
|
||||
"Modular input script returned a null scheme.")
|
||||
return 1
|
||||
else:
|
||||
event_writer.write_xml_document(scheme.to_xml())
|
||||
return 0
|
||||
|
||||
elif args[1].lower() == "--validate-arguments":
|
||||
validation_definition = ValidationDefinition.parse(input_stream)
|
||||
try:
|
||||
self.validate_input(validation_definition)
|
||||
return 0
|
||||
except Exception as e:
|
||||
root = ET.Element("error")
|
||||
ET.SubElement(root, "message").text = str(e)
|
||||
event_writer.write_xml_document(root)
|
||||
|
||||
return 1
|
||||
else:
|
||||
err_string = "ERROR Invalid arguments to modular input script:" + ' '.join(
|
||||
args)
|
||||
event_writer._err.write(err_string)
|
||||
return 1
|
||||
|
||||
except Exception as e:
|
||||
event_writer.log(EventWriter.ERROR, str(e))
|
||||
return 1
|
||||
|
||||
@property
|
||||
def service(self):
|
||||
""" Returns a Splunk service object for this script invocation.
|
||||
|
||||
The service object is created from the Splunkd URI and session key
|
||||
passed to the command invocation on the modular input stream. It is
|
||||
available as soon as the :code:`Script.stream_events` method is
|
||||
called.
|
||||
|
||||
:return: :class:`splunklib.client.Service`. A value of None is returned,
|
||||
if you call this method before the :code:`Script.stream_events` method
|
||||
is called.
|
||||
|
||||
"""
|
||||
if self._service is not None:
|
||||
return self._service
|
||||
|
||||
if self._input_definition is None:
|
||||
return None
|
||||
|
||||
splunkd_uri = self._input_definition.metadata["server_uri"]
|
||||
session_key = self._input_definition.metadata["session_key"]
|
||||
|
||||
splunkd = urlsplit(splunkd_uri, allow_fragments=False)
|
||||
|
||||
self._service = Service(
|
||||
scheme=splunkd.scheme,
|
||||
host=splunkd.hostname,
|
||||
port=splunkd.port,
|
||||
token=session_key,
|
||||
)
|
||||
|
||||
return self._service
|
||||
|
||||
@abstractmethod
|
||||
def get_scheme(self):
|
||||
"""The scheme defines the parameters understood by this modular input.
|
||||
|
||||
:return: a ``Scheme`` object representing the parameters for this modular input.
|
||||
"""
|
||||
|
||||
def validate_input(self, definition):
|
||||
"""Handles external validation for modular input kinds.
|
||||
|
||||
When Splunk calls a modular input script in validation mode, it will
|
||||
pass in an XML document giving information about the Splunk instance (so
|
||||
you can call back into it if needed) and the name and parameters of the
|
||||
proposed input.
|
||||
|
||||
If this function does not throw an exception, the validation is assumed
|
||||
to succeed. Otherwise any errors thrown will be turned into a string and
|
||||
logged back to Splunk.
|
||||
|
||||
The default implementation always passes.
|
||||
|
||||
:param definition: The parameters for the proposed input passed by splunkd.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def stream_events(self, inputs, ew):
|
||||
"""The method called to stream events into Splunk. It should do all of its output via
|
||||
EventWriter rather than assuming that there is a console attached.
|
||||
|
||||
:param inputs: An ``InputDefinition`` object.
|
||||
:param ew: An object with methods to write events and log messages to Splunk.
|
||||
"""
|
||||
@@ -1,74 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
# File for utility functions
|
||||
|
||||
from __future__ import absolute_import
|
||||
from splunklib.six.moves import zip
|
||||
def xml_compare(expected, found):
|
||||
"""Checks equality of two ``ElementTree`` objects.
|
||||
|
||||
:param expected: An ``ElementTree`` object.
|
||||
:param found: An ``ElementTree`` object.
|
||||
:return: ``Boolean``, whether the two objects are equal.
|
||||
"""
|
||||
|
||||
# if comparing the same ET object
|
||||
if expected == found:
|
||||
return True
|
||||
|
||||
# compare element attributes, ignoring order
|
||||
if set(expected.items()) != set(found.items()):
|
||||
return False
|
||||
|
||||
# check for equal number of children
|
||||
expected_children = list(expected)
|
||||
found_children = list(found)
|
||||
if len(expected_children) != len(found_children):
|
||||
return False
|
||||
|
||||
# compare children
|
||||
if not all([xml_compare(a, b) for a, b in zip(expected_children, found_children)]):
|
||||
return False
|
||||
|
||||
# compare elements, if there is no text node, return True
|
||||
if (expected.text is None or expected.text.strip() == "") \
|
||||
and (found.text is None or found.text.strip() == ""):
|
||||
return True
|
||||
else:
|
||||
return expected.tag == found.tag and expected.text == found.text \
|
||||
and expected.attrib == found.attrib
|
||||
|
||||
def parse_parameters(param_node):
|
||||
if param_node.tag == "param":
|
||||
return param_node.text
|
||||
elif param_node.tag == "param_list":
|
||||
parameters = []
|
||||
for mvp in param_node:
|
||||
parameters.append(mvp.text)
|
||||
return parameters
|
||||
else:
|
||||
raise ValueError("Invalid configuration scheme, %s tag unexpected." % param_node.tag)
|
||||
|
||||
def parse_xml_data(parent_node, child_node_tag):
|
||||
data = {}
|
||||
for child in parent_node:
|
||||
if child.tag == child_node_tag:
|
||||
if child_node_tag == "stanza":
|
||||
data[child.get("name")] = {}
|
||||
for param in child:
|
||||
data[child.get("name")][param.get("name")] = parse_parameters(param)
|
||||
elif "item" == parent_node.tag:
|
||||
data[child.get("name")] = parse_parameters(child)
|
||||
return data
|
||||
@@ -1,86 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import absolute_import
|
||||
try:
|
||||
import xml.etree.cElementTree as ET
|
||||
except ImportError as ie:
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from .utils import parse_xml_data
|
||||
|
||||
|
||||
class ValidationDefinition(object):
|
||||
"""This class represents the XML sent by Splunk for external validation of a
|
||||
new modular input.
|
||||
|
||||
**Example**::
|
||||
|
||||
v = ValidationDefinition()
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
self.metadata = {}
|
||||
self.parameters = {}
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, ValidationDefinition):
|
||||
return False
|
||||
return self.metadata == other.metadata and self.parameters == other.parameters
|
||||
|
||||
@staticmethod
|
||||
def parse(stream):
|
||||
"""Creates a ``ValidationDefinition`` from a provided stream containing XML.
|
||||
|
||||
The XML typically will look like this:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<items>
|
||||
<server_host>myHost</server_host>
|
||||
<server_uri>https://127.0.0.1:8089</server_uri>
|
||||
<session_key>123102983109283019283</session_key>
|
||||
<checkpoint_dir>/opt/splunk/var/lib/splunk/modinputs</checkpoint_dir>
|
||||
<item name="myScheme">
|
||||
<param name="param1">value1</param>
|
||||
<param_list name="param2">
|
||||
<value>value2</value>
|
||||
<value>value3</value>
|
||||
<value>value4</value>
|
||||
</param_list>
|
||||
</item>
|
||||
</items>
|
||||
|
||||
:param stream: ``Stream`` containing XML to parse.
|
||||
:return: A ``ValidationDefinition`` object.
|
||||
|
||||
"""
|
||||
|
||||
definition = ValidationDefinition()
|
||||
|
||||
# parse XML from the stream, then get the root node
|
||||
root = ET.parse(stream).getroot()
|
||||
|
||||
for node in root:
|
||||
# lone item node
|
||||
if node.tag == "item":
|
||||
# name from item node
|
||||
definition.metadata["name"] = node.get("name")
|
||||
definition.parameters = parse_xml_data(node, "")
|
||||
else:
|
||||
# Store anything else in metadata
|
||||
definition.metadata[node.tag] = node.text
|
||||
|
||||
return definition
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
# Copyright (c) 2009 Raymond Hettinger
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from UserDict import DictMixin
|
||||
|
||||
|
||||
class OrderedDict(dict, DictMixin):
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
if len(args) > 1:
|
||||
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
||||
try:
|
||||
self.__end
|
||||
except AttributeError:
|
||||
self.clear()
|
||||
self.update(*args, **kwds)
|
||||
|
||||
def clear(self):
|
||||
self.__end = end = []
|
||||
end += [None, end, end] # sentinel node for doubly linked list
|
||||
self.__map = {} # key --> [key, prev, next]
|
||||
dict.clear(self)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key not in self:
|
||||
end = self.__end
|
||||
curr = end[1]
|
||||
curr[2] = end[1] = self.__map[key] = [key, curr, end]
|
||||
dict.__setitem__(self, key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
dict.__delitem__(self, key)
|
||||
key, prev, next = self.__map.pop(key)
|
||||
prev[2] = next
|
||||
next[1] = prev
|
||||
|
||||
def __iter__(self):
|
||||
end = self.__end
|
||||
curr = end[2]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[2]
|
||||
|
||||
def __reversed__(self):
|
||||
end = self.__end
|
||||
curr = end[1]
|
||||
while curr is not end:
|
||||
yield curr[0]
|
||||
curr = curr[1]
|
||||
|
||||
def popitem(self, last=True):
|
||||
if not self:
|
||||
raise KeyError('dictionary is empty')
|
||||
if last:
|
||||
key = reversed(self).next()
|
||||
else:
|
||||
key = iter(self).next()
|
||||
value = self.pop(key)
|
||||
return key, value
|
||||
|
||||
def __reduce__(self):
|
||||
items = [[k, self[k]] for k in self]
|
||||
tmp = self.__map, self.__end
|
||||
del self.__map, self.__end
|
||||
inst_dict = vars(self).copy()
|
||||
self.__map, self.__end = tmp
|
||||
if inst_dict:
|
||||
return (self.__class__, (items,), inst_dict)
|
||||
return self.__class__, (items,)
|
||||
|
||||
def keys(self):
|
||||
return list(self)
|
||||
|
||||
setdefault = DictMixin.setdefault
|
||||
update = DictMixin.update
|
||||
pop = DictMixin.pop
|
||||
values = DictMixin.values
|
||||
items = DictMixin.items
|
||||
iterkeys = DictMixin.iterkeys
|
||||
itervalues = DictMixin.itervalues
|
||||
iteritems = DictMixin.iteritems
|
||||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return '%s()' % (self.__class__.__name__,)
|
||||
return '%s(%r)' % (self.__class__.__name__, self.items())
|
||||
|
||||
def copy(self):
|
||||
return self.__class__(self)
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, iterable, value=None):
|
||||
d = cls()
|
||||
for key in iterable:
|
||||
d[key] = value
|
||||
return d
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, OrderedDict):
|
||||
if len(self) != len(other):
|
||||
return False
|
||||
for p, q in zip(self.items(), other.items()):
|
||||
if p != q:
|
||||
return False
|
||||
return True
|
||||
return dict.__eq__(self, other)
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
-295
@@ -1,295 +0,0 @@
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""The **splunklib.results** module provides a streaming XML reader for Splunk
|
||||
search results.
|
||||
|
||||
Splunk search results can be returned in a variety of formats including XML,
|
||||
JSON, and CSV. To make it easier to stream search results in XML format, they
|
||||
are returned as a stream of XML *fragments*, not as a single XML document. This
|
||||
module supports incrementally reading one result record at a time from such a
|
||||
result stream. This module also provides a friendly iterator-based interface for
|
||||
accessing search results while avoiding buffering the result set, which can be
|
||||
very large.
|
||||
|
||||
To use the reader, instantiate :class:`ResultsReader` on a search result stream
|
||||
as follows:::
|
||||
|
||||
reader = ResultsReader(result_stream)
|
||||
for item in reader:
|
||||
print(item)
|
||||
print "Results are a preview: %s" % reader.is_preview
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from splunklib import six
|
||||
try:
|
||||
import xml.etree.cElementTree as et
|
||||
except:
|
||||
import xml.etree.ElementTree as et
|
||||
|
||||
try:
|
||||
from collections import OrderedDict # must be python 2.7
|
||||
except ImportError:
|
||||
from .ordereddict import OrderedDict
|
||||
|
||||
try:
|
||||
from splunklib.six.moves import cStringIO as StringIO
|
||||
except:
|
||||
from splunklib.six import StringIO
|
||||
|
||||
__all__ = [
|
||||
"ResultsReader",
|
||||
"Message"
|
||||
]
|
||||
|
||||
class Message(object):
|
||||
"""This class represents informational messages that Splunk interleaves in the results stream.
|
||||
|
||||
``Message`` takes two arguments: a string giving the message type (e.g., "DEBUG"), and
|
||||
a string giving the message itself.
|
||||
|
||||
**Example**::
|
||||
|
||||
m = Message("DEBUG", "There's something in that variable...")
|
||||
"""
|
||||
def __init__(self, type_, message):
|
||||
self.type = type_
|
||||
self.message = message
|
||||
|
||||
def __repr__(self):
|
||||
return "%s: %s" % (self.type, self.message)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.type, self.message) == (other.type, other.message)
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.type, self.message))
|
||||
|
||||
class _ConcatenatedStream(object):
|
||||
"""Lazily concatenate zero or more streams into a stream.
|
||||
|
||||
As you read from the concatenated stream, you get characters from
|
||||
each stream passed to ``_ConcatenatedStream``, in order.
|
||||
|
||||
**Example**::
|
||||
|
||||
from StringIO import StringIO
|
||||
s = _ConcatenatedStream(StringIO("abc"), StringIO("def"))
|
||||
assert s.read() == "abcdef"
|
||||
"""
|
||||
def __init__(self, *streams):
|
||||
self.streams = list(streams)
|
||||
|
||||
def read(self, n=None):
|
||||
"""Read at most *n* characters from this stream.
|
||||
|
||||
If *n* is ``None``, return all available characters.
|
||||
"""
|
||||
response = b""
|
||||
while len(self.streams) > 0 and (n is None or n > 0):
|
||||
txt = self.streams[0].read(n)
|
||||
response += txt
|
||||
if n is not None:
|
||||
n -= len(txt)
|
||||
if n is None or n > 0:
|
||||
del self.streams[0]
|
||||
return response
|
||||
|
||||
class _XMLDTDFilter(object):
|
||||
"""Lazily remove all XML DTDs from a stream.
|
||||
|
||||
All substrings matching the regular expression <?[^>]*> are
|
||||
removed in their entirety from the stream. No regular expressions
|
||||
are used, however, so everything still streams properly.
|
||||
|
||||
**Example**::
|
||||
|
||||
from StringIO import StringIO
|
||||
s = _XMLDTDFilter("<?xml abcd><element><?xml ...></element>")
|
||||
assert s.read() == "<element></element>"
|
||||
"""
|
||||
def __init__(self, stream):
|
||||
self.stream = stream
|
||||
|
||||
def read(self, n=None):
|
||||
"""Read at most *n* characters from this stream.
|
||||
|
||||
If *n* is ``None``, return all available characters.
|
||||
"""
|
||||
response = b""
|
||||
while n is None or n > 0:
|
||||
c = self.stream.read(1)
|
||||
if c == b"":
|
||||
break
|
||||
elif c == b"<":
|
||||
c += self.stream.read(1)
|
||||
if c == b"<?":
|
||||
while True:
|
||||
q = self.stream.read(1)
|
||||
if q == b">":
|
||||
break
|
||||
else:
|
||||
response += c
|
||||
if n is not None:
|
||||
n -= len(c)
|
||||
else:
|
||||
response += c
|
||||
if n is not None:
|
||||
n -= 1
|
||||
return response
|
||||
|
||||
class ResultsReader(object):
|
||||
"""This class returns dictionaries and Splunk messages from an XML results
|
||||
stream.
|
||||
|
||||
``ResultsReader`` is iterable, and returns a ``dict`` for results, or a
|
||||
:class:`Message` object for Splunk messages. This class has one field,
|
||||
``is_preview``, which is ``True`` when the results are a preview from a
|
||||
running search, or ``False`` when the results are from a completed search.
|
||||
|
||||
This function has no network activity other than what is implicit in the
|
||||
stream it operates on.
|
||||
|
||||
:param `stream`: The stream to read from (any object that supports
|
||||
``.read()``).
|
||||
|
||||
**Example**::
|
||||
|
||||
import results
|
||||
response = ... # the body of an HTTP response
|
||||
reader = results.ResultsReader(response)
|
||||
for result in reader:
|
||||
if isinstance(result, dict):
|
||||
print "Result: %s" % result
|
||||
elif isinstance(result, results.Message):
|
||||
print "Message: %s" % result
|
||||
print "is_preview = %s " % reader.is_preview
|
||||
"""
|
||||
# Be sure to update the docstrings of client.Jobs.oneshot,
|
||||
# client.Job.results_preview and client.Job.results to match any
|
||||
# changes made to ResultsReader.
|
||||
#
|
||||
# This wouldn't be a class, just the _parse_results function below,
|
||||
# except that you cannot get the current generator inside the
|
||||
# function creating that generator. Thus it's all wrapped up for
|
||||
# the sake of one field.
|
||||
def __init__(self, stream):
|
||||
# The search/jobs/exports endpoint, when run with
|
||||
# earliest_time=rt and latest_time=rt streams a sequence of
|
||||
# XML documents, each containing a result, as opposed to one
|
||||
# results element containing lots of results. Python's XML
|
||||
# parsers are broken, and instead of reading one full document
|
||||
# and returning the stream that follows untouched, they
|
||||
# destroy the stream and throw an error. To get around this,
|
||||
# we remove all the DTD definitions inline, then wrap the
|
||||
# fragments in a fiction <doc> element to make the parser happy.
|
||||
stream = _XMLDTDFilter(stream)
|
||||
stream = _ConcatenatedStream(BytesIO(b"<doc>"), stream, BytesIO(b"</doc>"))
|
||||
self.is_preview = None
|
||||
self._gen = self._parse_results(stream)
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
return next(self._gen)
|
||||
|
||||
__next__ = next
|
||||
|
||||
def _parse_results(self, stream):
|
||||
"""Parse results and messages out of *stream*."""
|
||||
result = None
|
||||
values = None
|
||||
try:
|
||||
for event, elem in et.iterparse(stream, events=('start', 'end')):
|
||||
if elem.tag == 'results' and event == 'start':
|
||||
# The wrapper element is a <results preview="0|1">. We
|
||||
# don't care about it except to tell is whether these
|
||||
# are preview results, or the final results from the
|
||||
# search.
|
||||
is_preview = elem.attrib['preview'] == '1'
|
||||
self.is_preview = is_preview
|
||||
if elem.tag == 'result':
|
||||
if event == 'start':
|
||||
result = OrderedDict()
|
||||
elif event == 'end':
|
||||
yield result
|
||||
result = None
|
||||
elem.clear()
|
||||
|
||||
elif elem.tag == 'field' and result is not None:
|
||||
# We need the 'result is not None' check because
|
||||
# 'field' is also the element name in the <meta>
|
||||
# header that gives field order, which is not what we
|
||||
# want at all.
|
||||
if event == 'start':
|
||||
values = []
|
||||
elif event == 'end':
|
||||
field_name = elem.attrib['k']
|
||||
if len(values) == 1:
|
||||
result[field_name] = values[0]
|
||||
else:
|
||||
result[field_name] = values
|
||||
# Calling .clear() is necessary to let the
|
||||
# element be garbage collected. Otherwise
|
||||
# arbitrarily large results sets will use
|
||||
# arbitrarily large memory intead of
|
||||
# streaming.
|
||||
elem.clear()
|
||||
|
||||
elif elem.tag in ('text', 'v') and event == 'end':
|
||||
try:
|
||||
text = "".join(elem.itertext())
|
||||
except AttributeError:
|
||||
# Assume we're running in Python < 2.7, before itertext() was added
|
||||
# So we'll define it here
|
||||
|
||||
def __itertext(self):
|
||||
tag = self.tag
|
||||
if not isinstance(tag, six.string_types) and tag is not None:
|
||||
return
|
||||
if self.text:
|
||||
yield self.text
|
||||
for e in self:
|
||||
for s in __itertext(e):
|
||||
yield s
|
||||
if e.tail:
|
||||
yield e.tail
|
||||
|
||||
text = "".join(__itertext(elem))
|
||||
values.append(text)
|
||||
elem.clear()
|
||||
|
||||
elif elem.tag == 'msg':
|
||||
if event == 'start':
|
||||
msg_type = elem.attrib['type']
|
||||
elif event == 'end':
|
||||
text = elem.text if elem.text is not None else ""
|
||||
yield Message(msg_type, text)
|
||||
elem.clear()
|
||||
except SyntaxError as pe:
|
||||
# This is here to handle the same incorrect return from
|
||||
# splunk that is described in __init__.
|
||||
if 'no element found' in pe.msg:
|
||||
return
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
|
||||
.. topic:: Design Notes
|
||||
|
||||
1. Commands are constrained to this ABNF grammar::
|
||||
|
||||
command = command-name *[wsp option] *[wsp [dquote] field-name [dquote]]
|
||||
command-name = alpha *( alpha / digit )
|
||||
option = option-name [wsp] "=" [wsp] option-value
|
||||
option-name = alpha *( alpha / digit / "_" )
|
||||
option-value = word / quoted-string
|
||||
word = 1*( %01-%08 / %0B / %0C / %0E-1F / %21 / %23-%FF ) ; Any character but DQUOTE and WSP
|
||||
quoted-string = dquote *( word / wsp / "\" dquote / dquote dquote ) dquote
|
||||
field-name = ( "_" / alpha ) *( alpha / digit / "_" / "." / "-" )
|
||||
|
||||
It does not show that :code:`field-name` values may be comma-separated. This is because Splunk strips commas from
|
||||
the command line. A search command will never see them.
|
||||
|
||||
2. Search commands targeting versions of Splunk prior to 6.3 must be statically configured as follows:
|
||||
|
||||
.. code-block:: text
|
||||
:linenos:
|
||||
|
||||
[command_name]
|
||||
filename = command_name.py
|
||||
supports_getinfo = true
|
||||
supports_rawargs = true
|
||||
|
||||
No other static configuration is required or expected and may interfere with command execution.
|
||||
|
||||
3. Commands support dynamic probing for settings.
|
||||
|
||||
Splunk probes for settings dynamically when :code:`supports_getinfo=true`.
|
||||
You must add this line to the commands.conf stanza for each of your search
|
||||
commands.
|
||||
|
||||
4. Commands do not support parsed arguments on the command line.
|
||||
|
||||
Splunk parses arguments when :code:`supports_rawargs=false`. The
|
||||
:code:`SearchCommand` class sets this value unconditionally. You cannot
|
||||
override it.
|
||||
|
||||
**Rationale**
|
||||
|
||||
Splunk parses arguments by stripping quotes, nothing more. This may be useful
|
||||
in some cases, but doesn't work well with our chosen grammar.
|
||||
|
||||
5. Commands consume input headers.
|
||||
|
||||
An input header is provided by Splunk when :code:`enableheader=true`. The
|
||||
:class:`SearchCommand` class sets this value unconditionally. You cannot
|
||||
override it.
|
||||
|
||||
6. Commands produce an output messages header.
|
||||
|
||||
Splunk expects a command to produce an output messages header when
|
||||
:code:`outputheader=true`. The :class:`SearchCommand` class sets this value
|
||||
unconditionally. You cannot override it.
|
||||
|
||||
7. Commands support multi-value fields.
|
||||
|
||||
Multi-value fields are provided and consumed by Splunk when
|
||||
:code:`supports_multivalue=true`. This value is fixed. You cannot override
|
||||
it.
|
||||
|
||||
8. This module represents all fields on the output stream in multi-value
|
||||
format.
|
||||
|
||||
Splunk recognizes two kinds of data: :code:`value` and :code:`list(value)`.
|
||||
The multi-value format represents these data in field pairs. Given field
|
||||
:code:`name` the multi-value format calls for the creation of this pair of
|
||||
fields.
|
||||
|
||||
================= =========================================================
|
||||
Field name Field data
|
||||
================= =========================================================
|
||||
:code:`name` Value or text from which a list of values was derived.
|
||||
|
||||
:code:`__mv_name` Empty, if :code:`field` represents a :code:`value`;
|
||||
otherwise, an encoded :code:`list(value)`. Values in the
|
||||
list are wrapped in dollar signs ($) and separated by
|
||||
semi-colons (;). Dollar signs ($) within a value are
|
||||
represented by a pair of dollar signs ($$).
|
||||
================= =========================================================
|
||||
|
||||
Serializing data in this format enables streaming and reduces a command's
|
||||
memory footprint at the cost of one extra byte of data per field per record
|
||||
and a small amount of extra processing time by the next command in the
|
||||
pipeline.
|
||||
|
||||
9. A :class:`ReportingCommand` must override :meth:`~ReportingCommand.reduce`
|
||||
and may override :meth:`~ReportingCommand.map`. Map/reduce commands on the
|
||||
Splunk processing pipeline are distinguished as this example illustrates.
|
||||
|
||||
**Splunk command**
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
sum total=total_date_hour date_hour
|
||||
|
||||
**Map command line**
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
sum __GETINFO__ __map__ total=total_date_hour date_hour
|
||||
sum __EXECUTE__ __map__ total=total_date_hour date_hour
|
||||
|
||||
**Reduce command line**
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
sum __GETINFO__ total=total_date_hour date_hour
|
||||
sum __EXECUTE__ total=total_date_hour date_hour
|
||||
|
||||
The :code:`__map__` argument is introduced by
|
||||
:meth:`ReportingCommand._execute`. Search command authors cannot influence
|
||||
the contents of the command line in this release.
|
||||
|
||||
.. topic:: References
|
||||
|
||||
1. `Search command style guide <http://docs.splunk.com/Documentation/Splunk/6.0/Search/Searchcommandstyleguide>`__
|
||||
|
||||
2. `Commands.conf.spec <http://docs.splunk.com/Documentation/Splunk/5.0.5/Admin/Commandsconf>`_
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from .environment import *
|
||||
from .decorators import *
|
||||
from .validators import *
|
||||
|
||||
from .generating_command import GeneratingCommand
|
||||
from .streaming_command import StreamingCommand
|
||||
from .eventing_command import EventingCommand
|
||||
from .reporting_command import ReportingCommand
|
||||
|
||||
from .external_search_command import execute, ExternalSearchCommand
|
||||
from .search_command import dispatch, SearchMetric
|
||||
@@ -1,450 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
from splunklib import six
|
||||
|
||||
try:
|
||||
from collections import OrderedDict # must be python 2.7
|
||||
except ImportError:
|
||||
from ..ordereddict import OrderedDict
|
||||
|
||||
from inspect import getmembers, isclass, isfunction
|
||||
from splunklib.six.moves import map as imap
|
||||
|
||||
from .internals import ConfigurationSettingsType, json_encode_string
|
||||
from .validators import OptionName
|
||||
|
||||
|
||||
class Configuration(object):
|
||||
""" Defines the configuration settings for a search command.
|
||||
|
||||
Documents, validates, and ensures that only relevant configuration settings are applied. Adds a :code:`name` class
|
||||
variable to search command classes that don't have one. The :code:`name` is derived from the name of the class.
|
||||
By convention command class names end with the word "Command". To derive :code:`name` the word "Command" is removed
|
||||
from the end of the class name and then converted to lower case for conformance with the `Search command style guide
|
||||
<http://docs.splunk.com/Documentation/Splunk/latest/Search/Searchcommandstyleguide>`__
|
||||
|
||||
"""
|
||||
def __init__(self, o=None, **kwargs):
|
||||
#
|
||||
# The o argument enables the configuration decorator to be used with or without parentheses. For example, it
|
||||
# enables you to write code that looks like this:
|
||||
#
|
||||
# @Configuration
|
||||
# class Foo(SearchCommand):
|
||||
# ...
|
||||
#
|
||||
# @Configuration()
|
||||
# class Bar(SearchCommand):
|
||||
# ...
|
||||
#
|
||||
# Without the o argument, the Python compiler will complain about the first form. With the o argument, both
|
||||
# forms work. The first form provides a value for o: Foo. The second form does does not provide a value for o.
|
||||
# The class or method decorated is not passed to the constructor. A value of None is passed instead.
|
||||
#
|
||||
self.settings = kwargs
|
||||
|
||||
def __call__(self, o):
|
||||
|
||||
if isfunction(o):
|
||||
# We must wait to finalize configuration as the class containing this function is under construction
|
||||
# at the time this call to decorate a member function. This will be handled in the call to
|
||||
# o.ConfigurationSettings.fix_up(o) in the elif clause of this code block.
|
||||
o._settings = self.settings
|
||||
elif isclass(o):
|
||||
|
||||
# Set command name
|
||||
|
||||
name = o.__name__
|
||||
if name.endswith('Command'):
|
||||
name = name[:-len('Command')]
|
||||
o.name = six.text_type(name.lower())
|
||||
|
||||
# Construct ConfigurationSettings instance for the command class
|
||||
|
||||
o.ConfigurationSettings = ConfigurationSettingsType(
|
||||
module=o.__module__ + '.' + o.__name__,
|
||||
name='ConfigurationSettings',
|
||||
bases=(o.ConfigurationSettings,))
|
||||
|
||||
ConfigurationSetting.fix_up(o.ConfigurationSettings, self.settings)
|
||||
o.ConfigurationSettings.fix_up(o)
|
||||
Option.fix_up(o)
|
||||
else:
|
||||
raise TypeError('Incorrect usage: Configuration decorator applied to {0}'.format(type(o), o.__name__))
|
||||
|
||||
return o
|
||||
|
||||
|
||||
class ConfigurationSetting(property):
|
||||
""" Generates a :class:`property` representing the named configuration setting
|
||||
|
||||
This is a convenience function designed to reduce the amount of boiler-plate code you must write; most notably for
|
||||
property setters.
|
||||
|
||||
:param name: Configuration setting name.
|
||||
:type name: str or unicode
|
||||
|
||||
:param doc: A documentation string.
|
||||
:type doc: bytes, unicode or NoneType
|
||||
|
||||
:param readonly: If true, specifies that the configuration setting is fixed.
|
||||
:type name: bool or NoneType
|
||||
|
||||
:param value: Configuration setting value.
|
||||
|
||||
:return: A :class:`property` instance representing the configuration setting.
|
||||
:rtype: property
|
||||
|
||||
"""
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None, name=None, readonly=None, value=None):
|
||||
property.__init__(self, fget=fget, fset=fset, fdel=fdel, doc=doc)
|
||||
self._readonly = readonly
|
||||
self._value = value
|
||||
self._name = name
|
||||
|
||||
def __call__(self, function):
|
||||
return self.getter(function)
|
||||
|
||||
def deleter(self, function):
|
||||
return self._copy_extra_attributes(property.deleter(self, function))
|
||||
|
||||
def getter(self, function):
|
||||
return self._copy_extra_attributes(property.getter(self, function))
|
||||
|
||||
def setter(self, function):
|
||||
return self._copy_extra_attributes(property.setter(self, function))
|
||||
|
||||
@staticmethod
|
||||
def fix_up(cls, values):
|
||||
|
||||
is_configuration_setting = lambda attribute: isinstance(attribute, ConfigurationSetting)
|
||||
definitions = getmembers(cls, is_configuration_setting)
|
||||
i = 0
|
||||
|
||||
for name, setting in definitions:
|
||||
|
||||
if setting._name is None:
|
||||
setting._name = name = six.text_type(name)
|
||||
else:
|
||||
name = setting._name
|
||||
|
||||
validate, specification = setting._get_specification()
|
||||
backing_field_name = '_' + name
|
||||
|
||||
if setting.fget is None and setting.fset is None and setting.fdel is None:
|
||||
|
||||
value = setting._value
|
||||
|
||||
if setting._readonly or value is not None:
|
||||
validate(specification, name, value)
|
||||
|
||||
def fget(bfn, value):
|
||||
return lambda this: getattr(this, bfn, value)
|
||||
|
||||
setting = setting.getter(fget(backing_field_name, value))
|
||||
|
||||
if not setting._readonly:
|
||||
|
||||
def fset(bfn, validate, specification, name):
|
||||
return lambda this, value: setattr(this, bfn, validate(specification, name, value))
|
||||
|
||||
setting = setting.setter(fset(backing_field_name, validate, specification, name))
|
||||
|
||||
setattr(cls, name, setting)
|
||||
|
||||
def is_supported_by_protocol(supporting_protocols):
|
||||
|
||||
def is_supported_by_protocol(version):
|
||||
return version in supporting_protocols
|
||||
|
||||
return is_supported_by_protocol
|
||||
|
||||
del setting._name, setting._value, setting._readonly
|
||||
|
||||
setting.is_supported_by_protocol = is_supported_by_protocol(specification.supporting_protocols)
|
||||
setting.supporting_protocols = specification.supporting_protocols
|
||||
setting.backing_field_name = backing_field_name
|
||||
definitions[i] = setting
|
||||
setting.name = name
|
||||
|
||||
i += 1
|
||||
|
||||
try:
|
||||
value = values[name]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
if setting.fset is None:
|
||||
raise ValueError('The value of configuration setting {} is fixed'.format(name))
|
||||
|
||||
setattr(cls, backing_field_name, validate(specification, name, value))
|
||||
del values[name]
|
||||
|
||||
if len(values) > 0:
|
||||
settings = sorted(list(six.iteritems(values)))
|
||||
settings = imap(lambda n_v: '{}={}'.format(n_v[0], repr(n_v[1])), settings)
|
||||
raise AttributeError('Inapplicable configuration settings: ' + ', '.join(settings))
|
||||
|
||||
cls.configuration_setting_definitions = definitions
|
||||
|
||||
def _copy_extra_attributes(self, other):
|
||||
other._readonly = self._readonly
|
||||
other._value = self._value
|
||||
other._name = self._name
|
||||
return other
|
||||
|
||||
def _get_specification(self):
|
||||
|
||||
name = self._name
|
||||
|
||||
try:
|
||||
specification = ConfigurationSettingsType.specification_matrix[name]
|
||||
except KeyError:
|
||||
raise AttributeError('Unknown configuration setting: {}={}'.format(name, repr(self._value)))
|
||||
|
||||
return ConfigurationSettingsType.validate_configuration_setting, specification
|
||||
|
||||
|
||||
class Option(property):
|
||||
""" Represents a search command option.
|
||||
|
||||
Required options must be specified on the search command line.
|
||||
|
||||
**Example:**
|
||||
|
||||
Short form (recommended). When you are satisfied with built-in or custom validation behaviors.
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
from splunklib.searchcommands.decorators import Option
|
||||
from splunklib.searchcommands.validators import Fieldname
|
||||
|
||||
total = Option(
|
||||
doc=''' **Syntax:** **total=***<fieldname>*
|
||||
**Description:** Name of the field that will hold the computed
|
||||
sum''',
|
||||
require=True, validate=Fieldname())
|
||||
|
||||
**Example:**
|
||||
|
||||
Long form. Useful when you wish to manage the option value and its deleter/getter/setter side-effects yourself. You
|
||||
must provide a getter and a setter. If your :code:`Option` requires `destruction <https://docs.python.org/2/reference/datamodel.html#object.__del__>`_ you must
|
||||
also provide a deleter. You must be prepared to accept a value of :const:`None` which indicates that your
|
||||
:code:`Option` is unset.
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
from splunklib.searchcommands import Option
|
||||
|
||||
@Option()
|
||||
def logging_configuration(self):
|
||||
\""" **Syntax:** logging_configuration=<path>
|
||||
**Description:** Loads an alternative logging configuration file for a command invocation. The logging
|
||||
configuration file must be in Python ConfigParser-format. The *<path>* name and all path names specified in
|
||||
configuration are relative to the app root directory.
|
||||
|
||||
\"""
|
||||
return self._logging_configuration
|
||||
|
||||
@logging_configuration.setter
|
||||
def logging_configuration(self, value):
|
||||
if value is not None
|
||||
logging.configure(value)
|
||||
self._logging_configuration = value
|
||||
|
||||
def __init__(self)
|
||||
self._logging_configuration = None
|
||||
|
||||
"""
|
||||
def __init__(self, fget=None, fset=None, fdel=None, doc=None, name=None, default=None, require=None, validate=None):
|
||||
property.__init__(self, fget, fset, fdel, doc)
|
||||
self.name = name
|
||||
self.default = default
|
||||
self.validate = validate
|
||||
self.require = bool(require)
|
||||
|
||||
def __call__(self, function):
|
||||
return self.getter(function)
|
||||
|
||||
# region Methods
|
||||
|
||||
def deleter(self, function):
|
||||
return self._copy_extra_attributes(property.deleter(self, function))
|
||||
|
||||
def getter(self, function):
|
||||
return self._copy_extra_attributes(property.getter(self, function))
|
||||
|
||||
def setter(self, function):
|
||||
return self._copy_extra_attributes(property.setter(self, function))
|
||||
|
||||
@classmethod
|
||||
def fix_up(cls, command_class):
|
||||
|
||||
is_option = lambda attribute: isinstance(attribute, Option)
|
||||
definitions = getmembers(command_class, is_option)
|
||||
validate_option_name = OptionName()
|
||||
i = 0
|
||||
|
||||
for name, option in definitions:
|
||||
|
||||
if option.name is None:
|
||||
option.name = name # no validation required
|
||||
else:
|
||||
validate_option_name(option.name)
|
||||
|
||||
if option.fget is None and option.fset is None and option.fdel is None:
|
||||
backing_field_name = '_' + name
|
||||
|
||||
def fget(bfn):
|
||||
return lambda this: getattr(this, bfn, None)
|
||||
|
||||
option = option.getter(fget(backing_field_name))
|
||||
|
||||
def fset(bfn, validate):
|
||||
if validate is None:
|
||||
return lambda this, value: setattr(this, bfn, value)
|
||||
return lambda this, value: setattr(this, bfn, validate(value))
|
||||
|
||||
option = option.setter(fset(backing_field_name, option.validate))
|
||||
setattr(command_class, name, option)
|
||||
|
||||
elif option.validate is not None:
|
||||
|
||||
def fset(function, validate):
|
||||
return lambda this, value: function(this, validate(value))
|
||||
|
||||
option = option.setter(fset(option.fset, option.validate))
|
||||
setattr(command_class, name, option)
|
||||
|
||||
definitions[i] = name, option
|
||||
i += 1
|
||||
|
||||
command_class.option_definitions = definitions
|
||||
|
||||
def _copy_extra_attributes(self, other):
|
||||
other.name = self.name
|
||||
other.default = self.default
|
||||
other.require = self.require
|
||||
other.validate = self.validate
|
||||
return other
|
||||
|
||||
# endregion
|
||||
|
||||
# region Types
|
||||
|
||||
class Item(object):
|
||||
""" Presents an instance/class view over a search command `Option`.
|
||||
|
||||
This class is used by SearchCommand.process to parse and report on option values.
|
||||
|
||||
"""
|
||||
def __init__(self, command, option):
|
||||
self._command = command
|
||||
self._option = option
|
||||
self._is_set = False
|
||||
validator = self.validator
|
||||
self._format = six.text_type if validator is None else validator.format
|
||||
|
||||
def __repr__(self):
|
||||
return '(' + repr(self.name) + ', ' + repr(self._format(self.value)) + ')'
|
||||
|
||||
def __str__(self):
|
||||
value = self.value
|
||||
value = 'None' if value is None else json_encode_string(self._format(value))
|
||||
return self.name + '=' + value
|
||||
|
||||
# region Properties
|
||||
|
||||
@property
|
||||
def is_required(self):
|
||||
return bool(self._option.require)
|
||||
|
||||
@property
|
||||
def is_set(self):
|
||||
""" Indicates whether an option value was provided as argument.
|
||||
|
||||
"""
|
||||
return self._is_set
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._option.name
|
||||
|
||||
@property
|
||||
def validator(self):
|
||||
return self._option.validate
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._option.__get__(self._command)
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self._option.__set__(self._command, value)
|
||||
self._is_set = True
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
def reset(self):
|
||||
self._option.__set__(self._command, self._option.default)
|
||||
self._is_set = False
|
||||
|
||||
pass
|
||||
# endregion
|
||||
|
||||
class View(OrderedDict):
|
||||
""" Presents an ordered dictionary view of the set of :class:`Option` arguments to a search command.
|
||||
|
||||
This class is used by SearchCommand.process to parse and report on option values.
|
||||
|
||||
"""
|
||||
def __init__(self, command):
|
||||
definitions = type(command).option_definitions
|
||||
item_class = Option.Item
|
||||
OrderedDict.__init__(self, ((option.name, item_class(command, option)) for (name, option) in definitions))
|
||||
|
||||
def __repr__(self):
|
||||
text = 'Option.View([' + ','.join(imap(lambda item: repr(item), six.itervalues(self))) + '])'
|
||||
return text
|
||||
|
||||
def __str__(self):
|
||||
text = ' '.join([str(item) for item in six.itervalues(self) if item.is_set])
|
||||
return text
|
||||
|
||||
# region Methods
|
||||
|
||||
def get_missing(self):
|
||||
missing = [item.name for item in six.itervalues(self) if item.is_required and not item.is_set]
|
||||
return missing if len(missing) > 0 else None
|
||||
|
||||
def reset(self):
|
||||
for value in six.itervalues(self):
|
||||
value.reset()
|
||||
|
||||
pass
|
||||
# endregion
|
||||
|
||||
pass
|
||||
# endregion
|
||||
|
||||
|
||||
__all__ = ['Configuration', 'Option']
|
||||
@@ -1,123 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from logging import getLogger, root, StreamHandler
|
||||
from logging.config import fileConfig
|
||||
from os import chdir, environ, path
|
||||
from splunklib.six.moves import getcwd
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def configure_logging(logger_name, filename=None):
|
||||
""" Configure logging and return the named logger and the location of the logging configuration file loaded.
|
||||
|
||||
This function expects a Splunk app directory structure::
|
||||
|
||||
<app-root>
|
||||
bin
|
||||
...
|
||||
default
|
||||
...
|
||||
local
|
||||
...
|
||||
|
||||
This function looks for a logging configuration file at each of these locations, loading the first, if any,
|
||||
logging configuration file that it finds::
|
||||
|
||||
local/{name}.logging.conf
|
||||
default/{name}.logging.conf
|
||||
local/logging.conf
|
||||
default/logging.conf
|
||||
|
||||
The current working directory is set to *<app-root>* before the logging configuration file is loaded. Hence, paths
|
||||
in the logging configuration file are relative to *<app-root>*. The current directory is reset before return.
|
||||
|
||||
You may short circuit the search for a logging configuration file by providing an alternative file location in
|
||||
`path`. Logging configuration files must be in `ConfigParser format`_.
|
||||
|
||||
#Arguments:
|
||||
|
||||
:param logger_name: Logger name
|
||||
:type logger_name: bytes, unicode
|
||||
|
||||
:param filename: Location of an alternative logging configuration file or `None`.
|
||||
:type filename: bytes, unicode or NoneType
|
||||
|
||||
:returns: The named logger and the location of the logging configuration file loaded.
|
||||
:rtype: tuple
|
||||
|
||||
.. _ConfigParser format: https://docs.python.org/2/library/logging.config.html#configuration-file-format
|
||||
|
||||
"""
|
||||
if filename is None:
|
||||
if logger_name is None:
|
||||
probing_paths = [path.join('local', 'logging.conf'), path.join('default', 'logging.conf')]
|
||||
else:
|
||||
probing_paths = [
|
||||
path.join('local', logger_name + '.logging.conf'),
|
||||
path.join('default', logger_name + '.logging.conf'),
|
||||
path.join('local', 'logging.conf'),
|
||||
path.join('default', 'logging.conf')]
|
||||
for relative_path in probing_paths:
|
||||
configuration_file = path.join(app_root, relative_path)
|
||||
if path.exists(configuration_file):
|
||||
filename = configuration_file
|
||||
break
|
||||
elif not path.isabs(filename):
|
||||
found = False
|
||||
for conf in 'local', 'default':
|
||||
configuration_file = path.join(app_root, conf, filename)
|
||||
if path.exists(configuration_file):
|
||||
filename = configuration_file
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
raise ValueError('Logging configuration file "{}" not found in local or default directory'.format(filename))
|
||||
elif not path.exists(filename):
|
||||
raise ValueError('Logging configuration file "{}" not found'.format(filename))
|
||||
|
||||
if filename is not None:
|
||||
global _current_logging_configuration_file
|
||||
filename = path.realpath(filename)
|
||||
|
||||
if filename != _current_logging_configuration_file:
|
||||
working_directory = getcwd()
|
||||
chdir(app_root)
|
||||
try:
|
||||
fileConfig(filename, {'SPLUNK_HOME': splunk_home})
|
||||
finally:
|
||||
chdir(working_directory)
|
||||
_current_logging_configuration_file = filename
|
||||
|
||||
if len(root.handlers) == 0:
|
||||
root.addHandler(StreamHandler())
|
||||
|
||||
return None if logger_name is None else getLogger(logger_name), filename
|
||||
|
||||
|
||||
_current_logging_configuration_file = None
|
||||
|
||||
splunk_home = path.abspath(path.join(getcwd(), environ.get('SPLUNK_HOME', '')))
|
||||
app_file = getattr(sys.modules['__main__'], '__file__', sys.executable)
|
||||
app_root = path.dirname(path.abspath(path.dirname(app_file)))
|
||||
|
||||
splunklib_logger, logging_configuration = configure_logging('splunklib')
|
||||
|
||||
|
||||
__all__ = ['app_file', 'app_root', 'logging_configuration', 'splunk_home', 'splunklib_logger']
|
||||
@@ -1,149 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from splunklib import six
|
||||
from splunklib.six.moves import map as imap
|
||||
|
||||
from .decorators import ConfigurationSetting
|
||||
from .search_command import SearchCommand
|
||||
|
||||
|
||||
class EventingCommand(SearchCommand):
|
||||
""" Applies a transformation to search results as they travel through the events pipeline.
|
||||
|
||||
Eventing commands typically filter, group, order, and/or or augment event records. Examples of eventing commands
|
||||
from Splunk's built-in command set include sort_, dedup_, and cluster_. Each execution of an eventing command
|
||||
should produce a set of event records that is independently usable by downstream processors.
|
||||
|
||||
.. _sort: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Sort
|
||||
.. _dedup: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Dedup
|
||||
.. _cluster: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Cluster
|
||||
|
||||
EventingCommand configuration
|
||||
==============================
|
||||
|
||||
You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
|
||||
Splunk 6.3 or later.
|
||||
|
||||
"""
|
||||
# region Methods
|
||||
|
||||
def transform(self, records):
|
||||
""" Generator function that processes and yields event records to the Splunk events pipeline.
|
||||
|
||||
You must override this method.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('EventingCommand.transform(self, records)')
|
||||
|
||||
def _execute(self, ifile, process):
|
||||
SearchCommand._execute(self, ifile, self.transform)
|
||||
|
||||
# endregion
|
||||
|
||||
class ConfigurationSettings(SearchCommand.ConfigurationSettings):
|
||||
""" Represents the configuration settings that apply to a :class:`EventingCommand`.
|
||||
|
||||
"""
|
||||
# region SCP v1/v2 properties
|
||||
|
||||
required_fields = ConfigurationSetting(doc='''
|
||||
List of required fields for this search which back-propagates to the generating search.
|
||||
|
||||
Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
|
||||
:code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
|
||||
specify a value of :const:`['*']`. No error is generated if a specified field is missing.
|
||||
|
||||
Default: :const:`None`, which implicitly selects all fields.
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v1 properties
|
||||
|
||||
clear_required_fields = ConfigurationSetting(doc='''
|
||||
:const:`True`, if required_fields represent the *only* fields required.
|
||||
|
||||
If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
|
||||
In most cases, :const:`False` is appropriate for eventing commands.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
''')
|
||||
|
||||
retainsevents = ConfigurationSetting(readonly=True, value=True, doc='''
|
||||
:const:`True`, if the command retains events the way the sort/dedup/cluster commands do.
|
||||
|
||||
If :const:`False`, the command transforms events the way the stats command does.
|
||||
|
||||
Fixed: :const:`True`
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v2 properties
|
||||
|
||||
maxinputs = ConfigurationSetting(doc='''
|
||||
Specifies the maximum number of events that can be passed to the command for each invocation.
|
||||
|
||||
This limit cannot exceed the value of `maxresultrows` as defined in limits.conf_. Under SCP 1 you must
|
||||
specify this value in commands.conf_.
|
||||
|
||||
Default: The value of `maxresultrows`.
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
.. _limits.conf: http://docs.splunk.com/Documentation/Splunk/latest/admin/Limitsconf
|
||||
|
||||
''')
|
||||
|
||||
type = ConfigurationSetting(readonly=True, value='events', doc='''
|
||||
Command type
|
||||
|
||||
Fixed: :const:`'events'`.
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
@classmethod
|
||||
def fix_up(cls, command):
|
||||
""" Verifies :code:`command` class structure.
|
||||
|
||||
"""
|
||||
if command.transform == EventingCommand.transform:
|
||||
raise AttributeError('No EventingCommand.transform override')
|
||||
SearchCommand.ConfigurationSettings.fix_up(command)
|
||||
|
||||
# TODO: Stop looking like a dictionary because we don't obey the semantics
|
||||
# N.B.: Does not use Python 2 dict copy semantics
|
||||
def iteritems(self):
|
||||
iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
|
||||
return imap(lambda name_value: (name_value[0], 'events' if name_value[0] == 'type' else name_value[1]), iteritems)
|
||||
|
||||
# N.B.: Does not use Python 3 dict view semantics
|
||||
if not six.PY2:
|
||||
items = iteritems
|
||||
|
||||
# endregion
|
||||
@@ -1,228 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from logging import getLogger
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
from splunklib import six
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from signal import signal, CTRL_BREAK_EVENT, SIGBREAK, SIGINT, SIGTERM
|
||||
from subprocess import Popen
|
||||
import atexit
|
||||
|
||||
from . import splunklib_logger as logger
|
||||
|
||||
# P1 [ ] TODO: Add ExternalSearchCommand class documentation
|
||||
|
||||
|
||||
class ExternalSearchCommand(object):
|
||||
"""
|
||||
"""
|
||||
def __init__(self, path, argv=None, environ=None):
|
||||
|
||||
if not isinstance(path, (bytes, six.text_type)):
|
||||
raise ValueError('Expected a string value for path, not {}'.format(repr(path)))
|
||||
|
||||
self._logger = getLogger(self.__class__.__name__)
|
||||
self._path = six.text_type(path)
|
||||
self._argv = None
|
||||
self._environ = None
|
||||
|
||||
self.argv = argv
|
||||
self.environ = environ
|
||||
|
||||
# region Properties
|
||||
|
||||
@property
|
||||
def argv(self):
|
||||
return getattr(self, '_argv')
|
||||
|
||||
@argv.setter
|
||||
def argv(self, value):
|
||||
if not (value is None or isinstance(value, (list, tuple))):
|
||||
raise ValueError('Expected a list, tuple or value of None for argv, not {}'.format(repr(value)))
|
||||
self._argv = value
|
||||
|
||||
@property
|
||||
def environ(self):
|
||||
return getattr(self, '_environ')
|
||||
|
||||
@environ.setter
|
||||
def environ(self, value):
|
||||
if not (value is None or isinstance(value, dict)):
|
||||
raise ValueError('Expected a dictionary value for environ, not {}'.format(repr(value)))
|
||||
self._environ = value
|
||||
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
def execute(self):
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
if self._argv is None:
|
||||
self._argv = os.path.splitext(os.path.basename(self._path))[0]
|
||||
self._execute(self._path, self._argv, self._environ)
|
||||
except:
|
||||
error_type, error, tb = sys.exc_info()
|
||||
message = 'Command execution failed: ' + six.text_type(error)
|
||||
self._logger.error(message + '\nTraceback:\n' + ''.join(traceback.format_tb(tb)))
|
||||
sys.exit(1)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
|
||||
@staticmethod
|
||||
def _execute(path, argv=None, environ=None):
|
||||
""" Executes an external search command.
|
||||
|
||||
:param path: Path to the external search command.
|
||||
:type path: unicode
|
||||
|
||||
:param argv: Argument list.
|
||||
:type argv: list or tuple
|
||||
The arguments to the child process should start with the name of the command being run, but this is not
|
||||
enforced. A value of :const:`None` specifies that the base name of path name :param:`path` should be used.
|
||||
|
||||
:param environ: A mapping which is used to define the environment variables for the new process.
|
||||
:type environ: dict or None.
|
||||
This mapping is used instead of the current process’s environment. A value of :const:`None` specifies that
|
||||
the :data:`os.environ` mapping should be used.
|
||||
|
||||
:return: None
|
||||
|
||||
"""
|
||||
search_path = os.getenv('PATH') if environ is None else environ.get('PATH')
|
||||
found = ExternalSearchCommand._search_path(path, search_path)
|
||||
|
||||
if found is None:
|
||||
raise ValueError('Cannot find command on path: {}'.format(path))
|
||||
|
||||
path = found
|
||||
logger.debug('starting command="%s", arguments=%s', path, argv)
|
||||
|
||||
def terminate(signal_number, frame):
|
||||
sys.exit('External search command is terminating on receipt of signal={}.'.format(signal_number))
|
||||
|
||||
def terminate_child():
|
||||
if p.pid is not None and p.returncode is None:
|
||||
logger.debug('terminating command="%s", arguments=%d, pid=%d', path, argv, p.pid)
|
||||
os.kill(p.pid, CTRL_BREAK_EVENT)
|
||||
|
||||
p = Popen(argv, executable=path, env=environ, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
|
||||
atexit.register(terminate_child)
|
||||
signal(SIGBREAK, terminate)
|
||||
signal(SIGINT, terminate)
|
||||
signal(SIGTERM, terminate)
|
||||
|
||||
logger.debug('started command="%s", arguments=%s, pid=%d', path, argv, p.pid)
|
||||
p.wait()
|
||||
|
||||
logger.debug('finished command="%s", arguments=%s, pid=%d, returncode=%d', path, argv, p.pid, p.returncode)
|
||||
|
||||
if p.returncode != 0:
|
||||
sys.exit(p.returncode)
|
||||
|
||||
@staticmethod
|
||||
def _search_path(executable, paths):
|
||||
""" Locates an executable program file.
|
||||
|
||||
:param executable: The name of the executable program to locate.
|
||||
:type executable: unicode
|
||||
|
||||
:param paths: A list of one or more directory paths where executable programs are located.
|
||||
:type paths: unicode
|
||||
|
||||
:return:
|
||||
:rtype: Path to the executable program located or :const:`None`.
|
||||
|
||||
"""
|
||||
directory, filename = os.path.split(executable)
|
||||
extension = os.path.splitext(filename)[1].upper()
|
||||
executable_extensions = ExternalSearchCommand._executable_extensions
|
||||
|
||||
if directory:
|
||||
if len(extension) and extension in executable_extensions:
|
||||
return None
|
||||
for extension in executable_extensions:
|
||||
path = executable + extension
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
if not paths:
|
||||
return None
|
||||
|
||||
directories = [directory for directory in paths.split(';') if len(directory)]
|
||||
|
||||
if len(directories) == 0:
|
||||
return None
|
||||
|
||||
if len(extension) and extension in executable_extensions:
|
||||
for directory in directories:
|
||||
path = os.path.join(directory, executable)
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
return None
|
||||
|
||||
for directory in directories:
|
||||
path_without_extension = os.path.join(directory, executable)
|
||||
for extension in executable_extensions:
|
||||
path = path_without_extension + extension
|
||||
if os.path.isfile(path):
|
||||
return path
|
||||
|
||||
return None
|
||||
|
||||
_executable_extensions = ('.COM', '.EXE')
|
||||
else:
|
||||
@staticmethod
|
||||
def _execute(path, argv, environ):
|
||||
if environ is None:
|
||||
os.execvp(path, argv)
|
||||
else:
|
||||
os.execvpe(path, argv, environ)
|
||||
return
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
def execute(path, argv=None, environ=None, command_class=ExternalSearchCommand):
|
||||
"""
|
||||
:param path:
|
||||
:type path: basestring
|
||||
:param argv:
|
||||
:type: argv: list, tuple, or None
|
||||
:param environ:
|
||||
:type environ: dict
|
||||
:param command_class: External search command class to instantiate and execute.
|
||||
:type command_class: type
|
||||
:return:
|
||||
:rtype: None
|
||||
"""
|
||||
assert issubclass(command_class, ExternalSearchCommand)
|
||||
command_class(path, argv, environ).execute()
|
||||
@@ -1,350 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from .decorators import ConfigurationSetting
|
||||
from .search_command import SearchCommand
|
||||
|
||||
from splunklib import six
|
||||
from splunklib.six.moves import map as imap, filter as ifilter
|
||||
|
||||
# P1 [O] TODO: Discuss generates_timeorder in the class-level documentation for GeneratingCommand
|
||||
|
||||
|
||||
class GeneratingCommand(SearchCommand):
|
||||
""" Generates events based on command arguments.
|
||||
|
||||
Generating commands receive no input and must be the first command on a pipeline. There are three pipelines:
|
||||
streams, events, and reports. The streams pipeline generates or processes time-ordered event records on an
|
||||
indexer or search head.
|
||||
|
||||
Streaming commands filter, modify, or augment event records and can be applied to subsets of index data in a
|
||||
parallel manner. An example of a streaming command from Splunk's built-in command set is rex_ which extracts and
|
||||
adds fields to event records at search time. Records that pass through the streams pipeline move on to the events
|
||||
pipeline.
|
||||
|
||||
The events pipeline generates or processes records on a search head. Eventing commands typically filter, group,
|
||||
order, or augment event records. Examples of eventing commands from Splunk's built-in command set include sort_,
|
||||
dedup_, and cluster_. Each execution of an eventing command should produce a set of event records that is
|
||||
independently usable by downstream processors. Records that pass through the events pipeline move on to the reports
|
||||
pipeline.
|
||||
|
||||
The reports pipeline also runs on a search head, but yields data structures for presentation, not event records.
|
||||
Examples of streaming from Splunk's built-in command set include chart_, stats_, and contingency_.
|
||||
|
||||
GeneratingCommand configuration
|
||||
===============================
|
||||
|
||||
Configure your generating command based on the pipeline that it targets. How you configure your command depends on
|
||||
the Search Command Protocol (SCP) version.
|
||||
|
||||
+----------+-------------------------------------+--------------------------------------------+
|
||||
| Pipeline | SCP 1 | SCP 2 |
|
||||
+==========+=====================================+============================================+
|
||||
| streams | streaming=True[,local=[True|False]] | type='streaming'[,distributed=[true|false] |
|
||||
+----------+-------------------------------------+--------------------------------------------+
|
||||
| events | retainsevents=True, streaming=False | type='events' |
|
||||
+----------+-------------------------------------+--------------------------------------------+
|
||||
| reports | streaming=False | type='reporting' |
|
||||
+----------+-------------------------------------+--------------------------------------------+
|
||||
|
||||
Only streaming commands may be distributed to indexers. By default generating commands are configured to run
|
||||
locally in the streams pipeline and will run under either SCP 1 or SCP 2.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@Configuration()
|
||||
class StreamingGeneratingCommand(GeneratingCommand)
|
||||
...
|
||||
|
||||
How you configure your command to run on a different pipeline or in a distributed fashion depends on what SCP
|
||||
protocol versions you wish to support. You must be sure to configure your command consistently for each protocol,
|
||||
if you wish to support both protocol versions correctly.
|
||||
|
||||
.. _chart: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Chart
|
||||
.. _cluster: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Cluster
|
||||
.. _contingency: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Contingency
|
||||
.. _dedup: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Dedup
|
||||
.. _rex: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Rex
|
||||
.. _sort: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Sort
|
||||
.. _stats: http://docs.splunk.com/Documentation/Splunk/latest/SearchReference/Stats
|
||||
|
||||
Distributed Generating command
|
||||
==============================
|
||||
|
||||
Commands configured like this will run as the first command on search heads and/or indexers on the streams pipeline.
|
||||
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
| Pipeline | SCP 1 | SCP 2 |
|
||||
+==========+===================================================+===================================================+
|
||||
| streams | 1. Add this line to your command's stanza in | 1. Add this configuration setting to your code: |
|
||||
| | | |
|
||||
| | default/commands.conf:: | .. code-block:: python |
|
||||
| | | |
|
||||
| | local = false | @Configuration(distributed=True) |
|
||||
| | | class SomeCommand(GeneratingCommand) |
|
||||
| | | ... |
|
||||
| | 2. Restart splunk | |
|
||||
| | | 2. You are good to go; no need to restart Splunk |
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
|
||||
Eventing Generating command
|
||||
===========================
|
||||
|
||||
Generating commands configured like this will run as the first command on a search head on the events pipeline.
|
||||
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
| Pipeline | SCP 1 | SCP 2 |
|
||||
+==========+===================================================+===================================================+
|
||||
| events | You have a choice. Add these configuration | Add this configuration setting to your command |
|
||||
| | settings to your command class: | setting to your command class: |
|
||||
| | | |
|
||||
| | .. code-block:: python | .. code-block:: python |
|
||||
| | | |
|
||||
| | @Configuration( | @Configuration(type='events') |
|
||||
| | retainsevents=True, streaming=False) | class SomeCommand(GeneratingCommand) |
|
||||
| | class SomeCommand(GeneratingCommand) | ... |
|
||||
| | ... | |
|
||||
| | | |
|
||||
| | Or add these lines to default/commands.conf: | |
|
||||
| | | |
|
||||
| | .. code-block:: text | |
|
||||
| | | |
|
||||
| | retainsevents = true | |
|
||||
| | streaming = false | |
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
|
||||
Configure your command class like this, if you wish to support both protocols:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@Configuration(type='events', retainsevents=True, streaming=False)
|
||||
class SomeCommand(GeneratingCommand)
|
||||
...
|
||||
|
||||
You might also consider adding these lines to commands.conf instead of adding them to your command class:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
retainsevents = false
|
||||
streaming = false
|
||||
|
||||
Reporting Generating command
|
||||
============================
|
||||
|
||||
Commands configured like this will run as the first command on a search head on the reports pipeline.
|
||||
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
| Pipeline | SCP 1 | SCP 2 |
|
||||
+==========+===================================================+===================================================+
|
||||
| events | You have a choice. Add these configuration | Add this configuration setting to your command |
|
||||
| | settings to your command class: | setting to your command class: |
|
||||
| | | |
|
||||
| | .. code-block:: python | .. code-block:: python |
|
||||
| | | |
|
||||
| | @Configuration(retainsevents=False) | @Configuration(type='reporting') |
|
||||
| | class SomeCommand(GeneratingCommand) | class SomeCommand(GeneratingCommand) |
|
||||
| | ... | ... |
|
||||
| | | |
|
||||
| | Or add this lines to default/commands.conf: | |
|
||||
| | | |
|
||||
| | .. code-block:: text | |
|
||||
| | | |
|
||||
| | retainsevents = false | |
|
||||
| | streaming = false | |
|
||||
+----------+---------------------------------------------------+---------------------------------------------------+
|
||||
|
||||
Configure your command class like this, if you wish to support both protocols:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@Configuration(type='reporting', streaming=False)
|
||||
class SomeCommand(GeneratingCommand)
|
||||
...
|
||||
|
||||
You might also consider adding these lines to commands.conf instead of adding them to your command class:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
retainsevents = false
|
||||
streaming = false
|
||||
|
||||
"""
|
||||
# region Methods
|
||||
|
||||
def generate(self):
|
||||
""" A generator that yields records to the Splunk processing pipeline
|
||||
|
||||
You must override this method.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('GeneratingCommand.generate(self)')
|
||||
|
||||
def _execute(self, ifile, process):
|
||||
""" Execution loop
|
||||
|
||||
:param ifile: Input file object. Unused.
|
||||
:type ifile: file
|
||||
|
||||
:return: `None`.
|
||||
|
||||
"""
|
||||
if self._protocol_version == 2:
|
||||
self._execute_v2(ifile, self.generate())
|
||||
else:
|
||||
assert self._protocol_version == 1
|
||||
self._record_writer.write_records(self.generate())
|
||||
self.finish()
|
||||
|
||||
def _execute_chunk_v2(self, process, chunk):
|
||||
count = 0
|
||||
for row in process:
|
||||
self._record_writer.write_record(row)
|
||||
count += 1
|
||||
if count == self._record_writer._maxresultrows:
|
||||
self._finished = False
|
||||
return
|
||||
self._finished = True
|
||||
|
||||
# endregion
|
||||
|
||||
# region Types
|
||||
|
||||
class ConfigurationSettings(SearchCommand.ConfigurationSettings):
|
||||
""" Represents the configuration settings for a :code:`GeneratingCommand` class.
|
||||
|
||||
"""
|
||||
# region SCP v1/v2 Properties
|
||||
|
||||
generating = ConfigurationSetting(readonly=True, value=True, doc='''
|
||||
Tells Splunk that this command generates events, but does not process inputs.
|
||||
|
||||
Generating commands must appear at the front of the search pipeline identified by :meth:`type`.
|
||||
|
||||
Fixed: :const:`True`
|
||||
|
||||
Supported by: SCP 1, SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v1 Properties
|
||||
|
||||
generates_timeorder = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command generates new events.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
local = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command should run locally on the search head.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
retainsevents = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command retains events the way the sort, dedup, and cluster commands do, or whether it
|
||||
transforms them the way the stats command does.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
streaming = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command is streamable.
|
||||
|
||||
Default: :const:`True`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v2 Properties
|
||||
|
||||
distributed = ConfigurationSetting(value=False, doc='''
|
||||
True, if this command should be distributed to indexers.
|
||||
|
||||
This value is ignored unless :meth:`type` is equal to :const:`streaming`. It is only this command type that
|
||||
may be distributed.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
type = ConfigurationSetting(value='streaming', doc='''
|
||||
A command type name.
|
||||
|
||||
==================== ======================================================================================
|
||||
Value Description
|
||||
-------------------- --------------------------------------------------------------------------------------
|
||||
:const:`'events'` Runs as the first command in the Splunk events pipeline. Cannot be distributed.
|
||||
:const:`'reporting'` Runs as the first command in the Splunk reports pipeline. Cannot be distributed.
|
||||
:const:`'streaming'` Runs as the first command in the Splunk streams pipeline. May be distributed.
|
||||
==================== ======================================================================================
|
||||
|
||||
Default: :const:`'streaming'`
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
@classmethod
|
||||
def fix_up(cls, command):
|
||||
""" Verifies :code:`command` class structure.
|
||||
|
||||
"""
|
||||
if command.generate == GeneratingCommand.generate:
|
||||
raise AttributeError('No GeneratingCommand.generate override')
|
||||
|
||||
# TODO: Stop looking like a dictionary because we don't obey the semantics
|
||||
# N.B.: Does not use Python 2 dict copy semantics
|
||||
def iteritems(self):
|
||||
iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
|
||||
version = self.command.protocol_version
|
||||
if version == 2:
|
||||
iteritems = ifilter(lambda name_value1: name_value1[0] != 'distributed', iteritems)
|
||||
if not self.distributed and self.type == 'streaming':
|
||||
iteritems = imap(
|
||||
lambda name_value: (name_value[0], 'stateful') if name_value[0] == 'type' else (name_value[0], name_value[1]), iteritems)
|
||||
return iteritems
|
||||
|
||||
# N.B.: Does not use Python 3 dict view semantics
|
||||
if not six.PY2:
|
||||
items = iteritems
|
||||
|
||||
pass
|
||||
# endregion
|
||||
|
||||
pass
|
||||
# endregion
|
||||
@@ -1,844 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from io import TextIOWrapper
|
||||
from collections import deque, namedtuple
|
||||
from splunklib import six
|
||||
try:
|
||||
from collections import OrderedDict # must be python 2.7
|
||||
except ImportError:
|
||||
from ..ordereddict import OrderedDict
|
||||
from splunklib.six.moves import StringIO
|
||||
from itertools import chain
|
||||
from splunklib.six.moves import map as imap
|
||||
from json import JSONDecoder, JSONEncoder
|
||||
from json.encoder import encode_basestring_ascii as json_encode_string
|
||||
from splunklib.six.moves import urllib
|
||||
|
||||
import csv
|
||||
import gzip
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from . import environment
|
||||
|
||||
csv.field_size_limit(10485760) # The default value is 128KB; upping to 10MB. See SPL-12117 for background on this issue
|
||||
|
||||
|
||||
def set_binary_mode(fh):
|
||||
""" Helper method to set up binary mode for file handles.
|
||||
Emphasis being sys.stdin, sys.stdout, sys.stderr.
|
||||
For python3, we want to return .buffer
|
||||
For python2+windows we want to set os.O_BINARY
|
||||
"""
|
||||
typefile = TextIOWrapper if sys.version_info >= (3, 0) else file
|
||||
# check for file handle
|
||||
if not isinstance(fh, typefile):
|
||||
return fh
|
||||
|
||||
# check for python3 and buffer
|
||||
if sys.version_info >= (3, 0) and hasattr(fh, 'buffer'):
|
||||
return fh.buffer
|
||||
# check for python3
|
||||
elif sys.version_info >= (3, 0):
|
||||
pass
|
||||
# check for windows python2. SPL-175233 -- python3 stdout is already binary
|
||||
elif sys.platform == 'win32':
|
||||
# Work around the fact that on Windows '\n' is mapped to '\r\n'. The typical solution is to simply open files in
|
||||
# binary mode, but stdout is already open, thus this hack. 'CPython' and 'PyPy' work differently. We assume that
|
||||
# all other Python implementations are compatible with 'CPython'. This might or might not be a valid assumption.
|
||||
from platform import python_implementation
|
||||
implementation = python_implementation()
|
||||
if implementation == 'PyPy':
|
||||
return os.fdopen(fh.fileno(), 'wb', 0)
|
||||
else:
|
||||
import msvcrt
|
||||
msvcrt.setmode(fh.fileno(), os.O_BINARY)
|
||||
return fh
|
||||
|
||||
|
||||
class CommandLineParser(object):
|
||||
r""" Parses the arguments to a search command.
|
||||
|
||||
A search command line is described by the following syntax.
|
||||
|
||||
**Syntax**::
|
||||
|
||||
command = command-name *[wsp option] *[wsp [dquote] field-name [dquote]]
|
||||
command-name = alpha *( alpha / digit )
|
||||
option = option-name [wsp] "=" [wsp] option-value
|
||||
option-name = alpha *( alpha / digit / "_" )
|
||||
option-value = word / quoted-string
|
||||
word = 1*( %01-%08 / %0B / %0C / %0E-1F / %21 / %23-%FF ) ; Any character but DQUOTE and WSP
|
||||
quoted-string = dquote *( word / wsp / "\" dquote / dquote dquote ) dquote
|
||||
field-name = ( "_" / alpha ) *( alpha / digit / "_" / "." / "-" )
|
||||
|
||||
**Note:**
|
||||
|
||||
This syntax is constrained to an 8-bit character set.
|
||||
|
||||
**Note:**
|
||||
|
||||
This syntax does not show that `field-name` values may be comma-separated when in fact they can be. This is
|
||||
because Splunk strips commas from the command line. A custom search command will never see them.
|
||||
|
||||
**Example:**
|
||||
|
||||
countmatches fieldname = word_count pattern = \w+ some_text_field
|
||||
|
||||
Option names are mapped to properties in the targeted ``SearchCommand``. It is the responsibility of the property
|
||||
setters to validate the values they receive. Property setters may also produce side effects. For example,
|
||||
setting the built-in `log_level` immediately changes the `log_level`.
|
||||
|
||||
"""
|
||||
@classmethod
|
||||
def parse(cls, command, argv):
|
||||
""" Splits an argument list into an options dictionary and a fieldname
|
||||
list.
|
||||
|
||||
The argument list, `argv`, must be of the form::
|
||||
|
||||
*[option]... *[<field-name>]
|
||||
|
||||
Options are validated and assigned to items in `command.options`. Field names are validated and stored in the
|
||||
list of `command.fieldnames`.
|
||||
|
||||
#Arguments:
|
||||
|
||||
:param command: Search command instance.
|
||||
:type command: ``SearchCommand``
|
||||
:param argv: List of search command arguments.
|
||||
:type argv: ``list``
|
||||
:return: ``None``
|
||||
|
||||
#Exceptions:
|
||||
|
||||
``SyntaxError``: Argument list is incorrectly formed.
|
||||
``ValueError``: Unrecognized option/field name, or an illegal field value.
|
||||
|
||||
"""
|
||||
debug = environment.splunklib_logger.debug
|
||||
command_class = type(command).__name__
|
||||
|
||||
# Prepare
|
||||
|
||||
debug('Parsing %s command line: %r', command_class, argv)
|
||||
command.fieldnames = None
|
||||
command.options.reset()
|
||||
argv = ' '.join(argv)
|
||||
|
||||
command_args = cls._arguments_re.match(argv)
|
||||
|
||||
if command_args is None:
|
||||
raise SyntaxError('Syntax error: {}'.format(argv))
|
||||
|
||||
# Parse options
|
||||
|
||||
for option in cls._options_re.finditer(command_args.group('options')):
|
||||
name, value = option.group('name'), option.group('value')
|
||||
if name not in command.options:
|
||||
raise ValueError(
|
||||
'Unrecognized {} command option: {}={}'.format(command.name, name, json_encode_string(value)))
|
||||
command.options[name].value = cls.unquote(value)
|
||||
|
||||
missing = command.options.get_missing()
|
||||
|
||||
if missing is not None:
|
||||
if len(missing) > 1:
|
||||
raise ValueError(
|
||||
'Values for these {} command options are required: {}'.format(command.name, ', '.join(missing)))
|
||||
raise ValueError('A value for {} command option {} is required'.format(command.name, missing[0]))
|
||||
|
||||
# Parse field names
|
||||
|
||||
fieldnames = command_args.group('fieldnames')
|
||||
|
||||
if fieldnames is None:
|
||||
command.fieldnames = []
|
||||
else:
|
||||
command.fieldnames = [cls.unquote(value.group(0)) for value in cls._fieldnames_re.finditer(fieldnames)]
|
||||
|
||||
debug(' %s: %s', command_class, command)
|
||||
|
||||
@classmethod
|
||||
def unquote(cls, string):
|
||||
""" Removes quotes from a quoted string.
|
||||
|
||||
Splunk search command quote rules are applied. The enclosing double-quotes, if present, are removed. Escaped
|
||||
double-quotes ('\"' or '""') are replaced by a single double-quote ('"').
|
||||
|
||||
**NOTE**
|
||||
|
||||
We are not using a json.JSONDecoder because Splunk quote rules are different than JSON quote rules. A
|
||||
json.JSONDecoder does not recognize a pair of double-quotes ('""') as an escaped quote ('"') and will
|
||||
decode single-quoted strings ("'") in addition to double-quoted ('"') strings.
|
||||
|
||||
"""
|
||||
if len(string) == 0:
|
||||
return ''
|
||||
|
||||
if string[0] == '"':
|
||||
if len(string) == 1 or string[-1] != '"':
|
||||
raise SyntaxError('Poorly formed string literal: ' + string)
|
||||
string = string[1:-1]
|
||||
|
||||
if len(string) == 0:
|
||||
return ''
|
||||
|
||||
def replace(match):
|
||||
value = match.group(0)
|
||||
if value == '""':
|
||||
return '"'
|
||||
if len(value) < 2:
|
||||
raise SyntaxError('Poorly formed string literal: ' + string)
|
||||
return value[1]
|
||||
|
||||
result = re.sub(cls._escaped_character_re, replace, string)
|
||||
return result
|
||||
|
||||
# region Class variables
|
||||
|
||||
_arguments_re = re.compile(r"""
|
||||
^\s*
|
||||
(?P<options> # Match a leading set of name/value pairs
|
||||
(?:
|
||||
(?:(?=\w)[^\d]\w*) # name
|
||||
\s*=\s* # =
|
||||
(?:"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+)\s* # value
|
||||
)*
|
||||
)\s*
|
||||
(?P<fieldnames> # Match a trailing set of field names
|
||||
(?:
|
||||
(?:"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+)\s*
|
||||
)*
|
||||
)\s*$
|
||||
""", re.VERBOSE | re.UNICODE)
|
||||
|
||||
_escaped_character_re = re.compile(r'(\\.|""|[\\"])')
|
||||
|
||||
_fieldnames_re = re.compile(r"""("(?:\\.|""|[^"\\])+"|(?:\\.|[^\s"])+)""")
|
||||
|
||||
_options_re = re.compile(r"""
|
||||
# Captures a set of name/value pairs when used with re.finditer
|
||||
(?P<name>(?:(?=\w)[^\d]\w*)) # name
|
||||
\s*=\s* # =
|
||||
(?P<value>"(?:\\.|""|[^"])*"|(?:\\.|[^\s"])+) # value
|
||||
""", re.VERBOSE | re.UNICODE)
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
class ConfigurationSettingsType(type):
|
||||
""" Metaclass for constructing ConfigurationSettings classes.
|
||||
|
||||
Instances of :class:`ConfigurationSettingsType` construct :class:`ConfigurationSettings` classes from classes from
|
||||
a base :class:`ConfigurationSettings` class and a dictionary of configuration settings. The settings in the
|
||||
dictionary are validated against the settings in the base class. You cannot add settings, you can only change their
|
||||
backing-field values and you cannot modify settings without backing-field values. These are considered fixed
|
||||
configuration setting values.
|
||||
|
||||
This is an internal class used in two places:
|
||||
|
||||
+ :meth:`decorators.Configuration.__call__`
|
||||
|
||||
Adds a ConfigurationSettings attribute to a :class:`SearchCommand` class.
|
||||
|
||||
+ :meth:`reporting_command.ReportingCommand.fix_up`
|
||||
|
||||
Adds a ConfigurationSettings attribute to a :meth:`ReportingCommand.map` method, if there is one.
|
||||
|
||||
"""
|
||||
def __new__(mcs, module, name, bases):
|
||||
mcs = super(ConfigurationSettingsType, mcs).__new__(mcs, str(name), bases, {})
|
||||
return mcs
|
||||
|
||||
def __init__(cls, module, name, bases):
|
||||
|
||||
super(ConfigurationSettingsType, cls).__init__(name, bases, None)
|
||||
cls.__module__ = module
|
||||
|
||||
@staticmethod
|
||||
def validate_configuration_setting(specification, name, value):
|
||||
if not isinstance(value, specification.type):
|
||||
if isinstance(specification.type, type):
|
||||
type_names = specification.type.__name__
|
||||
else:
|
||||
type_names = ', '.join(imap(lambda t: t.__name__, specification.type))
|
||||
raise ValueError('Expected {} value, not {}={}'.format(type_names, name, repr(value)))
|
||||
if specification.constraint and not specification.constraint(value):
|
||||
raise ValueError('Illegal value: {}={}'.format(name, repr(value)))
|
||||
return value
|
||||
|
||||
specification = namedtuple(
|
||||
'ConfigurationSettingSpecification', (
|
||||
'type',
|
||||
'constraint',
|
||||
'supporting_protocols'))
|
||||
|
||||
# P1 [ ] TODO: Review ConfigurationSettingsType.specification_matrix for completeness and correctness
|
||||
|
||||
specification_matrix = {
|
||||
'clear_required_fields': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'distributed': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[2]),
|
||||
'generates_timeorder': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'generating': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1, 2]),
|
||||
'local': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'maxinputs': specification(
|
||||
type=int,
|
||||
constraint=lambda value: 0 <= value <= six.MAXSIZE,
|
||||
supporting_protocols=[2]),
|
||||
'overrides_timeorder': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'required_fields': specification(
|
||||
type=(list, set, tuple),
|
||||
constraint=None,
|
||||
supporting_protocols=[1, 2]),
|
||||
'requires_preop': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'retainsevents': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'run_in_preview': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[2]),
|
||||
'streaming': specification(
|
||||
type=bool,
|
||||
constraint=None,
|
||||
supporting_protocols=[1]),
|
||||
'streaming_preop': specification(
|
||||
type=(bytes, six.text_type),
|
||||
constraint=None,
|
||||
supporting_protocols=[1, 2]),
|
||||
'type': specification(
|
||||
type=(bytes, six.text_type),
|
||||
constraint=lambda value: value in ('events', 'reporting', 'streaming'),
|
||||
supporting_protocols=[2])}
|
||||
|
||||
|
||||
class CsvDialect(csv.Dialect):
|
||||
""" Describes the properties of Splunk CSV streams """
|
||||
delimiter = ','
|
||||
quotechar = '"'
|
||||
doublequote = True
|
||||
skipinitialspace = False
|
||||
lineterminator = '\r\n'
|
||||
if sys.version_info >= (3, 0) and sys.platform == 'win32':
|
||||
lineterminator = '\n'
|
||||
quoting = csv.QUOTE_MINIMAL
|
||||
|
||||
|
||||
class InputHeader(dict):
|
||||
""" Represents a Splunk input header as a collection of name/value pairs.
|
||||
|
||||
"""
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join([name + ':' + value for name, value in six.iteritems(self)])
|
||||
|
||||
def read(self, ifile):
|
||||
""" Reads an input header from an input file.
|
||||
|
||||
The input header is read as a sequence of *<name>***:***<value>* pairs separated by a newline. The end of the
|
||||
input header is signalled by an empty line or an end-of-file.
|
||||
|
||||
:param ifile: File-like object that supports iteration over lines.
|
||||
|
||||
"""
|
||||
name, value = None, None
|
||||
|
||||
for line in ifile:
|
||||
if line == '\n':
|
||||
break
|
||||
item = line.split(':', 1)
|
||||
if len(item) == 2:
|
||||
# start of a new item
|
||||
if name is not None:
|
||||
self[name] = value[:-1] # value sans trailing newline
|
||||
name, value = item[0], urllib.parse.unquote(item[1])
|
||||
elif name is not None:
|
||||
# continuation of the current item
|
||||
value += urllib.parse.unquote(line)
|
||||
|
||||
if name is not None:
|
||||
self[name] = value[:-1] if value[-1] == '\n' else value
|
||||
|
||||
|
||||
Message = namedtuple('Message', ('type', 'text'))
|
||||
|
||||
|
||||
class MetadataDecoder(JSONDecoder):
|
||||
|
||||
def __init__(self):
|
||||
JSONDecoder.__init__(self, object_hook=self._object_hook)
|
||||
|
||||
@staticmethod
|
||||
def _object_hook(dictionary):
|
||||
|
||||
object_view = ObjectView(dictionary)
|
||||
stack = deque()
|
||||
stack.append((None, None, dictionary))
|
||||
|
||||
while len(stack):
|
||||
instance, member_name, dictionary = stack.popleft()
|
||||
|
||||
for name, value in six.iteritems(dictionary):
|
||||
if isinstance(value, dict):
|
||||
stack.append((dictionary, name, value))
|
||||
|
||||
if instance is not None:
|
||||
instance[member_name] = ObjectView(dictionary)
|
||||
|
||||
return object_view
|
||||
|
||||
|
||||
class MetadataEncoder(JSONEncoder):
|
||||
|
||||
def __init__(self):
|
||||
JSONEncoder.__init__(self, separators=MetadataEncoder._separators)
|
||||
|
||||
def default(self, o):
|
||||
return o.__dict__ if isinstance(o, ObjectView) else JSONEncoder.default(self, o)
|
||||
|
||||
_separators = (',', ':')
|
||||
|
||||
|
||||
class ObjectView(object):
|
||||
|
||||
def __init__(self, dictionary):
|
||||
self.__dict__ = dictionary
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.__dict__)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__dict__)
|
||||
|
||||
|
||||
class Recorder(object):
|
||||
|
||||
def __init__(self, path, f):
|
||||
self._recording = gzip.open(path + '.gz', 'wb')
|
||||
self._file = f
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._file, name)
|
||||
|
||||
def __iter__(self):
|
||||
for line in self._file:
|
||||
self._recording.write(line)
|
||||
self._recording.flush()
|
||||
yield line
|
||||
|
||||
def read(self, size=None):
|
||||
value = self._file.read() if size is None else self._file.read(size)
|
||||
self._recording.write(value)
|
||||
self._recording.flush()
|
||||
return value
|
||||
|
||||
def readline(self, size=None):
|
||||
value = self._file.readline() if size is None else self._file.readline(size)
|
||||
if len(value) > 0:
|
||||
self._recording.write(value)
|
||||
self._recording.flush()
|
||||
return value
|
||||
|
||||
def record(self, *args):
|
||||
for arg in args:
|
||||
self._recording.write(arg)
|
||||
|
||||
def write(self, text):
|
||||
self._recording.write(text)
|
||||
self._file.write(text)
|
||||
self._recording.flush()
|
||||
|
||||
|
||||
class RecordWriter(object):
|
||||
|
||||
def __init__(self, ofile, maxresultrows=None):
|
||||
self._maxresultrows = 50000 if maxresultrows is None else maxresultrows
|
||||
|
||||
self._ofile = set_binary_mode(ofile)
|
||||
self._fieldnames = None
|
||||
self._buffer = StringIO()
|
||||
|
||||
self._writer = csv.writer(self._buffer, dialect=CsvDialect)
|
||||
self._writerow = self._writer.writerow
|
||||
self._finished = False
|
||||
self._flushed = False
|
||||
|
||||
self._inspector = OrderedDict()
|
||||
self._chunk_count = 0
|
||||
self._pending_record_count = 0
|
||||
self._committed_record_count = 0
|
||||
|
||||
@property
|
||||
def is_flushed(self):
|
||||
return self._flushed
|
||||
|
||||
@is_flushed.setter
|
||||
def is_flushed(self, value):
|
||||
self._flushed = True if value else False
|
||||
|
||||
@property
|
||||
def ofile(self):
|
||||
return self._ofile
|
||||
|
||||
@ofile.setter
|
||||
def ofile(self, value):
|
||||
self._ofile = set_binary_mode(value)
|
||||
|
||||
@property
|
||||
def pending_record_count(self):
|
||||
return self._pending_record_count
|
||||
|
||||
@property
|
||||
def _record_count(self):
|
||||
warnings.warn(
|
||||
"_record_count will be deprecated soon. Use pending_record_count instead.",
|
||||
PendingDeprecationWarning
|
||||
)
|
||||
return self.pending_record_count
|
||||
|
||||
@property
|
||||
def committed_record_count(self):
|
||||
return self._committed_record_count
|
||||
|
||||
@property
|
||||
def _total_record_count(self):
|
||||
warnings.warn(
|
||||
"_total_record_count will be deprecated soon. Use committed_record_count instead.",
|
||||
PendingDeprecationWarning
|
||||
)
|
||||
return self.committed_record_count
|
||||
|
||||
def write(self, data):
|
||||
bytes_type = bytes if sys.version_info >= (3, 0) else str
|
||||
if not isinstance(data, bytes_type):
|
||||
data = data.encode('utf-8')
|
||||
self.ofile.write(data)
|
||||
|
||||
def flush(self, finished=None, partial=None):
|
||||
assert finished is None or isinstance(finished, bool)
|
||||
assert partial is None or isinstance(partial, bool)
|
||||
assert not (finished is None and partial is None)
|
||||
assert finished is None or partial is None
|
||||
self._ensure_validity()
|
||||
|
||||
def write_message(self, message_type, message_text, *args, **kwargs):
|
||||
self._ensure_validity()
|
||||
self._inspector.setdefault('messages', []).append((message_type, message_text.format(*args, **kwargs)))
|
||||
|
||||
def write_record(self, record):
|
||||
self._ensure_validity()
|
||||
self._write_record(record)
|
||||
|
||||
def write_records(self, records):
|
||||
self._ensure_validity()
|
||||
write_record = self._write_record
|
||||
for record in records:
|
||||
write_record(record)
|
||||
|
||||
def _clear(self):
|
||||
self._buffer.seek(0)
|
||||
self._buffer.truncate()
|
||||
self._inspector.clear()
|
||||
self._pending_record_count = 0
|
||||
|
||||
def _ensure_validity(self):
|
||||
if self._finished is True:
|
||||
assert self._record_count == 0 and len(self._inspector) == 0
|
||||
raise RuntimeError('I/O operation on closed record writer')
|
||||
|
||||
def _write_record(self, record):
|
||||
|
||||
fieldnames = self._fieldnames
|
||||
|
||||
if fieldnames is None:
|
||||
self._fieldnames = fieldnames = list(record.keys())
|
||||
value_list = imap(lambda fn: (str(fn), str('__mv_') + str(fn)), fieldnames)
|
||||
self._writerow(list(chain.from_iterable(value_list)))
|
||||
|
||||
get_value = record.get
|
||||
values = []
|
||||
|
||||
for fieldname in fieldnames:
|
||||
value = get_value(fieldname, None)
|
||||
|
||||
if value is None:
|
||||
values += (None, None)
|
||||
continue
|
||||
|
||||
value_t = type(value)
|
||||
|
||||
if issubclass(value_t, (list, tuple)):
|
||||
|
||||
if len(value) == 0:
|
||||
values += (None, None)
|
||||
continue
|
||||
|
||||
if len(value) > 1:
|
||||
value_list = value
|
||||
sv = ''
|
||||
mv = '$'
|
||||
|
||||
for value in value_list:
|
||||
|
||||
if value is None:
|
||||
sv += '\n'
|
||||
mv += '$;$'
|
||||
continue
|
||||
|
||||
value_t = type(value)
|
||||
|
||||
if value_t is not bytes:
|
||||
|
||||
if value_t is bool:
|
||||
value = str(value.real)
|
||||
elif value_t is six.text_type:
|
||||
value = value
|
||||
elif isinstance(value, six.integer_types) or value_t is float or value_t is complex:
|
||||
value = str(value)
|
||||
elif issubclass(value_t, (dict, list, tuple)):
|
||||
value = str(''.join(RecordWriter._iterencode_json(value, 0)))
|
||||
else:
|
||||
value = repr(value).encode('utf-8', errors='backslashreplace')
|
||||
|
||||
sv += value + '\n'
|
||||
mv += value.replace('$', '$$') + '$;$'
|
||||
|
||||
values += (sv[:-1], mv[:-2])
|
||||
continue
|
||||
|
||||
value = value[0]
|
||||
value_t = type(value)
|
||||
|
||||
if value_t is bool:
|
||||
values += (str(value.real), None)
|
||||
continue
|
||||
|
||||
if value_t is bytes:
|
||||
values += (value, None)
|
||||
continue
|
||||
|
||||
if value_t is six.text_type:
|
||||
if six.PY2:
|
||||
value = value.encode('utf-8')
|
||||
values += (value, None)
|
||||
continue
|
||||
|
||||
if isinstance(value, six.integer_types) or value_t is float or value_t is complex:
|
||||
values += (str(value), None)
|
||||
continue
|
||||
|
||||
if issubclass(value_t, dict):
|
||||
values += (str(''.join(RecordWriter._iterencode_json(value, 0))), None)
|
||||
continue
|
||||
|
||||
values += (repr(value), None)
|
||||
|
||||
self._writerow(values)
|
||||
self._pending_record_count += 1
|
||||
|
||||
if self.pending_record_count >= self._maxresultrows:
|
||||
self.flush(partial=True)
|
||||
|
||||
try:
|
||||
# noinspection PyUnresolvedReferences
|
||||
from _json import make_encoder
|
||||
except ImportError:
|
||||
# We may be running under PyPy 2.5 which does not include the _json module
|
||||
_iterencode_json = JSONEncoder(separators=(',', ':')).iterencode
|
||||
else:
|
||||
# Creating _iterencode_json this way yields a two-fold performance improvement on Python 2.7.9 and 2.7.10
|
||||
from json.encoder import encode_basestring_ascii
|
||||
|
||||
@staticmethod
|
||||
def _default(o):
|
||||
raise TypeError(repr(o) + ' is not JSON serializable')
|
||||
|
||||
_iterencode_json = make_encoder(
|
||||
{}, # markers (for detecting circular references)
|
||||
_default, # object_encoder
|
||||
encode_basestring_ascii, # string_encoder
|
||||
None, # indent
|
||||
':', ',', # separators
|
||||
False, # sort_keys
|
||||
False, # skip_keys
|
||||
True # allow_nan
|
||||
)
|
||||
|
||||
del make_encoder
|
||||
|
||||
|
||||
class RecordWriterV1(RecordWriter):
|
||||
|
||||
def flush(self, finished=None, partial=None):
|
||||
|
||||
RecordWriter.flush(self, finished, partial) # validates arguments and the state of this instance
|
||||
|
||||
if self.pending_record_count > 0 or (self._chunk_count == 0 and 'messages' in self._inspector):
|
||||
|
||||
messages = self._inspector.get('messages')
|
||||
|
||||
if self._chunk_count == 0:
|
||||
|
||||
# Messages are written to the messages header when we write the first chunk of data
|
||||
# Guarantee: These messages are displayed by splunkweb and the job inspector
|
||||
|
||||
if messages is not None:
|
||||
|
||||
message_level = RecordWriterV1._message_level.get
|
||||
|
||||
for level, text in messages:
|
||||
self.write(message_level(level, level))
|
||||
self.write('=')
|
||||
self.write(text)
|
||||
self.write('\r\n')
|
||||
|
||||
self.write('\r\n')
|
||||
|
||||
elif messages is not None:
|
||||
|
||||
# Messages are written to the messages header when we write subsequent chunks of data
|
||||
# Guarantee: These messages are displayed by splunkweb and the job inspector, if and only if the
|
||||
# command is configured with
|
||||
#
|
||||
# stderr_dest = message
|
||||
#
|
||||
# stderr_dest is a static configuration setting. This means that it can only be set in commands.conf.
|
||||
# It cannot be set in code.
|
||||
|
||||
stderr = sys.stderr
|
||||
|
||||
for level, text in messages:
|
||||
print(level, text, file=stderr)
|
||||
|
||||
self.write(self._buffer.getvalue())
|
||||
self._chunk_count += 1
|
||||
self._committed_record_count += self.pending_record_count
|
||||
self._clear()
|
||||
|
||||
self._finished = finished is True
|
||||
|
||||
_message_level = {
|
||||
'DEBUG': 'debug_message',
|
||||
'ERROR': 'error_message',
|
||||
'FATAL': 'error_message',
|
||||
'INFO': 'info_message',
|
||||
'WARN': 'warn_message'
|
||||
}
|
||||
|
||||
|
||||
class RecordWriterV2(RecordWriter):
|
||||
|
||||
def flush(self, finished=None, partial=None):
|
||||
|
||||
RecordWriter.flush(self, finished, partial) # validates arguments and the state of this instance
|
||||
|
||||
if partial or not finished:
|
||||
# Don't flush partial chunks, since the SCP v2 protocol does not
|
||||
# provide a way to send partial chunks yet.
|
||||
return
|
||||
|
||||
if not self.is_flushed:
|
||||
self.write_chunk(finished=True)
|
||||
|
||||
def write_chunk(self, finished=None):
|
||||
inspector = self._inspector
|
||||
self._committed_record_count += self.pending_record_count
|
||||
self._chunk_count += 1
|
||||
|
||||
# TODO: DVPL-6448: splunklib.searchcommands | Add support for partial: true when it is implemented in
|
||||
# ChunkedExternProcessor (See SPL-103525)
|
||||
#
|
||||
# We will need to replace the following block of code with this block:
|
||||
#
|
||||
# metadata = [item for item in (('inspector', inspector), ('finished', finished), ('partial', partial))]
|
||||
#
|
||||
# if partial is True:
|
||||
# finished = False
|
||||
|
||||
if len(inspector) == 0:
|
||||
inspector = None
|
||||
|
||||
metadata = [item for item in (('inspector', inspector), ('finished', finished))]
|
||||
self._write_chunk(metadata, self._buffer.getvalue())
|
||||
self._clear()
|
||||
|
||||
def write_metadata(self, configuration):
|
||||
self._ensure_validity()
|
||||
|
||||
metadata = chain(six.iteritems(configuration), (('inspector', self._inspector if self._inspector else None),))
|
||||
self._write_chunk(metadata, '')
|
||||
self.write('\n')
|
||||
self._clear()
|
||||
|
||||
def write_metric(self, name, value):
|
||||
self._ensure_validity()
|
||||
self._inspector['metric.' + name] = value
|
||||
|
||||
def _clear(self):
|
||||
super(RecordWriterV2, self)._clear()
|
||||
self._fieldnames = None
|
||||
|
||||
def _write_chunk(self, metadata, body):
|
||||
|
||||
if metadata:
|
||||
metadata = str(''.join(self._iterencode_json(dict([(n, v) for n, v in metadata if v is not None]), 0)))
|
||||
if sys.version_info >= (3, 0):
|
||||
metadata = metadata.encode('utf-8')
|
||||
metadata_length = len(metadata)
|
||||
else:
|
||||
metadata_length = 0
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
body = body.encode('utf-8')
|
||||
body_length = len(body)
|
||||
|
||||
if not (metadata_length > 0 or body_length > 0):
|
||||
return
|
||||
|
||||
start_line = 'chunked 1.0,%s,%s\n' % (metadata_length, body_length)
|
||||
self.write(start_line)
|
||||
self.write(metadata)
|
||||
self.write(body)
|
||||
self._ofile.flush()
|
||||
self._flushed = True
|
||||
@@ -1,281 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright © 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from itertools import chain
|
||||
|
||||
from .internals import ConfigurationSettingsType, json_encode_string
|
||||
from .decorators import ConfigurationSetting, Option
|
||||
from .streaming_command import StreamingCommand
|
||||
from .search_command import SearchCommand
|
||||
from .validators import Set
|
||||
from splunklib import six
|
||||
|
||||
|
||||
class ReportingCommand(SearchCommand):
|
||||
""" Processes search result records and generates a reporting data structure.
|
||||
|
||||
Reporting search commands run as either reduce or map/reduce operations. The reduce part runs on a search head and
|
||||
is responsible for processing a single chunk of search results to produce the command's reporting data structure.
|
||||
The map part is called a streaming preop. It feeds the reduce part with partial results and by default runs on the
|
||||
search head and/or one or more indexers.
|
||||
|
||||
You must implement a :meth:`reduce` method as a generator function that iterates over a set of event records and
|
||||
yields a reporting data structure. You may implement a :meth:`map` method as a generator function that iterates
|
||||
over a set of event records and yields :class:`dict` or :class:`list(dict)` instances.
|
||||
|
||||
ReportingCommand configuration
|
||||
==============================
|
||||
|
||||
Configure the :meth:`map` operation using a Configuration decorator on your :meth:`map` method. Configure it like
|
||||
you would a :class:`StreamingCommand`. Configure the :meth:`reduce` operation using a Configuration decorator on
|
||||
your :meth:`ReportingCommand` class.
|
||||
|
||||
You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
|
||||
Splunk 6.3 or later.
|
||||
|
||||
"""
|
||||
# region Special methods
|
||||
|
||||
def __init__(self):
|
||||
SearchCommand.__init__(self)
|
||||
|
||||
# endregion
|
||||
|
||||
# region Options
|
||||
|
||||
phase = Option(doc='''
|
||||
**Syntax:** phase=[map|reduce]
|
||||
|
||||
**Description:** Identifies the phase of the current map-reduce operation.
|
||||
|
||||
''', default='reduce', validate=Set('map', 'reduce'))
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
def map(self, records):
|
||||
""" Override this method to compute partial results.
|
||||
|
||||
:param records:
|
||||
:type records:
|
||||
|
||||
You must override this method, if :code:`requires_preop=True`.
|
||||
|
||||
"""
|
||||
return NotImplemented
|
||||
|
||||
def prepare(self):
|
||||
|
||||
phase = self.phase
|
||||
|
||||
if phase == 'map':
|
||||
# noinspection PyUnresolvedReferences
|
||||
self._configuration = self.map.ConfigurationSettings(self)
|
||||
return
|
||||
|
||||
if phase == 'reduce':
|
||||
streaming_preop = chain((self.name, 'phase="map"', str(self._options)), self.fieldnames)
|
||||
self._configuration.streaming_preop = ' '.join(streaming_preop)
|
||||
return
|
||||
|
||||
raise RuntimeError('Unrecognized reporting command phase: {}'.format(json_encode_string(six.text_type(phase))))
|
||||
|
||||
def reduce(self, records):
|
||||
""" Override this method to produce a reporting data structure.
|
||||
|
||||
You must override this method.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('reduce(self, records)')
|
||||
|
||||
def _execute(self, ifile, process):
|
||||
SearchCommand._execute(self, ifile, getattr(self, self.phase))
|
||||
|
||||
# endregion
|
||||
|
||||
# region Types
|
||||
|
||||
class ConfigurationSettings(SearchCommand.ConfigurationSettings):
|
||||
""" Represents the configuration settings for a :code:`ReportingCommand`.
|
||||
|
||||
"""
|
||||
# region SCP v1/v2 Properties
|
||||
|
||||
required_fields = ConfigurationSetting(doc='''
|
||||
List of required fields for this search which back-propagates to the generating search.
|
||||
|
||||
Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
|
||||
:code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
|
||||
specify a value of :const:`['*']`. No error is generated if a specified field is missing.
|
||||
|
||||
Default: :const:`None`, which implicitly selects all fields.
|
||||
|
||||
Supported by: SCP 1, SCP 2
|
||||
|
||||
''')
|
||||
|
||||
requires_preop = ConfigurationSetting(doc='''
|
||||
Indicates whether :meth:`ReportingCommand.map` is required for proper command execution.
|
||||
|
||||
If :const:`True`, :meth:`ReportingCommand.map` is guaranteed to be called. If :const:`False`, Splunk
|
||||
considers it to be an optimization that may be skipped.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1, SCP 2
|
||||
|
||||
''')
|
||||
|
||||
streaming_preop = ConfigurationSetting(doc='''
|
||||
Denotes the requested streaming preop search string.
|
||||
|
||||
Computed.
|
||||
|
||||
Supported by: SCP 1, SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v1 Properties
|
||||
|
||||
clear_required_fields = ConfigurationSetting(doc='''
|
||||
:const:`True`, if required_fields represent the *only* fields required.
|
||||
|
||||
If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
|
||||
In most cases, :const:`True` is appropriate for reporting commands.
|
||||
|
||||
Default: :const:`True`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
retainsevents = ConfigurationSetting(readonly=True, value=False, doc='''
|
||||
Signals that :meth:`ReportingCommand.reduce` transforms _raw events to produce a reporting data structure.
|
||||
|
||||
Fixed: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
streaming = ConfigurationSetting(readonly=True, value=False, doc='''
|
||||
Signals that :meth:`ReportingCommand.reduce` runs on the search head.
|
||||
|
||||
Fixed: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v2 Properties
|
||||
|
||||
maxinputs = ConfigurationSetting(doc='''
|
||||
Specifies the maximum number of events that can be passed to the command for each invocation.
|
||||
|
||||
This limit cannot exceed the value of `maxresultrows` in limits.conf_. Under SCP 1 you must specify this
|
||||
value in commands.conf_.
|
||||
|
||||
Default: The value of `maxresultrows`.
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
.. _limits.conf: http://docs.splunk.com/Documentation/Splunk/latest/admin/Limitsconf
|
||||
|
||||
''')
|
||||
|
||||
run_in_preview = ConfigurationSetting(doc='''
|
||||
:const:`True`, if this command should be run to generate results for preview; not wait for final output.
|
||||
|
||||
This may be important for commands that have side effects (e.g., outputlookup).
|
||||
|
||||
Default: :const:`True`
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
type = ConfigurationSetting(readonly=True, value='reporting', doc='''
|
||||
Command type name.
|
||||
|
||||
Fixed: :const:`'reporting'`.
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
@classmethod
|
||||
def fix_up(cls, command):
|
||||
""" Verifies :code:`command` class structure and configures the :code:`command.map` method.
|
||||
|
||||
Verifies that :code:`command` derives from :class:`ReportingCommand` and overrides
|
||||
:code:`ReportingCommand.reduce`. It then configures :code:`command.reduce`, if an overriding implementation
|
||||
of :code:`ReportingCommand.reduce` has been provided.
|
||||
|
||||
:param command: :code:`ReportingCommand` class
|
||||
|
||||
Exceptions:
|
||||
|
||||
:code:`TypeError` :code:`command` class is not derived from :code:`ReportingCommand`
|
||||
:code:`AttributeError` No :code:`ReportingCommand.reduce` override
|
||||
|
||||
"""
|
||||
if not issubclass(command, ReportingCommand):
|
||||
raise TypeError('{} is not a ReportingCommand'.format( command))
|
||||
|
||||
if command.reduce == ReportingCommand.reduce:
|
||||
raise AttributeError('No ReportingCommand.reduce override')
|
||||
|
||||
if command.map == ReportingCommand.map:
|
||||
cls._requires_preop = False
|
||||
return
|
||||
|
||||
f = vars(command)['map'] # Function backing the map method
|
||||
|
||||
# EXPLANATION OF PREVIOUS STATEMENT: There is no way to add custom attributes to methods. See [Why does
|
||||
# setattr fail on a method](http://stackoverflow.com/questions/7891277/why-does-setattr-fail-on-a-bound-method) for a discussion of this issue.
|
||||
|
||||
try:
|
||||
settings = f._settings
|
||||
except AttributeError:
|
||||
f.ConfigurationSettings = StreamingCommand.ConfigurationSettings
|
||||
return
|
||||
|
||||
# Create new StreamingCommand.ConfigurationSettings class
|
||||
|
||||
module = command.__module__ + '.' + command.__name__ + '.map'
|
||||
name = b'ConfigurationSettings'
|
||||
bases = (StreamingCommand.ConfigurationSettings,)
|
||||
|
||||
f.ConfigurationSettings = ConfigurationSettingsType(module, name, bases)
|
||||
ConfigurationSetting.fix_up(f.ConfigurationSettings, settings)
|
||||
del f._settings
|
||||
|
||||
pass
|
||||
# endregion
|
||||
|
||||
pass
|
||||
# endregion
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from splunklib import six
|
||||
from splunklib.six.moves import map as imap, filter as ifilter
|
||||
|
||||
from .decorators import ConfigurationSetting
|
||||
from .search_command import SearchCommand
|
||||
|
||||
|
||||
class StreamingCommand(SearchCommand):
|
||||
""" Applies a transformation to search results as they travel through the streams pipeline.
|
||||
|
||||
Streaming commands typically filter, augment, or update, search result records. Splunk will send them in batches of
|
||||
up to 50,000 records. Hence, a search command must be prepared to be invoked many times during the course of
|
||||
pipeline processing. Each invocation should produce a set of results independently usable by downstream processors.
|
||||
|
||||
By default Splunk may choose to run a streaming command locally on a search head and/or remotely on one or more
|
||||
indexers concurrently. The size and frequency of the search result batches sent to the command will vary based
|
||||
on scheduling considerations.
|
||||
|
||||
StreamingCommand configuration
|
||||
==============================
|
||||
|
||||
You can configure your command for operation under Search Command Protocol (SCP) version 1 or 2. SCP 2 requires
|
||||
Splunk 6.3 or later.
|
||||
|
||||
"""
|
||||
# region Methods
|
||||
|
||||
def stream(self, records):
|
||||
""" Generator function that processes and yields event records to the Splunk stream pipeline.
|
||||
|
||||
You must override this method.
|
||||
|
||||
"""
|
||||
raise NotImplementedError('StreamingCommand.stream(self, records)')
|
||||
|
||||
def _execute(self, ifile, process):
|
||||
SearchCommand._execute(self, ifile, self.stream)
|
||||
|
||||
# endregion
|
||||
|
||||
class ConfigurationSettings(SearchCommand.ConfigurationSettings):
|
||||
""" Represents the configuration settings that apply to a :class:`StreamingCommand`.
|
||||
|
||||
"""
|
||||
# region SCP v1/v2 properties
|
||||
|
||||
required_fields = ConfigurationSetting(doc='''
|
||||
List of required fields for this search which back-propagates to the generating search.
|
||||
|
||||
Setting this value enables selected fields mode under SCP 2. Under SCP 1 you must also specify
|
||||
:code:`clear_required_fields=True` to enable selected fields mode. To explicitly select all fields,
|
||||
specify a value of :const:`['*']`. No error is generated if a specified field is missing.
|
||||
|
||||
Default: :const:`None`, which implicitly selects all fields.
|
||||
|
||||
Supported by: SCP 1, SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v1 properties
|
||||
|
||||
clear_required_fields = ConfigurationSetting(doc='''
|
||||
:const:`True`, if required_fields represent the *only* fields required.
|
||||
|
||||
If :const:`False`, required_fields are additive to any fields that may be required by subsequent commands.
|
||||
In most cases, :const:`False` is appropriate for streaming commands.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
local = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command should run locally on the search head.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
overrides_timeorder = ConfigurationSetting(doc='''
|
||||
:const:`True`, if the command changes the order of events with respect to time.
|
||||
|
||||
Default: :const:`False`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
streaming = ConfigurationSetting(readonly=True, value=True, doc='''
|
||||
Specifies that the command is streamable.
|
||||
|
||||
Fixed: :const:`True`
|
||||
|
||||
Supported by: SCP 1
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region SCP v2 Properties
|
||||
|
||||
distributed = ConfigurationSetting(value=True, doc='''
|
||||
:const:`True`, if this command should be distributed to indexers.
|
||||
|
||||
Under SCP 1 you must either specify `local = False` or include this line in commands.conf_, if this command
|
||||
should be distributed to indexers.
|
||||
|
||||
..code:
|
||||
local = true
|
||||
|
||||
Default: :const:`True`
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
.. commands.conf_: http://docs.splunk.com/Documentation/Splunk/latest/Admin/Commandsconf
|
||||
|
||||
''')
|
||||
|
||||
maxinputs = ConfigurationSetting(doc='''
|
||||
Specifies the maximum number of events that can be passed to the command for each invocation.
|
||||
|
||||
This limit cannot exceed the value of `maxresultrows` in limits.conf. Under SCP 1 you must specify this
|
||||
value in commands.conf_.
|
||||
|
||||
Default: The value of `maxresultrows`.
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
type = ConfigurationSetting(readonly=True, value='streaming', doc='''
|
||||
Command type name.
|
||||
|
||||
Fixed: :const:`'streaming'`
|
||||
|
||||
Supported by: SCP 2
|
||||
|
||||
''')
|
||||
|
||||
# endregion
|
||||
|
||||
# region Methods
|
||||
|
||||
@classmethod
|
||||
def fix_up(cls, command):
|
||||
""" Verifies :code:`command` class structure.
|
||||
|
||||
"""
|
||||
if command.stream == StreamingCommand.stream:
|
||||
raise AttributeError('No StreamingCommand.stream override')
|
||||
return
|
||||
|
||||
# TODO: Stop looking like a dictionary because we don't obey the semantics
|
||||
# N.B.: Does not use Python 2 dict copy semantics
|
||||
def iteritems(self):
|
||||
iteritems = SearchCommand.ConfigurationSettings.iteritems(self)
|
||||
version = self.command.protocol_version
|
||||
if version == 1:
|
||||
if self.required_fields is None:
|
||||
iteritems = ifilter(lambda name_value: name_value[0] != 'clear_required_fields', iteritems)
|
||||
else:
|
||||
iteritems = ifilter(lambda name_value2: name_value2[0] != 'distributed', iteritems)
|
||||
if not self.distributed:
|
||||
iteritems = imap(
|
||||
lambda name_value1: (name_value1[0], 'stateful') if name_value1[0] == 'type' else (name_value1[0], name_value1[1]), iteritems)
|
||||
return iteritems
|
||||
|
||||
# N.B.: Does not use Python 3 dict view semantics
|
||||
if not six.PY2:
|
||||
items = iteritems
|
||||
|
||||
# endregion
|
||||
@@ -1,394 +0,0 @@
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
from json.encoder import encode_basestring_ascii as json_encode_string
|
||||
from collections import namedtuple
|
||||
from splunklib.six.moves import StringIO
|
||||
from io import open
|
||||
import csv
|
||||
import os
|
||||
import re
|
||||
from splunklib import six
|
||||
from splunklib.six.moves import getcwd
|
||||
|
||||
|
||||
class Validator(object):
|
||||
""" Base class for validators that check and format search command options.
|
||||
|
||||
You must inherit from this class and override :code:`Validator.__call__` and
|
||||
:code:`Validator.format`. :code:`Validator.__call__` should convert the
|
||||
value it receives as argument and then return it or raise a
|
||||
:code:`ValueError`, if the value will not convert.
|
||||
|
||||
:code:`Validator.format` should return a human readable version of the value
|
||||
it receives as argument the same way :code:`str` does.
|
||||
|
||||
"""
|
||||
def __call__(self, value):
|
||||
raise NotImplementedError()
|
||||
|
||||
def format(self, value):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class Boolean(Validator):
|
||||
""" Validates Boolean option values.
|
||||
|
||||
"""
|
||||
truth_values = {
|
||||
'1': True, '0': False,
|
||||
't': True, 'f': False,
|
||||
'true': True, 'false': False,
|
||||
'y': True, 'n': False,
|
||||
'yes': True, 'no': False
|
||||
}
|
||||
|
||||
def __call__(self, value):
|
||||
if not (value is None or isinstance(value, bool)):
|
||||
value = six.text_type(value).lower()
|
||||
if value not in Boolean.truth_values:
|
||||
raise ValueError('Unrecognized truth value: {0}'.format(value))
|
||||
value = Boolean.truth_values[value]
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else 't' if value else 'f'
|
||||
|
||||
|
||||
class Code(Validator):
|
||||
""" Validates code option values.
|
||||
|
||||
This validator compiles an option value into a Python code object that can be executed by :func:`exec` or evaluated
|
||||
by :func:`eval`. The value returned is a :func:`namedtuple` with two members: object, the result of compilation, and
|
||||
source, the original option value.
|
||||
|
||||
"""
|
||||
def __init__(self, mode='eval'):
|
||||
"""
|
||||
:param mode: Specifies what kind of code must be compiled; it can be :const:`'exec'`, if source consists of a
|
||||
sequence of statements, :const:`'eval'`, if it consists of a single expression, or :const:`'single'` if it
|
||||
consists of a single interactive statement. In the latter case, expression statements that evaluate to
|
||||
something other than :const:`None` will be printed.
|
||||
:type mode: unicode or bytes
|
||||
|
||||
"""
|
||||
self._mode = mode
|
||||
|
||||
def __call__(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
return Code.object(compile(value, 'string', self._mode), six.text_type(value))
|
||||
except (SyntaxError, TypeError) as error:
|
||||
if six.PY2:
|
||||
message = error.message
|
||||
else:
|
||||
message = str(error)
|
||||
|
||||
six.raise_from(ValueError(message), error)
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else value.source
|
||||
|
||||
object = namedtuple('Code', ('object', 'source'))
|
||||
|
||||
|
||||
class Fieldname(Validator):
|
||||
""" Validates field name option values.
|
||||
|
||||
"""
|
||||
pattern = re.compile(r'''[_.a-zA-Z-][_.a-zA-Z0-9-]*$''')
|
||||
|
||||
def __call__(self, value):
|
||||
if value is not None:
|
||||
value = six.text_type(value)
|
||||
if Fieldname.pattern.match(value) is None:
|
||||
raise ValueError('Illegal characters in fieldname: {}'.format(value))
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return value
|
||||
|
||||
|
||||
class File(Validator):
|
||||
""" Validates file option values.
|
||||
|
||||
"""
|
||||
def __init__(self, mode='rt', buffering=None, directory=None):
|
||||
self.mode = mode
|
||||
self.buffering = buffering
|
||||
self.directory = File._var_run_splunk if directory is None else directory
|
||||
|
||||
def __call__(self, value):
|
||||
|
||||
if value is None:
|
||||
return value
|
||||
|
||||
path = six.text_type(value)
|
||||
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(self.directory, path)
|
||||
|
||||
try:
|
||||
value = open(path, self.mode) if self.buffering is None else open(path, self.mode, self.buffering)
|
||||
except IOError as error:
|
||||
raise ValueError('Cannot open {0} with mode={1} and buffering={2}: {3}'.format(
|
||||
value, self.mode, self.buffering, error))
|
||||
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else value.name
|
||||
|
||||
_var_run_splunk = os.path.join(
|
||||
os.environ['SPLUNK_HOME'] if 'SPLUNK_HOME' in os.environ else getcwd(), 'var', 'run', 'splunk')
|
||||
|
||||
|
||||
class Integer(Validator):
|
||||
""" Validates integer option values.
|
||||
|
||||
"""
|
||||
def __init__(self, minimum=None, maximum=None):
|
||||
if minimum is not None and maximum is not None:
|
||||
def check_range(value):
|
||||
if not (minimum <= value <= maximum):
|
||||
raise ValueError('Expected integer in the range [{0},{1}], not {2}'.format(minimum, maximum, value))
|
||||
return
|
||||
elif minimum is not None:
|
||||
def check_range(value):
|
||||
if value < minimum:
|
||||
raise ValueError('Expected integer in the range [{0},+∞], not {1}'.format(minimum, value))
|
||||
return
|
||||
elif maximum is not None:
|
||||
def check_range(value):
|
||||
if value > maximum:
|
||||
raise ValueError('Expected integer in the range [-∞,{0}], not {1}'.format(maximum, value))
|
||||
return
|
||||
else:
|
||||
def check_range(value):
|
||||
return
|
||||
|
||||
self.check_range = check_range
|
||||
return
|
||||
|
||||
def __call__(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
if six.PY2:
|
||||
value = long(value)
|
||||
else:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
raise ValueError('Expected integer value, not {}'.format(json_encode_string(value)))
|
||||
|
||||
self.check_range(value)
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else six.text_type(int(value))
|
||||
|
||||
|
||||
class Duration(Validator):
|
||||
""" Validates duration option values.
|
||||
|
||||
"""
|
||||
def __call__(self, value):
|
||||
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
p = value.split(':', 2)
|
||||
result = None
|
||||
_60 = Duration._60
|
||||
_unsigned = Duration._unsigned
|
||||
|
||||
try:
|
||||
if len(p) == 1:
|
||||
result = _unsigned(p[0])
|
||||
if len(p) == 2:
|
||||
result = 60 * _unsigned(p[0]) + _60(p[1])
|
||||
if len(p) == 3:
|
||||
result = 3600 * _unsigned(p[0]) + 60 * _60(p[1]) + _60(p[2])
|
||||
except ValueError:
|
||||
raise ValueError('Invalid duration value: {0}'.format(value))
|
||||
|
||||
return result
|
||||
|
||||
def format(self, value):
|
||||
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
value = int(value)
|
||||
|
||||
s = value % 60
|
||||
m = value // 60 % 60
|
||||
h = value // (60 * 60)
|
||||
|
||||
return '{0:02d}:{1:02d}:{2:02d}'.format(h, m, s)
|
||||
|
||||
_60 = Integer(0, 59)
|
||||
_unsigned = Integer(0)
|
||||
|
||||
|
||||
class List(Validator):
|
||||
""" Validates a list of strings
|
||||
|
||||
"""
|
||||
class Dialect(csv.Dialect):
|
||||
""" Describes the properties of list option values. """
|
||||
strict = True
|
||||
delimiter = str(',')
|
||||
quotechar = str('"')
|
||||
doublequote = True
|
||||
lineterminator = str('\n')
|
||||
skipinitialspace = True
|
||||
quoting = csv.QUOTE_MINIMAL
|
||||
|
||||
def __init__(self, validator=None):
|
||||
if not (validator is None or isinstance(validator, Validator)):
|
||||
raise ValueError('Expected a Validator instance or None for validator, not {}', repr(validator))
|
||||
self._validator = validator
|
||||
|
||||
def __call__(self, value):
|
||||
|
||||
if value is None or isinstance(value, list):
|
||||
return value
|
||||
|
||||
try:
|
||||
value = next(csv.reader([value], self.Dialect))
|
||||
except csv.Error as error:
|
||||
raise ValueError(error)
|
||||
|
||||
if self._validator is None:
|
||||
return value
|
||||
|
||||
try:
|
||||
for index, item in enumerate(value):
|
||||
value[index] = self._validator(item)
|
||||
except ValueError as error:
|
||||
raise ValueError('Could not convert item {}: {}'.format(index, error))
|
||||
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
output = StringIO()
|
||||
writer = csv.writer(output, List.Dialect)
|
||||
writer.writerow(value)
|
||||
value = output.getvalue()
|
||||
return value[:-1]
|
||||
|
||||
|
||||
class Map(Validator):
|
||||
""" Validates map option values.
|
||||
|
||||
"""
|
||||
def __init__(self, **kwargs):
|
||||
self.membership = kwargs
|
||||
|
||||
def __call__(self, value):
|
||||
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
value = six.text_type(value)
|
||||
|
||||
if value not in self.membership:
|
||||
raise ValueError('Unrecognized value: {0}'.format(value))
|
||||
|
||||
return self.membership[value]
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else list(self.membership.keys())[list(self.membership.values()).index(value)]
|
||||
|
||||
|
||||
class Match(Validator):
|
||||
""" Validates that a value matches a regular expression pattern.
|
||||
|
||||
"""
|
||||
def __init__(self, name, pattern, flags=0):
|
||||
self.name = six.text_type(name)
|
||||
self.pattern = re.compile(pattern, flags)
|
||||
|
||||
def __call__(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
value = six.text_type(value)
|
||||
if self.pattern.match(value) is None:
|
||||
raise ValueError('Expected {}, not {}'.format(self.name, json_encode_string(value)))
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else six.text_type(value)
|
||||
|
||||
|
||||
class OptionName(Validator):
|
||||
""" Validates option names.
|
||||
|
||||
"""
|
||||
pattern = re.compile(r'''(?=\w)[^\d]\w*$''', re.UNICODE)
|
||||
|
||||
def __call__(self, value):
|
||||
if value is not None:
|
||||
value = six.text_type(value)
|
||||
if OptionName.pattern.match(value) is None:
|
||||
raise ValueError('Illegal characters in option name: {}'.format(value))
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else six.text_type(value)
|
||||
|
||||
|
||||
class RegularExpression(Validator):
|
||||
""" Validates regular expression option values.
|
||||
|
||||
"""
|
||||
def __call__(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
value = re.compile(six.text_type(value))
|
||||
except re.error as error:
|
||||
raise ValueError('{}: {}'.format(six.text_type(error).capitalize(), value))
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return None if value is None else value.pattern
|
||||
|
||||
|
||||
class Set(Validator):
|
||||
""" Validates set option values.
|
||||
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
self.membership = set(args)
|
||||
|
||||
def __call__(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
value = six.text_type(value)
|
||||
if value not in self.membership:
|
||||
raise ValueError('Unrecognized value: {}'.format(value))
|
||||
return value
|
||||
|
||||
def format(self, value):
|
||||
return self.__call__(value)
|
||||
|
||||
|
||||
__all__ = ['Boolean', 'Code', 'Duration', 'File', 'Integer', 'List', 'Map', 'RegularExpression', 'Set']
|
||||
Vendored
-980
@@ -1,980 +0,0 @@
|
||||
# Copyright (c) 2010-2020 Benjamin Peterson
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
"""Utilities for writing code that runs on Python 2 and 3"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
import sys
|
||||
import types
|
||||
|
||||
__author__ = "Benjamin Peterson <benjamin@python.org>"
|
||||
__version__ = "1.14.0"
|
||||
|
||||
|
||||
# Useful for very coarse version differentiation.
|
||||
PY2 = sys.version_info[0] == 2
|
||||
PY3 = sys.version_info[0] == 3
|
||||
PY34 = sys.version_info[0:2] >= (3, 4)
|
||||
|
||||
if PY3:
|
||||
string_types = str,
|
||||
integer_types = int,
|
||||
class_types = type,
|
||||
text_type = str
|
||||
binary_type = bytes
|
||||
|
||||
MAXSIZE = sys.maxsize
|
||||
else:
|
||||
string_types = basestring,
|
||||
integer_types = (int, long)
|
||||
class_types = (type, types.ClassType)
|
||||
text_type = unicode
|
||||
binary_type = str
|
||||
|
||||
if sys.platform.startswith("java"):
|
||||
# Jython always uses 32 bits.
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# It's possible to have sizeof(long) != sizeof(Py_ssize_t).
|
||||
class X(object):
|
||||
|
||||
def __len__(self):
|
||||
return 1 << 31
|
||||
try:
|
||||
len(X())
|
||||
except OverflowError:
|
||||
# 32-bit
|
||||
MAXSIZE = int((1 << 31) - 1)
|
||||
else:
|
||||
# 64-bit
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
func.__doc__ = doc
|
||||
|
||||
|
||||
def _import_module(name):
|
||||
"""Import module, returning the module after the last dot."""
|
||||
__import__(name)
|
||||
return sys.modules[name]
|
||||
|
||||
|
||||
class _LazyDescr(object):
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __get__(self, obj, tp):
|
||||
result = self._resolve()
|
||||
setattr(obj, self.name, result) # Invokes __set__.
|
||||
try:
|
||||
# This is a bit ugly, but it avoids running this again by
|
||||
# removing this descriptor.
|
||||
delattr(obj.__class__, self.name)
|
||||
except AttributeError:
|
||||
pass
|
||||
return result
|
||||
|
||||
|
||||
class MovedModule(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old, new=None):
|
||||
super(MovedModule, self).__init__(name)
|
||||
if PY3:
|
||||
if new is None:
|
||||
new = name
|
||||
self.mod = new
|
||||
else:
|
||||
self.mod = old
|
||||
|
||||
def _resolve(self):
|
||||
return _import_module(self.mod)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
_module = self._resolve()
|
||||
value = getattr(_module, attr)
|
||||
setattr(self, attr, value)
|
||||
return value
|
||||
|
||||
|
||||
class _LazyModule(types.ModuleType):
|
||||
|
||||
def __init__(self, name):
|
||||
super(_LazyModule, self).__init__(name)
|
||||
self.__doc__ = self.__class__.__doc__
|
||||
|
||||
def __dir__(self):
|
||||
attrs = ["__doc__", "__name__"]
|
||||
attrs += [attr.name for attr in self._moved_attributes]
|
||||
return attrs
|
||||
|
||||
# Subclasses should override this
|
||||
_moved_attributes = []
|
||||
|
||||
|
||||
class MovedAttribute(_LazyDescr):
|
||||
|
||||
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
|
||||
super(MovedAttribute, self).__init__(name)
|
||||
if PY3:
|
||||
if new_mod is None:
|
||||
new_mod = name
|
||||
self.mod = new_mod
|
||||
if new_attr is None:
|
||||
if old_attr is None:
|
||||
new_attr = name
|
||||
else:
|
||||
new_attr = old_attr
|
||||
self.attr = new_attr
|
||||
else:
|
||||
self.mod = old_mod
|
||||
if old_attr is None:
|
||||
old_attr = name
|
||||
self.attr = old_attr
|
||||
|
||||
def _resolve(self):
|
||||
module = _import_module(self.mod)
|
||||
return getattr(module, self.attr)
|
||||
|
||||
|
||||
class _SixMetaPathImporter(object):
|
||||
|
||||
"""
|
||||
A meta path importer to import six.moves and its submodules.
|
||||
|
||||
This class implements a PEP302 finder and loader. It should be compatible
|
||||
with Python 2.5 and all existing versions of Python3
|
||||
"""
|
||||
|
||||
def __init__(self, six_module_name):
|
||||
self.name = six_module_name
|
||||
self.known_modules = {}
|
||||
|
||||
def _add_module(self, mod, *fullnames):
|
||||
for fullname in fullnames:
|
||||
self.known_modules[self.name + "." + fullname] = mod
|
||||
|
||||
def _get_module(self, fullname):
|
||||
return self.known_modules[self.name + "." + fullname]
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
if fullname in self.known_modules:
|
||||
return self
|
||||
return None
|
||||
|
||||
def __get_module(self, fullname):
|
||||
try:
|
||||
return self.known_modules[fullname]
|
||||
except KeyError:
|
||||
raise ImportError("This loader does not know module " + fullname)
|
||||
|
||||
def load_module(self, fullname):
|
||||
try:
|
||||
# in case of a reload
|
||||
return sys.modules[fullname]
|
||||
except KeyError:
|
||||
pass
|
||||
mod = self.__get_module(fullname)
|
||||
if isinstance(mod, MovedModule):
|
||||
mod = mod._resolve()
|
||||
else:
|
||||
mod.__loader__ = self
|
||||
sys.modules[fullname] = mod
|
||||
return mod
|
||||
|
||||
def is_package(self, fullname):
|
||||
"""
|
||||
Return true, if the named module is a package.
|
||||
|
||||
We need this method to get correct spec objects with
|
||||
Python 3.4 (see PEP451)
|
||||
"""
|
||||
return hasattr(self.__get_module(fullname), "__path__")
|
||||
|
||||
def get_code(self, fullname):
|
||||
"""Return None
|
||||
|
||||
Required, if is_package is implemented"""
|
||||
self.__get_module(fullname) # eventually raises ImportError
|
||||
return None
|
||||
get_source = get_code # same as get_code
|
||||
|
||||
_importer = _SixMetaPathImporter(__name__)
|
||||
|
||||
|
||||
class _MovedItems(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects"""
|
||||
__path__ = [] # mark as package
|
||||
|
||||
|
||||
_moved_attributes = [
|
||||
MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
|
||||
MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
|
||||
MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
|
||||
MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
|
||||
MovedAttribute("intern", "__builtin__", "sys"),
|
||||
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
|
||||
MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
|
||||
MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
|
||||
MovedAttribute("getoutput", "commands", "subprocess"),
|
||||
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
|
||||
MovedAttribute("reduce", "__builtin__", "functools"),
|
||||
MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
|
||||
MovedAttribute("StringIO", "StringIO", "io"),
|
||||
MovedAttribute("UserDict", "UserDict", "collections"),
|
||||
MovedAttribute("UserList", "UserList", "collections"),
|
||||
MovedAttribute("UserString", "UserString", "collections"),
|
||||
MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
|
||||
MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
|
||||
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
|
||||
MovedModule("builtins", "__builtin__"),
|
||||
MovedModule("configparser", "ConfigParser"),
|
||||
MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
|
||||
MovedModule("copyreg", "copy_reg"),
|
||||
MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
|
||||
MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
|
||||
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
|
||||
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
|
||||
MovedModule("http_cookies", "Cookie", "http.cookies"),
|
||||
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
|
||||
MovedModule("html_parser", "HTMLParser", "html.parser"),
|
||||
MovedModule("http_client", "httplib", "http.client"),
|
||||
MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
|
||||
MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
|
||||
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
|
||||
MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
|
||||
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
|
||||
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
|
||||
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
|
||||
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
|
||||
MovedModule("cPickle", "cPickle", "pickle"),
|
||||
MovedModule("queue", "Queue"),
|
||||
MovedModule("reprlib", "repr"),
|
||||
MovedModule("socketserver", "SocketServer"),
|
||||
MovedModule("_thread", "thread", "_thread"),
|
||||
MovedModule("tkinter", "Tkinter"),
|
||||
MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
|
||||
MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
|
||||
MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
|
||||
MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
|
||||
MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
|
||||
MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
|
||||
MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
|
||||
MovedModule("tkinter_colorchooser", "tkColorChooser",
|
||||
"tkinter.colorchooser"),
|
||||
MovedModule("tkinter_commondialog", "tkCommonDialog",
|
||||
"tkinter.commondialog"),
|
||||
MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
|
||||
MovedModule("tkinter_font", "tkFont", "tkinter.font"),
|
||||
MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
|
||||
MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
|
||||
"tkinter.simpledialog"),
|
||||
MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
|
||||
MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
|
||||
MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
|
||||
MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
|
||||
MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
|
||||
MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
|
||||
]
|
||||
# Add windows specific modules.
|
||||
if sys.platform == "win32":
|
||||
_moved_attributes += [
|
||||
MovedModule("winreg", "_winreg"),
|
||||
]
|
||||
|
||||
for attr in _moved_attributes:
|
||||
setattr(_MovedItems, attr.name, attr)
|
||||
if isinstance(attr, MovedModule):
|
||||
_importer._add_module(attr, "moves." + attr.name)
|
||||
del attr
|
||||
|
||||
_MovedItems._moved_attributes = _moved_attributes
|
||||
|
||||
moves = _MovedItems(__name__ + ".moves")
|
||||
_importer._add_module(moves, "moves")
|
||||
|
||||
|
||||
class Module_six_moves_urllib_parse(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects in six.moves.urllib_parse"""
|
||||
|
||||
|
||||
_urllib_parse_moved_attributes = [
|
||||
MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urljoin", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urlparse", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("quote", "urllib", "urllib.parse"),
|
||||
MovedAttribute("quote_plus", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
|
||||
MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
|
||||
MovedAttribute("urlencode", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splitquery", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splittag", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splituser", "urllib", "urllib.parse"),
|
||||
MovedAttribute("splitvalue", "urllib", "urllib.parse"),
|
||||
MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_params", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_query", "urlparse", "urllib.parse"),
|
||||
MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
|
||||
]
|
||||
for attr in _urllib_parse_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_parse, attr.name, attr)
|
||||
del attr
|
||||
|
||||
Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
|
||||
"moves.urllib_parse", "moves.urllib.parse")
|
||||
|
||||
|
||||
class Module_six_moves_urllib_error(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects in six.moves.urllib_error"""
|
||||
|
||||
|
||||
_urllib_error_moved_attributes = [
|
||||
MovedAttribute("URLError", "urllib2", "urllib.error"),
|
||||
MovedAttribute("HTTPError", "urllib2", "urllib.error"),
|
||||
MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
|
||||
]
|
||||
for attr in _urllib_error_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_error, attr.name, attr)
|
||||
del attr
|
||||
|
||||
Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
|
||||
"moves.urllib_error", "moves.urllib.error")
|
||||
|
||||
|
||||
class Module_six_moves_urllib_request(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects in six.moves.urllib_request"""
|
||||
|
||||
|
||||
_urllib_request_moved_attributes = [
|
||||
MovedAttribute("urlopen", "urllib2", "urllib.request"),
|
||||
MovedAttribute("install_opener", "urllib2", "urllib.request"),
|
||||
MovedAttribute("build_opener", "urllib2", "urllib.request"),
|
||||
MovedAttribute("pathname2url", "urllib", "urllib.request"),
|
||||
MovedAttribute("url2pathname", "urllib", "urllib.request"),
|
||||
MovedAttribute("getproxies", "urllib", "urllib.request"),
|
||||
MovedAttribute("Request", "urllib2", "urllib.request"),
|
||||
MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
|
||||
MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
|
||||
MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("FileHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
|
||||
MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
|
||||
MovedAttribute("urlretrieve", "urllib", "urllib.request"),
|
||||
MovedAttribute("urlcleanup", "urllib", "urllib.request"),
|
||||
MovedAttribute("URLopener", "urllib", "urllib.request"),
|
||||
MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
|
||||
MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
|
||||
MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
|
||||
MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
|
||||
]
|
||||
for attr in _urllib_request_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_request, attr.name, attr)
|
||||
del attr
|
||||
|
||||
Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
|
||||
"moves.urllib_request", "moves.urllib.request")
|
||||
|
||||
|
||||
class Module_six_moves_urllib_response(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects in six.moves.urllib_response"""
|
||||
|
||||
|
||||
_urllib_response_moved_attributes = [
|
||||
MovedAttribute("addbase", "urllib", "urllib.response"),
|
||||
MovedAttribute("addclosehook", "urllib", "urllib.response"),
|
||||
MovedAttribute("addinfo", "urllib", "urllib.response"),
|
||||
MovedAttribute("addinfourl", "urllib", "urllib.response"),
|
||||
]
|
||||
for attr in _urllib_response_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_response, attr.name, attr)
|
||||
del attr
|
||||
|
||||
Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
|
||||
"moves.urllib_response", "moves.urllib.response")
|
||||
|
||||
|
||||
class Module_six_moves_urllib_robotparser(_LazyModule):
|
||||
|
||||
"""Lazy loading of moved objects in six.moves.urllib_robotparser"""
|
||||
|
||||
|
||||
_urllib_robotparser_moved_attributes = [
|
||||
MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
|
||||
]
|
||||
for attr in _urllib_robotparser_moved_attributes:
|
||||
setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
|
||||
del attr
|
||||
|
||||
Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
|
||||
"moves.urllib_robotparser", "moves.urllib.robotparser")
|
||||
|
||||
|
||||
class Module_six_moves_urllib(types.ModuleType):
|
||||
|
||||
"""Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
|
||||
__path__ = [] # mark as package
|
||||
parse = _importer._get_module("moves.urllib_parse")
|
||||
error = _importer._get_module("moves.urllib_error")
|
||||
request = _importer._get_module("moves.urllib_request")
|
||||
response = _importer._get_module("moves.urllib_response")
|
||||
robotparser = _importer._get_module("moves.urllib_robotparser")
|
||||
|
||||
def __dir__(self):
|
||||
return ['parse', 'error', 'request', 'response', 'robotparser']
|
||||
|
||||
_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
|
||||
"moves.urllib")
|
||||
|
||||
|
||||
def add_move(move):
|
||||
"""Add an item to six.moves."""
|
||||
setattr(_MovedItems, move.name, move)
|
||||
|
||||
|
||||
def remove_move(name):
|
||||
"""Remove item from six.moves."""
|
||||
try:
|
||||
delattr(_MovedItems, name)
|
||||
except AttributeError:
|
||||
try:
|
||||
del moves.__dict__[name]
|
||||
except KeyError:
|
||||
raise AttributeError("no such move, %r" % (name,))
|
||||
|
||||
|
||||
if PY3:
|
||||
_meth_func = "__func__"
|
||||
_meth_self = "__self__"
|
||||
|
||||
_func_closure = "__closure__"
|
||||
_func_code = "__code__"
|
||||
_func_defaults = "__defaults__"
|
||||
_func_globals = "__globals__"
|
||||
else:
|
||||
_meth_func = "im_func"
|
||||
_meth_self = "im_self"
|
||||
|
||||
_func_closure = "func_closure"
|
||||
_func_code = "func_code"
|
||||
_func_defaults = "func_defaults"
|
||||
_func_globals = "func_globals"
|
||||
|
||||
|
||||
try:
|
||||
advance_iterator = next
|
||||
except NameError:
|
||||
def advance_iterator(it):
|
||||
return it.next()
|
||||
next = advance_iterator
|
||||
|
||||
|
||||
try:
|
||||
callable = callable
|
||||
except NameError:
|
||||
def callable(obj):
|
||||
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
|
||||
|
||||
|
||||
if PY3:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound
|
||||
|
||||
create_bound_method = types.MethodType
|
||||
|
||||
def create_unbound_method(func, cls):
|
||||
return func
|
||||
|
||||
Iterator = object
|
||||
else:
|
||||
def get_unbound_function(unbound):
|
||||
return unbound.im_func
|
||||
|
||||
def create_bound_method(func, obj):
|
||||
return types.MethodType(func, obj, obj.__class__)
|
||||
|
||||
def create_unbound_method(func, cls):
|
||||
return types.MethodType(func, None, cls)
|
||||
|
||||
class Iterator(object):
|
||||
|
||||
def next(self):
|
||||
return type(self).__next__(self)
|
||||
|
||||
callable = callable
|
||||
_add_doc(get_unbound_function,
|
||||
"""Get the function out of a possibly unbound function""")
|
||||
|
||||
|
||||
get_method_function = operator.attrgetter(_meth_func)
|
||||
get_method_self = operator.attrgetter(_meth_self)
|
||||
get_function_closure = operator.attrgetter(_func_closure)
|
||||
get_function_code = operator.attrgetter(_func_code)
|
||||
get_function_defaults = operator.attrgetter(_func_defaults)
|
||||
get_function_globals = operator.attrgetter(_func_globals)
|
||||
|
||||
|
||||
if PY3:
|
||||
def iterkeys(d, **kw):
|
||||
return iter(d.keys(**kw))
|
||||
|
||||
def itervalues(d, **kw):
|
||||
return iter(d.values(**kw))
|
||||
|
||||
def iteritems(d, **kw):
|
||||
return iter(d.items(**kw))
|
||||
|
||||
def iterlists(d, **kw):
|
||||
return iter(d.lists(**kw))
|
||||
|
||||
viewkeys = operator.methodcaller("keys")
|
||||
|
||||
viewvalues = operator.methodcaller("values")
|
||||
|
||||
viewitems = operator.methodcaller("items")
|
||||
else:
|
||||
def iterkeys(d, **kw):
|
||||
return d.iterkeys(**kw)
|
||||
|
||||
def itervalues(d, **kw):
|
||||
return d.itervalues(**kw)
|
||||
|
||||
def iteritems(d, **kw):
|
||||
return d.iteritems(**kw)
|
||||
|
||||
def iterlists(d, **kw):
|
||||
return d.iterlists(**kw)
|
||||
|
||||
viewkeys = operator.methodcaller("viewkeys")
|
||||
|
||||
viewvalues = operator.methodcaller("viewvalues")
|
||||
|
||||
viewitems = operator.methodcaller("viewitems")
|
||||
|
||||
_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
|
||||
_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
|
||||
_add_doc(iteritems,
|
||||
"Return an iterator over the (key, value) pairs of a dictionary.")
|
||||
_add_doc(iterlists,
|
||||
"Return an iterator over the (key, [values]) pairs of a dictionary.")
|
||||
|
||||
|
||||
if PY3:
|
||||
def b(s):
|
||||
return s.encode("latin-1")
|
||||
|
||||
def u(s):
|
||||
return s
|
||||
unichr = chr
|
||||
import struct
|
||||
int2byte = struct.Struct(">B").pack
|
||||
del struct
|
||||
byte2int = operator.itemgetter(0)
|
||||
indexbytes = operator.getitem
|
||||
iterbytes = iter
|
||||
import io
|
||||
StringIO = io.StringIO
|
||||
BytesIO = io.BytesIO
|
||||
del io
|
||||
_assertCountEqual = "assertCountEqual"
|
||||
if sys.version_info[1] <= 1:
|
||||
_assertRaisesRegex = "assertRaisesRegexp"
|
||||
_assertRegex = "assertRegexpMatches"
|
||||
_assertNotRegex = "assertNotRegexpMatches"
|
||||
else:
|
||||
_assertRaisesRegex = "assertRaisesRegex"
|
||||
_assertRegex = "assertRegex"
|
||||
_assertNotRegex = "assertNotRegex"
|
||||
else:
|
||||
def b(s):
|
||||
return s
|
||||
# Workaround for standalone backslash
|
||||
|
||||
def u(s):
|
||||
return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
|
||||
unichr = unichr
|
||||
int2byte = chr
|
||||
|
||||
def byte2int(bs):
|
||||
return ord(bs[0])
|
||||
|
||||
def indexbytes(buf, i):
|
||||
return ord(buf[i])
|
||||
iterbytes = functools.partial(itertools.imap, ord)
|
||||
import StringIO
|
||||
StringIO = BytesIO = StringIO.StringIO
|
||||
_assertCountEqual = "assertItemsEqual"
|
||||
_assertRaisesRegex = "assertRaisesRegexp"
|
||||
_assertRegex = "assertRegexpMatches"
|
||||
_assertNotRegex = "assertNotRegexpMatches"
|
||||
_add_doc(b, """Byte literal""")
|
||||
_add_doc(u, """Text literal""")
|
||||
|
||||
|
||||
def assertCountEqual(self, *args, **kwargs):
|
||||
return getattr(self, _assertCountEqual)(*args, **kwargs)
|
||||
|
||||
|
||||
def assertRaisesRegex(self, *args, **kwargs):
|
||||
return getattr(self, _assertRaisesRegex)(*args, **kwargs)
|
||||
|
||||
|
||||
def assertRegex(self, *args, **kwargs):
|
||||
return getattr(self, _assertRegex)(*args, **kwargs)
|
||||
|
||||
|
||||
def assertNotRegex(self, *args, **kwargs):
|
||||
return getattr(self, _assertNotRegex)(*args, **kwargs)
|
||||
|
||||
|
||||
if PY3:
|
||||
exec_ = getattr(moves.builtins, "exec")
|
||||
|
||||
def reraise(tp, value, tb=None):
|
||||
try:
|
||||
if value is None:
|
||||
value = tp()
|
||||
if value.__traceback__ is not tb:
|
||||
raise value.with_traceback(tb)
|
||||
raise value
|
||||
finally:
|
||||
value = None
|
||||
tb = None
|
||||
|
||||
else:
|
||||
def exec_(_code_, _globs_=None, _locs_=None):
|
||||
"""Execute code in a namespace."""
|
||||
if _globs_ is None:
|
||||
frame = sys._getframe(1)
|
||||
_globs_ = frame.f_globals
|
||||
if _locs_ is None:
|
||||
_locs_ = frame.f_locals
|
||||
del frame
|
||||
elif _locs_ is None:
|
||||
_locs_ = _globs_
|
||||
exec("""exec _code_ in _globs_, _locs_""")
|
||||
|
||||
exec_("""def reraise(tp, value, tb=None):
|
||||
try:
|
||||
raise tp, value, tb
|
||||
finally:
|
||||
tb = None
|
||||
""")
|
||||
|
||||
|
||||
if sys.version_info[:2] > (3,):
|
||||
exec_("""def raise_from(value, from_value):
|
||||
try:
|
||||
raise value from from_value
|
||||
finally:
|
||||
value = None
|
||||
""")
|
||||
else:
|
||||
def raise_from(value, from_value):
|
||||
raise value
|
||||
|
||||
|
||||
print_ = getattr(moves.builtins, "print", None)
|
||||
if print_ is None:
|
||||
def print_(*args, **kwargs):
|
||||
"""The new-style print function for Python 2.4 and 2.5."""
|
||||
fp = kwargs.pop("file", sys.stdout)
|
||||
if fp is None:
|
||||
return
|
||||
|
||||
def write(data):
|
||||
if not isinstance(data, basestring):
|
||||
data = str(data)
|
||||
# If the file has an encoding, encode unicode with it.
|
||||
if (isinstance(fp, file) and
|
||||
isinstance(data, unicode) and
|
||||
fp.encoding is not None):
|
||||
errors = getattr(fp, "errors", None)
|
||||
if errors is None:
|
||||
errors = "strict"
|
||||
data = data.encode(fp.encoding, errors)
|
||||
fp.write(data)
|
||||
want_unicode = False
|
||||
sep = kwargs.pop("sep", None)
|
||||
if sep is not None:
|
||||
if isinstance(sep, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(sep, str):
|
||||
raise TypeError("sep must be None or a string")
|
||||
end = kwargs.pop("end", None)
|
||||
if end is not None:
|
||||
if isinstance(end, unicode):
|
||||
want_unicode = True
|
||||
elif not isinstance(end, str):
|
||||
raise TypeError("end must be None or a string")
|
||||
if kwargs:
|
||||
raise TypeError("invalid keyword arguments to print()")
|
||||
if not want_unicode:
|
||||
for arg in args:
|
||||
if isinstance(arg, unicode):
|
||||
want_unicode = True
|
||||
break
|
||||
if want_unicode:
|
||||
newline = unicode("\n")
|
||||
space = unicode(" ")
|
||||
else:
|
||||
newline = "\n"
|
||||
space = " "
|
||||
if sep is None:
|
||||
sep = space
|
||||
if end is None:
|
||||
end = newline
|
||||
for i, arg in enumerate(args):
|
||||
if i:
|
||||
write(sep)
|
||||
write(arg)
|
||||
write(end)
|
||||
if sys.version_info[:2] < (3, 3):
|
||||
_print = print_
|
||||
|
||||
def print_(*args, **kwargs):
|
||||
fp = kwargs.get("file", sys.stdout)
|
||||
flush = kwargs.pop("flush", False)
|
||||
_print(*args, **kwargs)
|
||||
if flush and fp is not None:
|
||||
fp.flush()
|
||||
|
||||
_add_doc(reraise, """Reraise an exception.""")
|
||||
|
||||
if sys.version_info[0:2] < (3, 4):
|
||||
# This does exactly the same what the :func:`py3:functools.update_wrapper`
|
||||
# function does on Python versions after 3.2. It sets the ``__wrapped__``
|
||||
# attribute on ``wrapper`` object and it doesn't raise an error if any of
|
||||
# the attributes mentioned in ``assigned`` and ``updated`` are missing on
|
||||
# ``wrapped`` object.
|
||||
def _update_wrapper(wrapper, wrapped,
|
||||
assigned=functools.WRAPPER_ASSIGNMENTS,
|
||||
updated=functools.WRAPPER_UPDATES):
|
||||
for attr in assigned:
|
||||
try:
|
||||
value = getattr(wrapped, attr)
|
||||
except AttributeError:
|
||||
continue
|
||||
else:
|
||||
setattr(wrapper, attr, value)
|
||||
for attr in updated:
|
||||
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
|
||||
wrapper.__wrapped__ = wrapped
|
||||
return wrapper
|
||||
_update_wrapper.__doc__ = functools.update_wrapper.__doc__
|
||||
|
||||
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
|
||||
updated=functools.WRAPPER_UPDATES):
|
||||
return functools.partial(_update_wrapper, wrapped=wrapped,
|
||||
assigned=assigned, updated=updated)
|
||||
wraps.__doc__ = functools.wraps.__doc__
|
||||
|
||||
else:
|
||||
wraps = functools.wraps
|
||||
|
||||
|
||||
def with_metaclass(meta, *bases):
|
||||
"""Create a base class with a metaclass."""
|
||||
# This requires a bit of explanation: the basic idea is to make a dummy
|
||||
# metaclass for one level of class instantiation that replaces itself with
|
||||
# the actual metaclass.
|
||||
class metaclass(type):
|
||||
|
||||
def __new__(cls, name, this_bases, d):
|
||||
if sys.version_info[:2] >= (3, 7):
|
||||
# This version introduced PEP 560 that requires a bit
|
||||
# of extra care (we mimic what is done by __build_class__).
|
||||
resolved_bases = types.resolve_bases(bases)
|
||||
if resolved_bases is not bases:
|
||||
d['__orig_bases__'] = bases
|
||||
else:
|
||||
resolved_bases = bases
|
||||
return meta(name, resolved_bases, d)
|
||||
|
||||
@classmethod
|
||||
def __prepare__(cls, name, this_bases):
|
||||
return meta.__prepare__(name, bases)
|
||||
return type.__new__(metaclass, 'temporary_class', (), {})
|
||||
|
||||
|
||||
def add_metaclass(metaclass):
|
||||
"""Class decorator for creating a class with a metaclass."""
|
||||
def wrapper(cls):
|
||||
orig_vars = cls.__dict__.copy()
|
||||
slots = orig_vars.get('__slots__')
|
||||
if slots is not None:
|
||||
if isinstance(slots, str):
|
||||
slots = [slots]
|
||||
for slots_var in slots:
|
||||
orig_vars.pop(slots_var)
|
||||
orig_vars.pop('__dict__', None)
|
||||
orig_vars.pop('__weakref__', None)
|
||||
if hasattr(cls, '__qualname__'):
|
||||
orig_vars['__qualname__'] = cls.__qualname__
|
||||
return metaclass(cls.__name__, cls.__bases__, orig_vars)
|
||||
return wrapper
|
||||
|
||||
|
||||
def ensure_binary(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce **s** to six.binary_type.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> encoded to `str`
|
||||
- `str` -> `str`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> encoded to `bytes`
|
||||
- `bytes` -> `bytes`
|
||||
"""
|
||||
if isinstance(s, text_type):
|
||||
return s.encode(encoding, errors)
|
||||
elif isinstance(s, binary_type):
|
||||
return s
|
||||
else:
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
|
||||
|
||||
def ensure_str(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce *s* to `str`.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> encoded to `str`
|
||||
- `str` -> `str`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> `str`
|
||||
- `bytes` -> decoded to `str`
|
||||
"""
|
||||
if not isinstance(s, (text_type, binary_type)):
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
if PY2 and isinstance(s, text_type):
|
||||
s = s.encode(encoding, errors)
|
||||
elif PY3 and isinstance(s, binary_type):
|
||||
s = s.decode(encoding, errors)
|
||||
return s
|
||||
|
||||
|
||||
def ensure_text(s, encoding='utf-8', errors='strict'):
|
||||
"""Coerce *s* to six.text_type.
|
||||
|
||||
For Python 2:
|
||||
- `unicode` -> `unicode`
|
||||
- `str` -> `unicode`
|
||||
|
||||
For Python 3:
|
||||
- `str` -> `str`
|
||||
- `bytes` -> decoded to `str`
|
||||
"""
|
||||
if isinstance(s, binary_type):
|
||||
return s.decode(encoding, errors)
|
||||
elif isinstance(s, text_type):
|
||||
return s
|
||||
else:
|
||||
raise TypeError("not expecting type '%s'" % type(s))
|
||||
|
||||
|
||||
def python_2_unicode_compatible(klass):
|
||||
"""
|
||||
A class decorator that defines __unicode__ and __str__ methods under Python 2.
|
||||
Under Python 3 it does nothing.
|
||||
|
||||
To support Python 2 and 3 with a single code base, define a __str__ method
|
||||
returning text and apply this decorator to the class.
|
||||
"""
|
||||
if PY2:
|
||||
if '__str__' not in klass.__dict__:
|
||||
raise ValueError("@python_2_unicode_compatible cannot be applied "
|
||||
"to %s because it doesn't define __str__()." %
|
||||
klass.__name__)
|
||||
klass.__unicode__ = klass.__str__
|
||||
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
|
||||
return klass
|
||||
|
||||
|
||||
# Complete the moves implementation.
|
||||
# This code is at the end of this module to speed up module loading.
|
||||
# Turn this module into a package.
|
||||
__path__ = [] # required for PEP 302 and PEP 451
|
||||
__package__ = __name__ # see PEP 366 @ReservedAssignment
|
||||
if globals().get("__spec__") is not None:
|
||||
__spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
|
||||
# Remove other six meta path importers, since they cause problems. This can
|
||||
# happen if six is removed from sys.modules and then reloaded. (Setuptools does
|
||||
# this for some reason.)
|
||||
if sys.meta_path:
|
||||
for i, importer in enumerate(sys.meta_path):
|
||||
# Here's some real nastiness: Another "instance" of the six module might
|
||||
# be floating around. Therefore, we can't use isinstance() to check for
|
||||
# the six meta path importer, since the other six instance will have
|
||||
# inserted an importer with different class.
|
||||
if (type(importer).__name__ == "_SixMetaPathImporter" and
|
||||
importer.name == __name__):
|
||||
del sys.meta_path[i]
|
||||
break
|
||||
del i, importer
|
||||
# Finally, add the importer to the meta path import hook.
|
||||
sys.meta_path.append(_importer)
|
||||
Vendored
-53
@@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
#
|
||||
# Copyright 2011-2015 Splunk, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import app
|
||||
import os,sys
|
||||
import requests
|
||||
|
||||
from splunklib.searchcommands import dispatch, StreamingCommand, Configuration, validators, Option
|
||||
from splunklib.searchcommands.validators import Code
|
||||
|
||||
@Configuration()
|
||||
class WgetCommand(StreamingCommand):
|
||||
""" Call wget from url in data.
|
||||
##Syntax
|
||||
.. code-block::
|
||||
wget output=<field> <field-list>
|
||||
##Description
|
||||
The :code:`wget` command calls a url which is present in a field.
|
||||
##Example
|
||||
tbd
|
||||
"""
|
||||
|
||||
output = Option(
|
||||
doc='''
|
||||
**Syntax:** **output=***<output>*
|
||||
**Description:** Name of the field that will hold the return data''',
|
||||
require=True, validate=validators.Fieldname())
|
||||
|
||||
def stream(self, records):
|
||||
self.logger.debug('WgetCommand: %s', self) # logs command line
|
||||
fieldnames = self.fieldnames
|
||||
|
||||
for record in records:
|
||||
for fieldname in fieldnames:
|
||||
r = requests.get(record[fieldname])
|
||||
record[self.output] = r.json()
|
||||
yield record
|
||||
|
||||
dispatch(WgetCommand, sys.argv, sys.stdin, sys.stdout, __name__)
|
||||
@@ -1,3 +0,0 @@
|
||||
### Deprecated since ESCU UI was deprecated and this conf file is no longer in use
|
||||
|
||||
### Using one single file analyticstories.conf that will be used both by ES and ESCU
|
||||
Vendored
-24
@@ -1,24 +0,0 @@
|
||||
#
|
||||
# Splunk app configuration file
|
||||
#
|
||||
|
||||
[install]
|
||||
is_configured = 0
|
||||
|
||||
[ui]
|
||||
is_visible = 1
|
||||
label = Dev Sec Ops Analytics
|
||||
|
||||
[triggers]
|
||||
reload.analytic_stories = simple
|
||||
reload.analyticstories = simple
|
||||
reload.es_investigations = simple
|
||||
reload.use_case_library = simple
|
||||
|
||||
[launcher]
|
||||
author = Splunk Threat Research Team
|
||||
description =
|
||||
version = 1.0.0
|
||||
|
||||
[package]
|
||||
check_for_updates = 0
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
#############
|
||||
# Automatically generated by generator.py in splunk/security_content
|
||||
# On Date: 2021-09-13T10:57:27 UTC
|
||||
# Author: Splunk Security Research
|
||||
# Contact: research@splunk.com
|
||||
#############
|
||||
|
||||
[api_call_by_user_baseline]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[cloud_instances_enough_data]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_api_calls_per_user_role]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_compute_creations_by_user]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_compute_images]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_compute_instance_types]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_instance_modifications_by_user]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_provisioning_activity_sources]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_cloud_regions]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_running_windows_services]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[previously_seen_users_console_logins]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
[zoom_first_time_child_process]
|
||||
enforceTypes = false
|
||||
replicate = false
|
||||
|
||||
Vendored
-10
@@ -1,10 +0,0 @@
|
||||
[wget]
|
||||
filename = wget.py
|
||||
run_in_preview = false
|
||||
outputheader = true
|
||||
enableheader = true
|
||||
requires_srinfo = true
|
||||
supports_getinfo = true
|
||||
supports_multivalues = true
|
||||
supports_rawargs = true
|
||||
python.version = python3
|
||||
@@ -1,8 +0,0 @@
|
||||
<nav search_view="search">
|
||||
<view name="analytics" default='true' />
|
||||
<view name="user_analytics" />
|
||||
<view name="repository_analytics" />
|
||||
<view name="dev_sec_ops_analytics" />
|
||||
<view name="search" />
|
||||
<view name="dashboards" />
|
||||
</nav>
|
||||
-1
@@ -1 +0,0 @@
|
||||
Add all the views that your app needs in this directory
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-10
@@ -1,10 +0,0 @@
|
||||
|
||||
[panel_group://workbench_panel_group_dev_sec_ops]
|
||||
label = Dev Sec Ops
|
||||
description = This story is focused around detecting attacks on a DevSecOps lifeccycle which consists of the phases plan, code, build, test, release, deploy, operate and monitor.
|
||||
disabled = 0
|
||||
|
||||
panels = ["panel://workbench_panel_get_notable_history___response_task"]
|
||||
|
||||
|
||||
|
||||
Vendored
-449
@@ -1,449 +0,0 @@
|
||||
#############
|
||||
# Automatically generated by generator.py in splunk/security_content
|
||||
# On Date: 2021-09-13T10:57:27 UTC
|
||||
# Author: Splunk Security Research
|
||||
# Contact: research@splunk.com
|
||||
#############
|
||||
|
||||
|
||||
[aws_cloudwatchlogs_eks]
|
||||
definition = sourcetype="aws:cloudwatchlogs:eks"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_config]
|
||||
definition = sourcetype=aws:config
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_description]
|
||||
definition = sourcetype="aws:description"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_ecr_users]
|
||||
definition = userName IN (user)
|
||||
description = specify the user allowed to push Images to AWS ECR.
|
||||
|
||||
[aws_s3_accesslogs]
|
||||
definition = sourcetype=aws:s3:accesslogs
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_securityhub_finding]
|
||||
definition = sourcetype="aws:securityhub:finding"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_securityhub_firehose]
|
||||
definition = sourcetype="aws:securityhub:firehose"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[brand_abuse_dns]
|
||||
definition = lookup update=true brandMonitoring_lookup domain as query OUTPUT domain_abuse | search domain_abuse=true
|
||||
description = This macro limits the output to only domains that are in the brand monitoring lookup file
|
||||
|
||||
[brand_abuse_email]
|
||||
definition = lookup update=true brandMonitoring_lookup domain as src_user OUTPUT domain_abuse | search domain_abuse=true
|
||||
description = This macro limits the output to only domains that are in the brand monitoring lookup file
|
||||
|
||||
[brand_abuse_web]
|
||||
definition = lookup update=true brandMonitoring_lookup domain as urls OUTPUT domain_abuse | search domain_abuse=true
|
||||
description = This macro limits the output to only domains that are in the brand monitoring lookup file
|
||||
|
||||
[circleci]
|
||||
definition = sourcetype=circleci
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[cisco_networks]
|
||||
definition = eventtype=cisco_ios
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[cloud_api_calls_from_previously_unseen_user_roles_activity_window]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far back you should be checking for new commands from user roles
|
||||
|
||||
[cloudtrail]
|
||||
definition = sourcetype=aws:cloudtrail
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[cloudwatch_eks]
|
||||
definition = sourcetype="aws:cloudwatchlogs:eks"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for AWS cloudwatch eks logs. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[cloudwatch_vpc]
|
||||
definition = sourcetype=aws:cloudwatchlogs:vpcflow
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for AWS cloudwatch vpc logs. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[cloudwatchlogs_vpcflow]
|
||||
definition = sourcetype=aws:cloudwatchlogs:vpcflow
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[dynamic_dns_providers]
|
||||
definition = lookup update=true dynamic_dns_providers_default dynamic_dns_domains as query OUTPUTNEW isDynDNS_default | lookup update=true dynamic_dns_providers_local dynamic_dns_domains as query OUTPUTNEW isDynDNS_local| eval isDynDNS = coalesce(isDynDNS_default, isDynDNS_local)|fields - isDynDNS_default, isDynDNS_local| search isDynDNS=True
|
||||
description = This macro limits the output of the query field to dynamic dns domains. It looks up the domains in a file provided by Splunk and one intended to be updated by the end user.
|
||||
|
||||
[dynamic_dns_web_traffic]
|
||||
definition = lookup update=true dynamic_dns_providers_default dynamic_dns_domains as url OUTPUTNEW isDynDNS_default | lookup update=true dynamic_dns_providers_local dynamic_dns_domains as url OUTPUTNEW isDynDNS_local| eval isDynDNS = coalesce(isDynDNS_default, isDynDNS_local)|fields - isDynDNS_default, isDynDNS_local| search isDynDNS=True
|
||||
description = This is a description
|
||||
|
||||
[ec2_modification_api_calls]
|
||||
definition = (eventName=AssociateAddress OR eventName=AssociateIamInstanceProfile OR eventName=AttachClassicLinkVpc OR eventName=AttachNetworkInterface OR eventName=AttachVolume OR eventName=BundleInstance OR eventName=DetachClassicLinkVpc OR eventName=DetachVolume OR eventName=ModifyInstanceAttribute OR eventName=ModifyInstancePlacement OR eventName=MonitorInstances OR eventName=RebootInstances OR eventName=ResetInstanceAttribute OR eventName=StartInstances OR eventName=StopInstances OR eventName=TerminateInstances OR eventName=UnmonitorInstances)
|
||||
description = This is a list of AWS event names that have to do with modifying Amazon EC2 instances
|
||||
|
||||
[evilginx_phishlets_0365]
|
||||
definition = (query=login* AND query=www*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as Office 365
|
||||
|
||||
[evilginx_phishlets_amazon]
|
||||
definition = (query=fls-na* AND query = www* AND query=images*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as Amazon
|
||||
|
||||
[evilginx_phishlets_aws]
|
||||
definition = (query=www* AND query=aws* AND query=console.aws* AND query=signin.aws* AND api-northeast-1.console.aws* AND query=fls-na* AND query=images-na*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as an AWS console
|
||||
|
||||
[evilginx_phishlets_facebook]
|
||||
definition = (query=www* AND query = m* AND query=static*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as FaceBook
|
||||
|
||||
[evilginx_phishlets_github]
|
||||
definition = (query=api* AND query = github*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as GitHub
|
||||
|
||||
[evilginx_phishlets_google]
|
||||
definition = (query=accounts* AND query=ssl* AND query=www*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as Google
|
||||
|
||||
[evilginx_phishlets_outlook]
|
||||
definition = (query=outlook* AND query=login* AND query=account*)
|
||||
description = This limits the query fields to domains that are associated with evilginx masquerading as Outlook
|
||||
|
||||
[exchange]
|
||||
definition = sourcetype="MSWindows:IIS"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[f5_bigip_rogue]
|
||||
definition = index=netops sourcetype="f5:bigip:rogue"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[filter_rare_process_allow_list]
|
||||
definition = lookup update=true lookup_rare_process_allow_list_default process as process OUTPUTNEW allow_list | where allow_list="false" | lookup update=true lookup_rare_process_allow_list_local process as process OUTPUT allow_list | where allow_list="false"
|
||||
description = This macro is intended to allow_list processes that have been definied as rare
|
||||
|
||||
[github]
|
||||
definition = sourcetype=aws:firehose:json
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[github_known_users]
|
||||
definition = user IN (user_names_here)
|
||||
description = specify the user allowed to create PRs in Github projects.
|
||||
|
||||
[google_gcp_pubnet_message]
|
||||
definition = sourcetype="google:gcp:pubsub:message"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for Google GCP. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[google_gcp_pubsub_message]
|
||||
definition = sourcetype="google:gcp:pubsub:message"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[gsuite_drive]
|
||||
definition = sourcetype=gsuite:drive:json
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[gsuite_gmail]
|
||||
definition = sourcetype=gsuite:gmail:bigquery
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[is_windows_system_file]
|
||||
definition = lookup update=true is_windows_system_file filename as process_name OUTPUT systemFile | search systemFile=true
|
||||
description = This macro limits the output to process names that are in the Windows System directory
|
||||
|
||||
[kube_objects_events]
|
||||
definition = sourcetype=kube:objects:events
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[kubernetes_azure]
|
||||
definition = sourcetype=mscs:storage:blob:json
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for Kubernetes data from Azure. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[kubernetes_container_controller]
|
||||
definition = sourcetype=kube:container:controller
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for Kubernetes data. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[linux_hosts]
|
||||
definition = index=*
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[netbackup]
|
||||
definition = sourcetype="netbackup_logs"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[network_acl_events]
|
||||
definition = (eventName = CreateNetworkAcl OR eventName = CreateNetworkAclEntry OR eventName = DeleteNetworkAcl OR eventName = DeleteNetworkAclEntry OR eventName = ReplaceNetworkAclEntry OR eventName = ReplaceNetworkAclAssociation)
|
||||
description = This is a list of AWS event names that are associated with Network ACLs
|
||||
|
||||
[notable]
|
||||
definition = index=notable
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[o365_management_activity]
|
||||
definition = sourcetype=o365:management:activity
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[okta]
|
||||
definition = eventtype=okta_log
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[osquery_process]
|
||||
definition = eventtype="osquery-process"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[powershell]
|
||||
definition = (source=WinEventLog:Microsoft-Windows-PowerShell/Operational OR source="XmlWinEventLog:Microsoft-Windows-PowerShell/Operational")
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[previously_seen_cloud_api_calls_per_user_role_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of cloud api calls per user role
|
||||
|
||||
[previously_seen_cloud_compute_creations_by_user_search_window_begin_offset]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far into the past the window should be to determine if the user is new or not
|
||||
|
||||
[previously_seen_cloud_compute_image_search_window_begin_offset]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far into the past the window should be to determine if the image is new or not
|
||||
|
||||
[previously_seen_cloud_compute_images_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of cloud instance images
|
||||
|
||||
[previously_seen_cloud_compute_instance_type_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of cloud instance types
|
||||
|
||||
[previously_seen_cloud_compute_instance_types_search_window_begin_offset]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far into the past the window should be to determine if the instance type is new or not
|
||||
|
||||
[previously_seen_cloud_instance_modifications_by_user_search_window_begin_offset]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far into the past the window should be to determine if the user is new or not
|
||||
|
||||
[previously_seen_cloud_provisioning_activity_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of cloud provisioning locations
|
||||
|
||||
[previously_seen_cloud_region_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of cloud regions
|
||||
|
||||
[previously_seen_cloud_regions_search_window_begin_offset]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far into the past the window should be to determine if the region is new or not
|
||||
|
||||
[previously_seen_windows_services_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of Windows services
|
||||
|
||||
[previously_seen_windows_services_window]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far back you should be checking for new Windows services
|
||||
|
||||
[previously_seen_zoom_child_processes_forget_window]
|
||||
definition = "-90d@d"
|
||||
description = Use this macro to determine how long to keep track of zoom child processes
|
||||
|
||||
[previously_seen_zoom_child_processes_window]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far back you should be checking for new zoom child processes
|
||||
|
||||
[previously_unseen_cloud_provisioning_activity_window]
|
||||
definition = "-70m@m"
|
||||
description = Use this macro to determine how far back you should be checking for new provisioning activities
|
||||
|
||||
[printservice]
|
||||
definition = source="wineventlog:microsoft-windows-printservice/operational" OR sourcetype="WinEventLog:Microsoft-Windows-PrintService/Admin"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[process_esentutl]
|
||||
definition = (Processes.process_name=esentutl.exe OR Processes.original_file_name=esentutl.exe)
|
||||
description = Matches the process with its original file name, data for this macro came from https://strontic.github.io/
|
||||
|
||||
[prohibited_apps_launching_cmd]
|
||||
definition = | inputlookup prohibited_apps_launching_cmd | rename prohibited_applications as parent_process_name | eval parent_process_name="*" . parent_process_name | table parent_process_name
|
||||
description = This macro outputs a list of process that should not be the parent process of cmd.exe
|
||||
|
||||
[prohibited_softwares]
|
||||
definition = lookup prohibited_softwares app as process_name OUTPUT is_prohibited | search is_prohibited=True
|
||||
description = This macro limits the output to process_names that have been marked as prohibited
|
||||
|
||||
[ransomware_extensions]
|
||||
definition = lookup update=true ransomware_extensions_lookup Extensions AS file_extension OUTPUT Name | search Name !=False
|
||||
description = This macro limits the output to files that have extensions associated with ransomware
|
||||
|
||||
[ransomware_notes]
|
||||
definition = lookup ransomware_notes_lookup ransomware_notes as file_name OUTPUT status as "Known Ransomware Notes" | search "Known Ransomware Notes"=True
|
||||
description = This macro limits the output to files that have been identified as a ransomware note
|
||||
|
||||
[remove_valid_domains]
|
||||
definition = eval domain=trim(domain,"*") | search NOT[| inputlookup domains] NOT[ |inputlookup cim_corporate_email_domain_lookup] NOT[inputlookup cim_corporate_web_domain_lookup] | eval domain="*"+domain+"*"
|
||||
description = This macro removes valid domains from the output
|
||||
|
||||
[s3_accesslogs]
|
||||
definition = sourcetype=aws:s3:accesslogs
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype) for AWS cloudwatch vpc logs. Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[security_content_ctime(1)]
|
||||
args = field
|
||||
definition = convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
|
||||
description = convert epoch time to string
|
||||
|
||||
[security_content_summariesonly]
|
||||
definition = summariesonly=false allow_old_summaries=true
|
||||
description = search data model's summaries only
|
||||
|
||||
[security_group_api_calls]
|
||||
definition = (eventName=AuthorizeSecurityGroupIngress OR eventName=CreateSecurityGroup OR eventName=DeleteSecurityGroup OR eventName=DescribeClusterSecurityGroups OR eventName=DescribeDBSecurityGroups OR eventName=DescribeSecurityGroupReferences OR eventName=DescribeSecurityGroups OR eventName=DescribeStaleSecurityGroups OR eventName=RevokeSecurityGroupIngress OR eventName=UpdateSecurityGroupRuleDescriptionsIngress)
|
||||
description = This macro is a list of AWS event names associated with security groups
|
||||
|
||||
[signals]
|
||||
definition = index=signals
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[stream_dns]
|
||||
definition = sourcetype=stream:dns
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[stream_http]
|
||||
definition = sourcetype=stream:http
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[stream_tcp]
|
||||
definition = sourcetype=stream:tcp
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[suspicious_email_attachments]
|
||||
definition = lookup update=true is_suspicious_file_extension_lookup file_name OUTPUT suspicious | search suspicious=true
|
||||
description = This macro limits the output to email attachments that have suspicious extensions
|
||||
|
||||
[suspicious_writes]
|
||||
definition = lookup suspicious_writes_lookup file as file_name OUTPUT note as "Reference" | search "Reference" != False
|
||||
description = This macro limites the output to file names that have been marked as suspicious
|
||||
|
||||
[sysmon]
|
||||
definition = sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational OR source=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[system_network_configuration_discovery_tools]
|
||||
definition = (process_name= "arp.exe" OR process_name= "at.exe" OR process_name= "attrib.exe" OR process_name= "cscript.exe" OR process_name= "dsquery.exe" OR process_name= "hostname.exe" OR process_name= "ipconfig.exe" OR process_name= "mimikatz.exe" OR process_name= "nbstat.exe" OR process_name= "net.exe" OR process_name= "netsh.exe" OR process_name= "nslookup.exe" OR process_name= "ping.exe" OR process_name= "quser.exe" OR process_name= "qwinsta.exe" OR process_name= "reg.exe" OR process_name= "runas.exe" OR process_name= "sc.exe" OR process_name= "schtasks.exe" OR process_name= "ssh.exe" OR process_name= "systeminfo.exe" OR process_name= "taskkill.exe" OR process_name= "telnet.exe" OR process_name= "tracert.exe" OR process_name="wscript.exe" OR process_name= "xcopy.exe")
|
||||
description = This macro is a list of process that can be used to discover the network configuration
|
||||
|
||||
[uncommon_processes]
|
||||
definition = lookup update=true lookup_uncommon_processes_default process_name as process_name outputnew uncommon_default,category_default,analytic_story_default,kill_chain_phase_default,mitre_attack_default | lookup update=true lookup_uncommon_processes_local process_name as process_name outputnew uncommon_local,category_local,analytic_story_local,kill_chain_phase_local,mitre_attack_local | eval uncommon = coalesce(uncommon_default, uncommon_local), analytic_story = coalesce(analytic_story_default, analytic_story_local), category=coalesce(category_default, category_local), kill_chain_phase=coalesce(kill_chain_phase_default, kill_chain_phase_local), mitre_attack=coalesce(mitre_attack_default, mitre_attack_local) | fields - analytic_story_default, analytic_story_local, category_default, category_local, kill_chain_phase_default, kill_chain_phase_local, mitre_attack_default, mitre_attack_local, uncommon_default, uncommon_local | search uncommon=true
|
||||
description = This macro limits the output to processes that have been marked as uncommon
|
||||
|
||||
[wineventlog_security]
|
||||
definition = eventtype=wineventlog_security
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[wineventlog_system]
|
||||
definition = eventtype=wineventlog_system
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[wmi]
|
||||
definition = sourcetype="wineventlog:microsoft-windows-wmi-activity/operational"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[zeek_rpc]
|
||||
definition = index=zeek sourcetype="zeek:rpc:json"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[zeek_ssl]
|
||||
definition = index=zeek sourcetype="zeek:ssl:json"
|
||||
description = customer specific splunk configurations(eg- index, source, sourcetype). Replace the macro definition with configurations for your Splunk Environmnent.
|
||||
|
||||
[aws_ecr_container_scanning_findings_high_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[aws_ecr_container_scanning_findings_low_informational_unknown_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[aws_ecr_container_scanning_findings_medium_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[aws_ecr_container_upload_outside_business_hours_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[aws_ecr_container_upload_unknown_user_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[circle_ci_disable_security_job_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[circle_ci_disable_security_step_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[correlation_by_repository_and_risk_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[correlation_by_user_and_risk_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_email_suspicious_attachment_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[github_dependabot_alert_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[github_pull_request_from_unknown_user_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[github_commit_changes_in_master_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[github_commit_in_develop_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_drive_share_in_external_email_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_email_suspicious_subject_with_attachment_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_email_with_known_abuse_web_service_link_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_outbound_email_with_attachment_to_external_domain_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[gsuite_suspicious_shared_file_name_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[kubernetes_nginx_ingress_lfi_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[kubernetes_nginx_ingress_rfi_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
[kubernetes_scanner_image_pulling_filter]
|
||||
definition = search *
|
||||
description = Update this macro to limit the output results to filter out false positives.
|
||||
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
[MODIFIED-stash]
|
||||
lookup_image_to_repository = images_to_repository image OUTPUT repository
|
||||
-1055
File diff suppressed because it is too large
Load Diff
-4
@@ -1,4 +0,0 @@
|
||||
[wget-command]
|
||||
syntax = [wget]
|
||||
shortdesc = [run wget on a given url]
|
||||
usage = public
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
#############
|
||||
# Automatically generated by generator.py in splunk/security_content
|
||||
# On Date: 2021-09-13T10:57:27 UTC
|
||||
# Author: Splunk Security Research
|
||||
# Contact: research@splunk.com
|
||||
#############
|
||||
|
||||
[api_call_by_user_baseline]
|
||||
collection = api_call_by_user_baseline
|
||||
external_type = kvstore
|
||||
# description = A collection that will contain the baseline information for number of AWS API calls per user
|
||||
fields_list = arn, latestCount, numDataPoints, avgApiCalls, stdevApiCalls
|
||||
|
||||
[attacker_tools]
|
||||
filename = attacker_tools.csv
|
||||
default_match = false
|
||||
case_sensitive_match = false
|
||||
# description = A list of tools used by attackers
|
||||
match_type = WILDCARD(attacker_tool_names)
|
||||
min_matches = 1
|
||||
|
||||
[aws_service_accounts]
|
||||
filename = aws_service_accounts.csv
|
||||
# description = A lookup file that will contain AWS Service accounts
|
||||
|
||||
[baseline_blocked_outbound_connections]
|
||||
filename = baseline_blocked_outbound_connections.csv
|
||||
# description = A lookup file that will contain the baseline information for number of blocked outbound connections
|
||||
|
||||
[brandMonitoring_lookup]
|
||||
filename = brand_monitoring.csv
|
||||
default_match = false
|
||||
# description = A file that contains look-a-like domains for brands that you want to monitor
|
||||
match_type = WILDCARD(domain)
|
||||
min_matches = 1
|
||||
|
||||
[cloud_instances_enough_data]
|
||||
collection = cloud_instances_enough_data
|
||||
external_type = kvstore
|
||||
default_match = false
|
||||
# description = A lookup to determine if you have a sufficient amount of time has passed to collect cloud instance data for behavioral searches
|
||||
match_type = WILDCARD(filter)
|
||||
fields_list = _key, filter, enough_data
|
||||
|
||||
[csc_lookup]
|
||||
filename = csc_lookup.csv
|
||||
# description = The CSC control numbers and names
|
||||
min_matches = 1
|
||||
|
||||
[discovered_dns_records]
|
||||
filename = discovered_dns_records.csv
|
||||
default_match = false
|
||||
# description = A placeholder for a list of discovered DNS records generated by the baseline discover_dns_records
|
||||
min_matches = 1
|
||||
|
||||
[domains]
|
||||
filename = domains.csv
|
||||
# description = A list of domains that can be ignored
|
||||
|
||||
[dynamic_dns_providers_default]
|
||||
filename = dynamic_dns_providers_default.csv
|
||||
case_sensitive_match = false
|
||||
# description = A list of dynammic dns providers that should not be modified
|
||||
match_type = WILDCARD(dynamic_dns_domains)
|
||||
|
||||
[dynamic_dns_providers_local]
|
||||
filename = dynamic_dns_providers_local.csv
|
||||
case_sensitive_match = false
|
||||
# description = A list of dynammic dns providers that can be modified
|
||||
match_type = WILDCARD(dynamic_dns_domains)
|
||||
|
||||
[escu_search_id_lookup]
|
||||
filename = escu_search_id.csv
|
||||
# description = A placeholder lookup file to hold information for ESCU Usage dashboard
|
||||
|
||||
[images_to_repository]
|
||||
filename = images_to_repository.csv
|
||||
# description = Mapping images to repositories
|
||||
|
||||
[is_suspicious_file_extension_lookup]
|
||||
filename = is_suspicious_file_extension_lookup.csv
|
||||
# description = A list of suspicious extensions for email attachments
|
||||
match_type = WILDCARD(file_name)
|
||||
|
||||
[is_windows_system_file]
|
||||
filename = is_windows_system_file.csv
|
||||
default_match = false
|
||||
# description = A full baseline of executable files in Windows\System32 and Windows\Syswow64, including sub-directories from Server 2016 and Windows 10.
|
||||
min_matches = 1
|
||||
|
||||
[legit_domains]
|
||||
filename = legit_domains.csv
|
||||
# description = A list of legit domains to be used as an ignore list for possible phishing sites
|
||||
|
||||
[local_file_inclusion_paths]
|
||||
filename = local_file_inclusion_paths.csv
|
||||
default_match = false
|
||||
case_sensitive_match = false
|
||||
# description = A list of interesting files in a local file inclusion attack
|
||||
match_type = WILDCARD(local_file_inclusion_paths)
|
||||
min_matches = 1
|
||||
|
||||
[lookup_rare_process_allow_list_default]
|
||||
filename = rare_process_allow_list_default.csv
|
||||
default_match = false
|
||||
case_sensitive_match = false
|
||||
# description = A list of rare processes that are legitimate that is provided by Splunk
|
||||
match_type = WILDCARD(process)
|
||||
min_matches = 1
|
||||
|
||||
[lookup_rare_process_allow_list_local]
|
||||
filename = rare_process_allow_list_local.csv
|
||||
default_match = false
|
||||
case_sensitive_match = false
|
||||
# description = A list of rare processes that are legitimate provided by the end user
|
||||
match_type = WILDCARD(process)
|
||||
min_matches = 1
|
||||
|
||||
[lookup_uncommon_processes_default]
|
||||
filename = uncommon_processes_default.csv
|
||||
case_sensitive_match = false
|
||||
# description = A list of processes that are not common
|
||||
match_type = WILDCARD(process)
|
||||
|
||||
[lookup_uncommon_processes_local]
|
||||
filename = uncommon_processes_local.csv
|
||||
case_sensitive_match = false
|
||||
# description = A list of processes that are not common
|
||||
match_type = WILDCARD(process)
|
||||
|
||||
[mandatory_job_for_workflow]
|
||||
filename = mandatory_job_for_workflow.csv
|
||||
# description = A lookup file that will be used to define the mandatory job for workflow
|
||||
|
||||
[mandatory_step_for_job]
|
||||
filename = mandatory_step_for_job.csv
|
||||
# description = A lookup file that will be used to define the mandatory step for job
|
||||
|
||||
[network_acl_activity_baseline]
|
||||
filename = network_acl_activity_baseline.csv
|
||||
# description = A lookup file that will contain the baseline information for number of AWS Network ACL Activity
|
||||
|
||||
[previously_seen_S3_access_from_remote_ip]
|
||||
filename = previously_seen_S3_access_from_remote_ip.csv
|
||||
# description = A placeholder for a list of IPs that have access S3
|
||||
|
||||
[previously_seen_api_calls_from_user_roles]
|
||||
filename = previously_seen_api_calls_from_user_roles.csv
|
||||
# description = A placeholder for a list of AWS API calls for each user role
|
||||
|
||||
[previously_seen_aws_cross_account_activity]
|
||||
filename = previously_seen_aws_cross_account_activity.csv
|
||||
# description = A placeholder for a list of AWS accounts and assumed roles
|
||||
|
||||
[previously_seen_aws_regions]
|
||||
filename = previously_seen_aws_regions.csv
|
||||
default_match = false
|
||||
# description = A place holder for a list of used AWS regions
|
||||
min_matches = 1
|
||||
|
||||
[previously_seen_cloud_api_calls_per_user_role]
|
||||
collection = previously_seen_cloud_api_calls_per_user_role
|
||||
external_type = kvstore
|
||||
# description = A table of users, commands, and the first and last time that they have been seen
|
||||
fields_list = _key, user, command, firstTimeSeen, lastTimeSeen, enough_data
|
||||
|
||||
[previously_seen_cloud_compute_creations_by_user]
|
||||
collection = previously_seen_cloud_compute_creations_by_user
|
||||
external_type = kvstore
|
||||
# description = A table of previously seen users creating cloud instances
|
||||
fields_list = _key, firstTimeSeen, lastTimeSeen, user, enough_data
|
||||
|
||||
[previously_seen_cloud_compute_images]
|
||||
collection = previously_seen_cloud_compute_images
|
||||
external_type = kvstore
|
||||
# description = A table of previously seen Cloud image IDs
|
||||
fields_list = _key, firstTimeSeen, lastTimeSeen, image_id, enough_data
|
||||
|
||||
[previously_seen_cloud_compute_instance_types]
|
||||
collection = previously_seen_cloud_compute_instance_types
|
||||
external_type = kvstore
|
||||
# description = A place holder for a list of used cloud compute instance types
|
||||
fields_list = _key, firstTimeSeen, lastTimeSeen, instance_type, enough_data
|
||||
|
||||
[previously_seen_cloud_instance_modifications_by_user]
|
||||
collection = previously_seen_cloud_instance_modifications_by_user
|
||||
external_type = kvstore
|
||||
# description = A table of users seen making instance modifications, and the first and last time that the activity was observed
|
||||
fields_list = _key, firstTimeSeen, lastTimeSeen, user, enough_data
|
||||
|
||||
[previously_seen_cloud_provisioning_activity_sources]
|
||||
collection = previously_seen_cloud_provisioning_activity_sources
|
||||
external_type = kvstore
|
||||
# description = A table of source IPs, geographic locations, and the first and last time that they have that done cloud provisioning activities
|
||||
fields_list = _key, src, City, Country, Region, firstTimeSeen, lastTimeSeen, enough_data
|
||||
|
||||
[previously_seen_cloud_regions]
|
||||
collection = previously_seen_cloud_regions
|
||||
external_type = kvstore
|
||||
# description = A table of vendor_region values and the first and last time that they have been observed in cloud provisioning activities
|
||||
fields_list = _key, firstTimeSeen, lastTimeSeen, vendor_region, enough_data
|
||||
|
||||
[previously_seen_cmd_line_arguments]
|
||||
filename = previously_seen_cmd_line_arguments.csv
|
||||
# description = A placeholder for a list of cmd line arugments that been seen before
|
||||
|
||||
[previously_seen_ec2_modifications_by_user]
|
||||
filename = previously_seen_ec2_modifications_by_user.csv
|
||||
# description = A place holder for a list of AWS EC2 modifications done by each user
|
||||
|
||||
[previously_seen_running_windows_services]
|
||||
collection = previously_seen_running_windows_services
|
||||
external_type = kvstore
|
||||
# description = A placeholder for the list of Windows Services running
|
||||
fields_list = _key, service, firstTimeSeen, lastTimeSeen
|
||||
|
||||
[previously_seen_users_console_logins]
|
||||
collection = previously_seen_users_console_logins
|
||||
external_type = kvstore
|
||||
# description = A table of users seen doing console logins, and the first and last time that the activity was observed
|
||||
fields_list = _key, firstTime, lastTime, user, src, City, Region, Country
|
||||
|
||||
[prohibited_apps_launching_cmd]
|
||||
filename = prohibited_apps_launching_cmd.csv
|
||||
# description = A list of processes that should not be launching cmd.exe
|
||||
match_type = WILDCARD(prohibited_applications)
|
||||
|
||||
[prohibited_processes]
|
||||
filename = prohibited_processes.csv
|
||||
# description = A list of processes that have been marked as prohibited
|
||||
|
||||
[prohibited_softwares]
|
||||
filename = prohibited_softwares.csv
|
||||
# description = A list of processes that have been marked as prohibited
|
||||
|
||||
[ransomware_extensions_lookup]
|
||||
filename = ransomware_extensions.csv
|
||||
default_match = false
|
||||
case_sensitive_match = false
|
||||
# description = A list of file extensions that are associated with ransomware
|
||||
match_type = WILDCARD(Extensions)
|
||||
min_matches = 1
|
||||
|
||||
[ransomware_notes_lookup]
|
||||
filename = ransomware_notes.csv
|
||||
default_match = false
|
||||
# description = A list of file names that are ransomware note files
|
||||
match_type = WILDCARD(ransomware_notes)
|
||||
min_matches = 1
|
||||
|
||||
[s3_deletion_baseline]
|
||||
filename = s3_deletion_baseline.csv
|
||||
# description = A placeholder for the baseline information for AWS S3 deletions
|
||||
|
||||
[security_group_activity_baseline]
|
||||
filename = security_group_activity_baseline.csv
|
||||
# description = A placeholder for the baseline information for AWS security groups
|
||||
|
||||
[security_services_lookup]
|
||||
filename = security_services.csv
|
||||
default_match = false
|
||||
# description = A list of services that deal with security
|
||||
match_type = WILDCARD(service)
|
||||
min_matches = 1
|
||||
|
||||
[suspicious_writes_lookup]
|
||||
filename = suspicious_files.csv
|
||||
default_match = false
|
||||
# description = A list of suspicious file names
|
||||
match_type = WILDCARD(file)
|
||||
min_matches = 1
|
||||
|
||||
[zoom_first_time_child_process]
|
||||
collection = zoom_first_time_child_process
|
||||
external_type = kvstore
|
||||
# description = A list of suspicious file names
|
||||
fields_list = _key, dest, process_name, firstTimeSeen, lastTimeSeen
|
||||
|
||||
|
||||
### Default transforms definitions for the lookup files we ship ###
|
||||
[mitre_enrichment]
|
||||
filename = mitre_enrichment.csv
|
||||
# description = A lookup file that is created by generate.py
|
||||
@@ -1,3 +0,0 @@
|
||||
### Deprecated since ESCU UI was deprecated and this conf file is no longer in use
|
||||
|
||||
### Using one single file analyticstories.conf that will be used both by ES and ESCU
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
attacker_tool_names,description
|
||||
remcom.exe,This process is an open source replacement to psexec and is not typically seen in an enterprise environment.
|
||||
pwdump.exe,This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
pwdump2.exe,This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
nc.exe,This process is an open source tool used for network communications.
|
||||
wce.exe,This process is associated with a tool used to dump hashes and execute pass-the-hash and pass-the-ticket attacks.
|
||||
cain.exe,This process is associated with a tool used to collect user credentials and execute attacks.
|
||||
nmap.exe,This process is an open source network mapping tool used to identify hosts and listening services on a network.
|
||||
kidlogger.exe,This process is associated with a tool used to collect keyboard input on a host.
|
||||
isass.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
svch0st.exe,This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
at.exe,This process is used to schedule other processes to run. schtasks.exe should be used instead as it provides more flexibility.
|
||||
getmail.exe,This process is seen to be used by attackers to extract email files from host machines.
|
||||
ntdll.exe,This process was identified as malicious by DHS Alert TA18-074A.
|
||||
netpass.exe,This process was identified as malicious by DHS Alert TA18-201A and attackers use this tool to recover all network passwords stored on your system for the current logged-on user.
|
||||
WebBrowserPassView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers as a password recovery tool that reveals the passwords stored in Web Browsers.
|
||||
OutlookAddressBookView.exe,This process was identified as malicious by DHS Alert TA18-201A and is used by attackers to steal the details of all recipients stored in the address books of Microsoft Outlook.
|
||||
mailpv.exe,This process was identified by DHS Alert TA18-201A and attackers use this tool is a password-recovery tool that reveals the passwords and other account details from various email clients.
|
||||
NLBrute.exe,A RDP brute force tool found in botnets for further expansion and and acquisition of targets. This process was identified in the SamSam Ransomware Campaign and attackers use this tool to brute force RDP instances with a range of commonly used passwords.
|
||||
selfdel.exe,This executable was delivered in the SamSam Ransomware Campain and the attackers levereged this binary to delete its malicilous activities.
|
||||
masscan.exe,This executable was delivered in the XMRig Crypto Miner
|
||||
Massscan_GUI.exe,This executable was delivered in the XMRig Crypto Miner
|
||||
KPortScan3.exe,This executable was delivered in the XMRig Crypto Miner and is commonly used by attackers to scan the internet
|
||||
NLAChecker.exe,A scanner tool that checks for Windows hosts for Network Level Authentication. This tool allows attackers to detect Windows Servers with RDP without NLA enabled which facilitates the use of brute force non microsoft rdp tools or exploits
|
||||
ns.exe,A commonly used tool used by attackers to scan and map file shares
|
||||
SilverBullet.exe,Malware was discovered in our monitoring of honey pots that abuses this open source software for scanning and connecting to hosts.
|
||||
|
@@ -1 +0,0 @@
|
||||
identity
|
||||
|
@@ -1 +0,0 @@
|
||||
src_ip,numDataPoints,latestCount,avgBlockedConnections,stdevBlockedConnections
|
||||
|
-1
@@ -1 +0,0 @@
|
||||
domain,domain_abuse
|
||||
|
-21
@@ -1,21 +0,0 @@
|
||||
number, name
|
||||
1, Inventory of Authorized and Unauthorized Devices
|
||||
2, Inventory of Authorized and Unauthorized Software
|
||||
3, Secure Configuration of End-User Devices
|
||||
4, Continuous Vulnerability Assessment & Remediation
|
||||
5, Controlled Use of Administrative Privileges
|
||||
6, Maintenance Monitoring and Analysis of Audit Logs
|
||||
7, Email & Web Browser Protections
|
||||
8, Malware Defense
|
||||
9, Limitation & Control of Network Ports-Protocols & Services
|
||||
10, Data Recovery Capability
|
||||
11, Secure Configuration of Network Devices
|
||||
12, Boundary Defense
|
||||
13, Data Protection
|
||||
14, Controlled Access Based on Need to Know
|
||||
15, Wireless Access Control
|
||||
16, Account Monitoring and Control
|
||||
17, Security Skills Assessment and Appropriate Training
|
||||
18, Application Software Security
|
||||
19, Incident Response and Management
|
||||
20, Penetration Tests and Red Team Exercises
|
||||
|
@@ -1 +0,0 @@
|
||||
count,domain,type,query,answer
|
||||
|
Vendored
-1
@@ -1 +0,0 @@
|
||||
domain,isValidDomain
|
||||
|
-91976
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
dynamic_dns_domains, isDynDNS_local
|
||||
|
-1
@@ -1 +0,0 @@
|
||||
savedsearch_name, search_id, user, _time, usage
|
||||
|
@@ -1,3 +0,0 @@
|
||||
image, repository
|
||||
devsecops/cat_dog_client, splunk/devsecops_poc
|
||||
devsecops/cat_dog_server, splunk/devsecops_poc
|
||||
|
@@ -1,52 +0,0 @@
|
||||
file_name,suspicious
|
||||
*.avi.com,true
|
||||
*.avi.exe,true
|
||||
*.doc.com,true
|
||||
*.doc.exe,true
|
||||
*.docx.com,true
|
||||
*.docx.exe,true
|
||||
*.jpg.com,true
|
||||
*.jpg.exe,true
|
||||
*.jpeg.com,true
|
||||
*.jpeg.exe,true
|
||||
*.mpg.com,true
|
||||
*.mpg.exe,true
|
||||
*.mpg2.com,true
|
||||
*.mpg2.exe,true
|
||||
*.mpeg.com,true
|
||||
*.mpeg.exe,true
|
||||
*.pdf.com,true
|
||||
*.pdf.exe,true
|
||||
*.png.com,true
|
||||
*.png.exe,true
|
||||
*.ppt.com,true
|
||||
*.ppt.exe,true
|
||||
*.pptx.com,true
|
||||
*.pptx.exe,true
|
||||
*.swf.com,true
|
||||
*.swf.exe,true
|
||||
*.xls.com,true
|
||||
*.xls.exe,true
|
||||
*.xlsx.com,true
|
||||
*.xlsx.exe,true
|
||||
*.zip.com,true
|
||||
*.zip.exe,true
|
||||
*.bat,true
|
||||
*.chm,true
|
||||
*.com,true
|
||||
*.cmd,true
|
||||
*.cpl,true
|
||||
*.exe,true
|
||||
*.hlp,true
|
||||
*.hta,true
|
||||
*.jar,true
|
||||
*.js,true
|
||||
*.msi,true
|
||||
*.pif,true
|
||||
*.ps1,true
|
||||
*.rar,true
|
||||
*.reg,true
|
||||
*.scr,true
|
||||
*.vbe,true
|
||||
*.vbs,true
|
||||
*.wsf,true
|
||||
|
-753
@@ -1,753 +0,0 @@
|
||||
filename,systemFile
|
||||
acu.exe,true
|
||||
AgentService.exe,true
|
||||
aitstatic.exe,true
|
||||
alg.exe,true
|
||||
AppHostRegistrationVerifier.exe,true
|
||||
appidcertstorecheck.exe,true
|
||||
appidpolicyconverter.exe,true
|
||||
appidtel.exe,true
|
||||
ApplicationFrameHost.exe,true
|
||||
ApplySettingsTemplateCatalog.exe,true
|
||||
AppVClient.exe,true
|
||||
AppVDllSurrogate.exe,true
|
||||
AppVNice.exe,true
|
||||
AppVStreamingUX.exe,true
|
||||
ARP.EXE,true
|
||||
at.exe,true
|
||||
AtBroker.exe,true
|
||||
attrib.exe,true
|
||||
audiodg.exe,true
|
||||
auditpol.exe,true
|
||||
AuthHost.exe,true
|
||||
autochk.exe,true
|
||||
autoconv.exe,true
|
||||
autofmt.exe,true
|
||||
AxInstUI.exe,true
|
||||
backgroundTaskHost.exe,true
|
||||
BackgroundTransferHost.exe,true
|
||||
bcastdvr.exe,true
|
||||
bcdboot.exe,true
|
||||
bcdedit.exe,true
|
||||
BioIso.exe,true
|
||||
bitsadmin.exe,true
|
||||
bootcfg.exe,true
|
||||
bootim.exe,true
|
||||
bridgeunattend.exe,true
|
||||
browser_broker.exe,true
|
||||
bthudtask.exe,true
|
||||
ByteCodeGenerator.exe,true
|
||||
cacls.exe,true
|
||||
calc.exe,true
|
||||
CameraSettingsUIHost.exe,true
|
||||
CastSrv.exe,true
|
||||
CertEnrollCtrl.exe,true
|
||||
certreq.exe,true
|
||||
certutil.exe,true
|
||||
change.exe,true
|
||||
changepk.exe,true
|
||||
charmap.exe,true
|
||||
CheckNetIsolation.exe,true
|
||||
chglogon.exe,true
|
||||
chgport.exe,true
|
||||
chgusr.exe,true
|
||||
chkdsk.exe,true
|
||||
chkntfs.exe,true
|
||||
choice.exe,true
|
||||
cipher.exe,true
|
||||
cleanmgr.exe,true
|
||||
cliconfg.exe,true
|
||||
clip.exe,true
|
||||
ClipUp.exe,true
|
||||
CloudExperienceHostBroker.exe,true
|
||||
CloudNotifications.exe,true
|
||||
CloudStorageWizard.exe,true
|
||||
cmd.exe,true
|
||||
cmdkey.exe,true
|
||||
cmdl32.exe,true
|
||||
cmmon32.exe,true
|
||||
cmstp.exe,true
|
||||
cofire.exe,true
|
||||
colorcpl.exe,true
|
||||
comp.exe,true
|
||||
compact.exe,true
|
||||
CompatTelRunner.exe,true
|
||||
CompMgmtLauncher.exe,true
|
||||
ComputerDefaults.exe,true
|
||||
Configure-SMRemoting.exe,true
|
||||
conhost.exe,true
|
||||
consent.exe,true
|
||||
control.exe,true
|
||||
convert.exe,true
|
||||
CredentialUIBroker.exe,true
|
||||
credwiz.exe,true
|
||||
cscript.exe,true
|
||||
csrss.exe,true
|
||||
ctfmon.exe,true
|
||||
cttune.exe,true
|
||||
cttunesvr.exe,true
|
||||
dasHost.exe,true
|
||||
DataExchangeHost.exe,true
|
||||
DataSenseLiveTileTask.exe,true
|
||||
dccw.exe,true
|
||||
dcgpofix.exe,true
|
||||
dcomcnfg.exe,true
|
||||
dcpromo.exe,true
|
||||
ddodiag.exe,true
|
||||
Defrag.exe,true
|
||||
DeviceCensus.exe,true
|
||||
DeviceEject.exe,true
|
||||
DeviceEnroller.exe,true
|
||||
DevicePairingWizard.exe,true
|
||||
DeviceProperties.exe,true
|
||||
DFDWiz.exe,true
|
||||
dfrgui.exe,true
|
||||
dfsrdiag.exe,true
|
||||
dialer.exe,true
|
||||
DIMC.exe,true
|
||||
diskpart.exe,true
|
||||
diskperf.exe,true
|
||||
diskraid.exe,true
|
||||
diskshadow.exe,true
|
||||
DiskSnapshot.exe,true
|
||||
Dism.exe,true
|
||||
dispdiag.exe,true
|
||||
DisplaySwitch.exe,true
|
||||
djoin.exe,true
|
||||
dllhost.exe,true
|
||||
dllhst3g.exe,true
|
||||
dmcertinst.exe,true
|
||||
dmcfghost.exe,true
|
||||
DmNotificationBroker.exe,true
|
||||
DmOmaCpMo.exe,true
|
||||
dnscacheugc.exe,true
|
||||
doskey.exe,true
|
||||
dpapimig.exe,true
|
||||
DpiScaling.exe,true
|
||||
dpnsvr.exe,true
|
||||
driverquery.exe,true
|
||||
drvcfg.exe,true
|
||||
drvinst.exe,true
|
||||
DsmUserTask.exe,true
|
||||
dsregcmd.exe,true
|
||||
dstokenclean.exe,true
|
||||
dvdplay.exe,true
|
||||
dwm.exe,true
|
||||
DWWIN.EXE,true
|
||||
dxdiag.exe,true
|
||||
Dxpserver.exe,true
|
||||
Eap3Host.exe,true
|
||||
EaseOfAccessDialog.exe,true
|
||||
easinvoker.exe,true
|
||||
EasPoliciesBrokerHost.exe,true
|
||||
EDPCleanup.exe,true
|
||||
edpnotify.exe,true
|
||||
efsui.exe,true
|
||||
EhStorAuthn.exe,true
|
||||
embeddedapplauncher.exe,true
|
||||
EmbeddedAppLauncherConfig.exe,true
|
||||
escUnattend.exe,true
|
||||
esentutl.exe,true
|
||||
eudcedit.exe,true
|
||||
eventcreate.exe,true
|
||||
eventvwr.exe,true
|
||||
expand.exe,true
|
||||
extrac32.exe,true
|
||||
fc.exe,true
|
||||
find.exe,true
|
||||
findstr.exe,true
|
||||
finger.exe,true
|
||||
fixmapi.exe,true
|
||||
fltMC.exe,true
|
||||
fodhelper.exe,true
|
||||
Fondue.exe,true
|
||||
fontdrvhost.exe,true
|
||||
fontview.exe,true
|
||||
forfiles.exe,true
|
||||
fsavailux.exe,true
|
||||
fsquirt.exe,true
|
||||
fsutil.exe,true
|
||||
ftp.exe,true
|
||||
GameBarPresenceWriter.exe,true
|
||||
GamePanel.exe,true
|
||||
GenValObj.exe,true
|
||||
getmac.exe,true
|
||||
gpresult.exe,true
|
||||
gpscript.exe,true
|
||||
gpupdate.exe,true
|
||||
grpconv.exe,true
|
||||
hdwwiz.exe,true
|
||||
help.exe,true
|
||||
HOSTNAME.EXE,true
|
||||
hvax64.exe,true
|
||||
hvix64.exe,true
|
||||
hvloader.exe,true
|
||||
hwrcomp.exe,true
|
||||
hwrreg.exe,true
|
||||
iashost.exe,true
|
||||
icacls.exe,true
|
||||
IcsEntitlementHost.exe,true
|
||||
icsunattend.exe,true
|
||||
ie4uinit.exe,true
|
||||
ieUnatt.exe,true
|
||||
iexpress.exe,true
|
||||
immersivetpmvscmgrsvr.exe,true
|
||||
InfDefaultInstall.exe,true
|
||||
InstallAgent.exe,true
|
||||
InstallAgentUserBroker.exe,true
|
||||
ipconfig.exe,true
|
||||
iscsicli.exe,true
|
||||
iscsicpl.exe,true
|
||||
isoburn.exe,true
|
||||
klist.exe,true
|
||||
ksetup.exe,true
|
||||
ktmutil.exe,true
|
||||
ktpass.exe,true
|
||||
label.exe,true
|
||||
LanguageComponentsInstallerComHandler.exe,true
|
||||
LaunchTM.exe,true
|
||||
LaunchWinApp.exe,true
|
||||
LbfoAdmin.exe,true
|
||||
LegacyNetUXHost.exe,true
|
||||
LicenseManagerShellext.exe,true
|
||||
licensingdiag.exe,true
|
||||
LicensingUI.exe,true
|
||||
LocationNotificationWindows.exe,true
|
||||
Locator.exe,true
|
||||
LockAppHost.exe,true
|
||||
LockScreenContentServer.exe,true
|
||||
lodctr.exe,true
|
||||
logagent.exe,true
|
||||
logman.exe,true
|
||||
logoff.exe,true
|
||||
LogonUI.exe,true
|
||||
lpkinstall.exe,true
|
||||
lpksetup.exe,true
|
||||
lpremove.exe,true
|
||||
LsaIso.exe,true
|
||||
lsass.exe,true
|
||||
Magnify.exe,true
|
||||
makecab.exe,true
|
||||
mavinject.exe,true
|
||||
MbaeParserTask.exe,true
|
||||
mblctr.exe,true
|
||||
mcbuilder.exe,true
|
||||
MDEServer.exe,true
|
||||
MDMAgent.exe,true
|
||||
MDMAppInstaller.exe,true
|
||||
MdmDiagnosticsTool.exe,true
|
||||
MdRes.exe,true
|
||||
MdSched.exe,true
|
||||
mfpmp.exe,true
|
||||
Microsoft.Uev.CscUnpinTool.exe,true
|
||||
Microsoft.Uev.SyncController.exe,true
|
||||
mmc.exe,true
|
||||
mobsync.exe,true
|
||||
mountvol.exe,true
|
||||
mpnotify.exe,true
|
||||
MpSigStub.exe,true
|
||||
MRINFO.EXE,true
|
||||
MRT-KB890830.exe,true
|
||||
MRT.exe,true
|
||||
MSchedExe.exe,true
|
||||
msconfig.exe,true
|
||||
msdt.exe,true
|
||||
msdtc.exe,true
|
||||
msfeedssync.exe,true
|
||||
msg.exe,true
|
||||
mshta.exe,true
|
||||
msiexec.exe,true
|
||||
msinfo32.exe,true
|
||||
mspaint.exe,true
|
||||
MsSpellCheckingHost.exe,true
|
||||
mstsc.exe,true
|
||||
mtstocom.exe,true
|
||||
MuiUnattend.exe,true
|
||||
MultiDigiMon.exe,true
|
||||
MusNotification.exe,true
|
||||
MusNotificationUx.exe,true
|
||||
Narrator.exe,true
|
||||
nbtstat.exe,true
|
||||
ndadmin.exe,true
|
||||
net.exe,true
|
||||
net1.exe,true
|
||||
netbtugc.exe,true
|
||||
netcfg.exe,true
|
||||
NetCfgNotifyObjectHost.exe,true
|
||||
netdom.exe,true
|
||||
NetEvtFwdr.exe,true
|
||||
NetHost.exe,true
|
||||
netiougc.exe,true
|
||||
Netplwiz.exe,true
|
||||
netsh.exe,true
|
||||
NETSTAT.EXE,true
|
||||
newdev.exe,true
|
||||
nltest.exe,true
|
||||
notepad.exe,true
|
||||
nslookup.exe,true
|
||||
ntoskrnl.exe,true
|
||||
ntprint.exe,true
|
||||
odbcad32.exe,true
|
||||
odbcconf.exe,true
|
||||
omadmclient.exe,true
|
||||
omadmprc.exe,true
|
||||
openfiles.exe,true
|
||||
OpenWith.exe,true
|
||||
OptionalFeatures.exe,true
|
||||
osk.exe,true
|
||||
PackagedCWALauncher.exe,true
|
||||
PackageInspector.exe,true
|
||||
PasswordOnWakeSettingFlyout.exe,true
|
||||
PATHPING.EXE,true
|
||||
pcalua.exe,true
|
||||
pcaui.exe,true
|
||||
pcwrun.exe,true
|
||||
perfmon.exe,true
|
||||
phoneactivate.exe,true
|
||||
PickerHost.exe,true
|
||||
PING.EXE,true
|
||||
PkgMgr.exe,true
|
||||
plasrv.exe,true
|
||||
PnPUnattend.exe,true
|
||||
pnputil.exe,true
|
||||
poqexec.exe,true
|
||||
powercfg.exe,true
|
||||
PresentationHost.exe,true
|
||||
PresentationSettings.exe,true
|
||||
prevhost.exe,true
|
||||
print.exe,true
|
||||
PrintBrmUi.exe,true
|
||||
PrintDialogHost.exe,true
|
||||
PrintDialogHost3D.exe,true
|
||||
printfilterpipelinesvc.exe,true
|
||||
PrintIsolationHost.exe,true
|
||||
printui.exe,true
|
||||
proquota.exe,true
|
||||
psr.exe,true
|
||||
pwlauncher.exe,true
|
||||
qappsrv.exe,true
|
||||
qprocess.exe,true
|
||||
query.exe,true
|
||||
quser.exe,true
|
||||
qwinsta.exe,true
|
||||
rasdial.exe,true
|
||||
rdpclip.exe,true
|
||||
rdpinit.exe,true
|
||||
rdpinput.exe,true
|
||||
RdpSa.exe,true
|
||||
RdpSaProxy.exe,true
|
||||
RdpSaUacHelper.exe,true
|
||||
rdpshell.exe,true
|
||||
rdpsign.exe,true
|
||||
rdrleakdiag.exe,true
|
||||
RDSPnf.exe,true
|
||||
ReAgentc.exe,true
|
||||
recover.exe,true
|
||||
RecoveryDrive.exe,true
|
||||
reg.exe,true
|
||||
regedt32.exe,true
|
||||
regini.exe,true
|
||||
Register-CimProvider.exe,true
|
||||
regsvr32.exe,true
|
||||
rekeywiz.exe,true
|
||||
relog.exe,true
|
||||
RelPost.exe,true
|
||||
RemotePosWorker.exe,true
|
||||
replace.exe,true
|
||||
reset.exe,true
|
||||
ResetEngine.exe,true
|
||||
resmon.exe,true
|
||||
RMActivate.exe,true
|
||||
RMActivate_isv.exe,true
|
||||
RMActivate_ssp.exe,true
|
||||
RMActivate_ssp_isv.exe,true
|
||||
RmClient.exe,true
|
||||
rmttpmvscmgrsvr.exe,true
|
||||
Robocopy.exe,true
|
||||
ROUTE.EXE,true
|
||||
RpcPing.exe,true
|
||||
rrinstaller.exe,true
|
||||
rsopprov.exe,true
|
||||
runas.exe,true
|
||||
rundll32.exe,true
|
||||
RunLegacyCPLElevated.exe,true
|
||||
runonce.exe,true
|
||||
RuntimeBroker.exe,true
|
||||
rwinsta.exe,true
|
||||
sacsess.exe,true
|
||||
sc.exe,true
|
||||
schtasks.exe,true
|
||||
ScriptRunner.exe,true
|
||||
sdbinst.exe,true
|
||||
sdiagnhost.exe,true
|
||||
SearchFilterHost.exe,true
|
||||
SearchIndexer.exe,true
|
||||
SearchProtocolHost.exe,true
|
||||
SecEdit.exe,true
|
||||
secinit.exe,true
|
||||
securekernel.exe,true
|
||||
SensorDataService.exe,true
|
||||
ServerManager.exe,true
|
||||
ServerManagerLauncher.exe,true
|
||||
services.exe,true
|
||||
sessionmsg.exe,true
|
||||
sethc.exe,true
|
||||
setres.exe,true
|
||||
setspn.exe,true
|
||||
SettingSyncHost.exe,true
|
||||
setupcl.exe,true
|
||||
setupugc.exe,true
|
||||
setx.exe,true
|
||||
sfc.exe,true
|
||||
shrpubw.exe,true
|
||||
shutdown.exe,true
|
||||
sigverif.exe,true
|
||||
SIHClient.exe,true
|
||||
sihost.exe,true
|
||||
SlideToShutDown.exe,true
|
||||
slui.exe,true
|
||||
smartscreen.exe,true
|
||||
SmartScreenSettings.exe,true
|
||||
smss.exe,true
|
||||
SndVol.exe,true
|
||||
SnippingTool.exe,true
|
||||
snmptrap.exe,true
|
||||
sort.exe,true
|
||||
SpaceAgent.exe,true
|
||||
spaceman.exe,true
|
||||
spoolsv.exe,true
|
||||
SppExtComObj.Exe,true
|
||||
sppsvc.exe,true
|
||||
stordiag.exe,true
|
||||
subst.exe,true
|
||||
svchost.exe,true
|
||||
sxstrace.exe,true
|
||||
SyncAppvPublishingServer.exe,true
|
||||
SyncHost.exe,true
|
||||
syskey.exe,true
|
||||
SysResetErr.exe,true
|
||||
systeminfo.exe,true
|
||||
SystemPropertiesAdvanced.exe,true
|
||||
SystemPropertiesComputerName.exe,true
|
||||
SystemPropertiesDataExecutionPrevention.exe,true
|
||||
SystemPropertiesHardware.exe,true
|
||||
SystemPropertiesPerformance.exe,true
|
||||
SystemPropertiesProtection.exe,true
|
||||
SystemPropertiesRemote.exe,true
|
||||
systemreset.exe,true
|
||||
SystemSettingsAdminFlows.exe,true
|
||||
SystemSettingsBroker.exe,true
|
||||
SystemSettingsRemoveDevice.exe,true
|
||||
systray.exe,true
|
||||
tabcal.exe,true
|
||||
takeown.exe,true
|
||||
TapiUnattend.exe,true
|
||||
taskhostw.exe,true
|
||||
taskkill.exe,true
|
||||
tasklist.exe,true
|
||||
Taskmgr.exe,true
|
||||
tcmsetup.exe,true
|
||||
TCPSVCS.EXE,true
|
||||
tdlrecover.exe,true
|
||||
ThumbnailExtractionHost.exe,true
|
||||
TieringEngineService.exe,true
|
||||
timeout.exe,true
|
||||
TokenBrokerCookies.exe,true
|
||||
TpmInit.exe,true
|
||||
tpmvscmgr.exe,true
|
||||
tpmvscmgrsvr.exe,true
|
||||
tracerpt.exe,true
|
||||
TRACERT.EXE,true
|
||||
tscon.exe,true
|
||||
tsdiscon.exe,true
|
||||
tsecimp.exe,true
|
||||
tskill.exe,true
|
||||
TSTheme.exe,true
|
||||
TSWbPrxy.exe,true
|
||||
typeperf.exe,true
|
||||
tzsync.exe,true
|
||||
tzutil.exe,true
|
||||
ucsvc.exe,true
|
||||
UevAgentPolicyGenerator.exe,true
|
||||
UevAppMonitor.exe,true
|
||||
UevTemplateBaselineGenerator.exe,true
|
||||
UevTemplateConfigItemGenerator.exe,true
|
||||
UI0Detect.exe,true
|
||||
unlodctr.exe,true
|
||||
unregmp2.exe,true
|
||||
UpgradeResultsUI.exe,true
|
||||
upnpcont.exe,true
|
||||
UserAccountBroker.exe,true
|
||||
UserAccountControlSettings.exe,true
|
||||
userinit.exe,true
|
||||
UsoClient.exe,true
|
||||
Utilman.exe,true
|
||||
VaultCmd.exe,true
|
||||
vds.exe,true
|
||||
vdsldr.exe,true
|
||||
verclsid.exe,true
|
||||
verifier.exe,true
|
||||
verifiergui.exe,true
|
||||
vssadmin.exe,true
|
||||
VSSUIRUN.exe,true
|
||||
VSSVC.exe,true
|
||||
w32tm.exe,true
|
||||
waitfor.exe,true
|
||||
WallpaperHost.exe,true
|
||||
WebCache.exe,true
|
||||
wecutil.exe,true
|
||||
WerFault.exe,true
|
||||
WerFaultSecure.exe,true
|
||||
wermgr.exe,true
|
||||
wevtutil.exe,true
|
||||
wextract.exe,true
|
||||
where.exe,true
|
||||
whoami.exe,true
|
||||
wiaacmgr.exe,true
|
||||
wiawow64.exe,true
|
||||
wimserv.exe,true
|
||||
win32calc.exe,true
|
||||
WinBioDataModelOOBE.exe,true
|
||||
Windows.Media.BackgroundPlayback.exe,true
|
||||
WindowsActionDialog.exe,true
|
||||
WindowsUpdateElevatedInstaller.exe,true
|
||||
wininit.exe,true
|
||||
winload.exe,true
|
||||
winlogon.exe,true
|
||||
winresume.exe,true
|
||||
winrs.exe,true
|
||||
winrshost.exe,true
|
||||
WinSAT.exe,true
|
||||
winver.exe,true
|
||||
wkspbroker.exe,true
|
||||
wksprt.exe,true
|
||||
wlrmdr.exe,true
|
||||
WMPDMC.exe,true
|
||||
wowreg32.exe,true
|
||||
WPDShextAutoplay.exe,true
|
||||
wpr.exe,true
|
||||
write.exe,true
|
||||
WSCollect.exe,true
|
||||
wscript.exe,true
|
||||
WSManHTTPConfig.exe,true
|
||||
wsmprovhost.exe,true
|
||||
wsqmcons.exe,true
|
||||
WSReset.exe,true
|
||||
wuapihost.exe,true
|
||||
wuauclt.exe,true
|
||||
WUDFHost.exe,true
|
||||
wusa.exe,true
|
||||
WWAHost.exe,true
|
||||
XblGameSaveTask.exe,true
|
||||
xcopy.exe,true
|
||||
xwizard.exe,true
|
||||
comrepl.exe,true
|
||||
MigRegDB.exe,true
|
||||
DiagnosticsHub.StandardCollector.Service.exe,true
|
||||
DismHost.exe,true
|
||||
F12Chooser.exe,true
|
||||
IMJPDCT.EXE,true
|
||||
IMJPSET.EXE,true
|
||||
IMJPUEX.EXE,true
|
||||
imjpuexc.exe,true
|
||||
IMTCLNWZ.EXE,true
|
||||
IMTCPROP.exe,true
|
||||
IMCCPHR.exe,true
|
||||
ImeBroker.exe,true
|
||||
imecfmui.exe,true
|
||||
IMEDICTUPDATEUI.EXE,true
|
||||
IMEPADSV.EXE,true
|
||||
IMESEARCH.EXE,true
|
||||
IMEWDBLD.EXE,true
|
||||
ChsIME.exe,true
|
||||
ChtIME.exe,true
|
||||
mighost.exe,true
|
||||
audit.exe,true
|
||||
AuditShD.exe,true
|
||||
FirstLogonAnim.exe,true
|
||||
msoobe.exe,true
|
||||
oobeldr.exe,true
|
||||
Setup.exe,true
|
||||
UserOOBEBroker.exe,true
|
||||
windeploy.exe,true
|
||||
SpeechUXWiz.exe,true
|
||||
SpeechModelDownload.exe,true
|
||||
SpeechRuntime.exe,true
|
||||
PrintBrm.exe,true
|
||||
PrintBrmEngine.exe,true
|
||||
sysprep.exe,true
|
||||
SystemResetPlatform.exe,true
|
||||
mofcomp.exe,true
|
||||
scrcons.exe,true
|
||||
unsecapp.exe,true
|
||||
wbemtest.exe,true
|
||||
WinMgmt.exe,true
|
||||
WMIADAP.exe,true
|
||||
WmiApSrv.exe,true
|
||||
WMIC.exe,true
|
||||
WmiPrvSE.exe,true
|
||||
powershell.exe,true
|
||||
powershell_ise.exe,true
|
||||
dplaysvr.exe,true
|
||||
dtdump.exe,true
|
||||
hh.exe,true
|
||||
instnm.exe,true
|
||||
perfhost.exe,true
|
||||
rasautou.exe,true
|
||||
rasphone.exe,true
|
||||
regedit.exe,true
|
||||
setup16.exe,true
|
||||
user.exe,true
|
||||
_isdel.exe,true
|
||||
agentactivationruntimestarter.exe,true
|
||||
ApplyTrustOffline.exe,true
|
||||
ApproveChildRequest.exe,true
|
||||
appverif.exe,true
|
||||
baaupdate.exe,true
|
||||
bash.exe,true
|
||||
bdechangepin.exe,true
|
||||
BdeHdCfg.exe,true
|
||||
BdeUISrv.exe,true
|
||||
bdeunlock.exe,true
|
||||
BitLockerDeviceEncryption.exe,true
|
||||
BitLockerWizard.exe,true
|
||||
BitLockerWizardElev.exe,true
|
||||
bootsect.exe,true
|
||||
browserexport.exe,true
|
||||
CIDiag.exe,true
|
||||
CompPkgSrv.exe,true
|
||||
convertvhd.exe,true
|
||||
coredpussvr.exe,true
|
||||
CredentialEnrollmentManager.exe,true
|
||||
curl.exe,true
|
||||
CustomInstallExec.exe,true
|
||||
d3dconfig.exe,true
|
||||
DataStoreCacheDumpTool.exe,true
|
||||
DataUsageLiveTileTask.exe,true
|
||||
deploymentcsphelper.exe,true
|
||||
desktopimgdownldr.exe,true
|
||||
DeviceCredentialDeployment.exe,true
|
||||
directxdatabaseupdater.exe,true
|
||||
dmclient.exe,true
|
||||
DTUHandler.exe,true
|
||||
dusmtask.exe,true
|
||||
DXCap.exe,true
|
||||
DXCpl.exe,true
|
||||
dxgiadaptercache.exe,true
|
||||
EASPolicyManagerBrokerHost.exe,true
|
||||
EduPrintProv.exe,true
|
||||
EoAExperiences.exe,true
|
||||
fhmanagew.exe,true
|
||||
FileHistory.exe,true
|
||||
FsIso.exe,true
|
||||
fvenotify.exe,true
|
||||
fveprompt.exe,true
|
||||
FXSCOVER.exe,true
|
||||
FXSSVC.exe,true
|
||||
FXSUNATD.exe,true
|
||||
hcsdiag.exe,true
|
||||
hnsdiag.exe,true
|
||||
hvsievaluator.exe,true
|
||||
ie4ushowIE.exe,true
|
||||
IESettingSync.exe,true
|
||||
InputSwitchToastHandler.exe,true
|
||||
iotstartup.exe,true
|
||||
manage-bde.exe,true
|
||||
MBR2GPT.EXE,true
|
||||
microsoft.windows.softwarelogo.showdesktop.exe,true
|
||||
MicrosoftEdgeBCHost.exe,true
|
||||
MicrosoftEdgeCP.exe,true
|
||||
MicrosoftEdgeDevTools.exe,true
|
||||
MicrosoftEdgeSH.exe,true
|
||||
mmgaserver.exe,true
|
||||
MoUsoCoreWorker.exe,true
|
||||
msra.exe,true
|
||||
MusNotifyIcon.exe,true
|
||||
NDKPing.exe,true
|
||||
NgcIso.exe,true
|
||||
nmbind.exe,true
|
||||
nmscrub.exe,true
|
||||
nvspinfo.exe,true
|
||||
ofdeploy.exe,true
|
||||
pacjsworker.exe,true
|
||||
PinEnrollmentBroker.exe,true
|
||||
PktMon.exe,true
|
||||
pospaymentsworker.exe,true
|
||||
provlaunch.exe,true
|
||||
provtool.exe,true
|
||||
ProximityUxHost.exe,true
|
||||
prproc.exe,true
|
||||
quickassist.exe,true
|
||||
raserver.exe,true
|
||||
RDVGHelper.exe,true
|
||||
recdisc.exe,true
|
||||
refsutil.exe,true
|
||||
RemoteAppLifetimeManager.exe,true
|
||||
RemoteFXvGPUDisablement.exe,true
|
||||
repair-bde.exe,true
|
||||
rstrui.exe,true
|
||||
runexehelper.exe,true
|
||||
sdchange.exe,true
|
||||
sdclt.exe,true
|
||||
SecurityHealthHost.exe,true
|
||||
SecurityHealthService.exe,true
|
||||
SecurityHealthSystray.exe,true
|
||||
SgrmBroker.exe,true
|
||||
SgrmLpac.exe,true
|
||||
SpatialAudioLicenseSrv.exe,true
|
||||
Spectrum.exe,true
|
||||
srdelayed.exe,true
|
||||
SrTasks.exe,true
|
||||
SystemUWPLauncher.exe,true
|
||||
tar.exe,true
|
||||
tcblaunch.exe,true
|
||||
TpmTool.exe,true
|
||||
ttdinject.exe,true
|
||||
tttracer.exe,true
|
||||
UIMgrBroker.exe,true
|
||||
upfc.exe,true
|
||||
usocoreworker.exe,true
|
||||
UtcDecoderHost.exe,true
|
||||
VBoxControl.exe,true
|
||||
VBoxService.exe,true
|
||||
VBoxTray.exe,true
|
||||
vfpctrl.exe,true
|
||||
vmcompute.exe,true
|
||||
vmwp.exe,true
|
||||
VsGraphicsDesktopEngine.exe,true
|
||||
VsGraphicsRemoteEngine.exe,true
|
||||
vsjitdebugger.exe,true
|
||||
WaaSMedicAgent.exe,true
|
||||
wbadmin.exe,true
|
||||
wbengine.exe,true
|
||||
WFS.exe,true
|
||||
wifitask.exe,true
|
||||
Windows.WARP.JITService.exe,true
|
||||
WinRTNetMUAHostServer.exe,true
|
||||
wlanext.exe,true
|
||||
WorkFolders.exe,true
|
||||
WpcMon.exe,true
|
||||
WpcTok.exe,true
|
||||
wpnpinst.exe,true
|
||||
wscadminui.exe,true
|
||||
wsl.exe,true
|
||||
wslconfig.exe,true
|
||||
WUDFCompanionHost.exe,true
|
||||
IEChooser.exe,true
|
||||
wslhost.exe,true
|
||||
scp.exe,true
|
||||
sftp.exe,true
|
||||
ssh-add.exe,true
|
||||
ssh-agent.exe,true
|
||||
ssh-keygen.exe,true
|
||||
ssh-keyscan.exe,true
|
||||
ssh.exe,true
|
||||
PerceptionSimulationInput.exe,true
|
||||
PerceptionSimulationService.exe,true
|
||||
UNPUXHost.exe,true
|
||||
UNPUXLauncher.exe,true
|
||||
UpdateNotificationMgr.exe,true
|
||||
FaceFodUninstaller.exe,true
|
||||
wlms.exe,true
|
||||
OneDriveSetup.exe,true
|
||||
OposHost.exe,true
|
||||
|
-20
@@ -1,20 +0,0 @@
|
||||
domain, isLegit
|
||||
amazon.com, True
|
||||
ssl-images-amazon.com, True
|
||||
facebook.com, True
|
||||
xx.fbcdn.net, True
|
||||
github.com, True
|
||||
githubassets.com, True
|
||||
instagram.com, True
|
||||
linkedin.com, True
|
||||
microsoftonline.com, True
|
||||
office.com, True
|
||||
okta.com, True
|
||||
live.com, True
|
||||
protonmail.com, True
|
||||
reddit.com, True
|
||||
redditstatic.com, True
|
||||
twitter.com, True
|
||||
twimg.com, True
|
||||
google.com, True
|
||||
|
||||
|
-1009
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
workflow_name, job_name
|
||||
deployment, k8s-security
|
||||
|
@@ -1,2 +0,0 @@
|
||||
job_name, step_name
|
||||
k8s-security, Run Kube Hunter
|
||||
|
-564
@@ -1,564 +0,0 @@
|
||||
"mitre_id","technique","tactics","groups"
|
||||
"T1553.006","Code Signing Policy Modification","Defense Evasion","Turla|APT39"
|
||||
"T1614","System Location Discovery","Discovery","no"
|
||||
"T1613","Container and Resource Discovery","Discovery","no"
|
||||
"T1552.007","Container API","Credential Access","no"
|
||||
"T1612","Build Image on Host","Defense Evasion","no"
|
||||
"T1611","Escape to Host","Privilege Escalation","no"
|
||||
"T1204.003","Malicious Image","Execution","no"
|
||||
"T1053.007","Container Orchestration Job","Execution|Persistence|Privilege Escalation","no"
|
||||
"T1610","Deploy Container","Defense Evasion|Execution","no"
|
||||
"T1609","Container Administration Command","Execution","no"
|
||||
"T1608.005","Link Target","Resource Development","Silent Librarian"
|
||||
"T1608.004","Drive-by Target","Resource Development","APT32|Threat Group-3390"
|
||||
"T1608.003","Install Digital Certificate","Resource Development","no"
|
||||
"T1608.002","Upload Tool","Resource Development","Threat Group-3390"
|
||||
"T1608.001","Upload Malware","Resource Development","APT32"
|
||||
"T1608","Stage Capabilities","Resource Development","no"
|
||||
"T1016.001","Internet Connection Discovery","Discovery","APT29|UNC2452|Turla"
|
||||
"T1553.005","Mark-of-the-Web Bypass","Defense Evasion","TA505"
|
||||
"T1555.005","Password Managers","Credential Access","Fox Kitten|Operation Wocao"
|
||||
"T1484.002","Domain Trust Modification","Defense Evasion|Privilege Escalation","APT29|UNC2452"
|
||||
"T1484.001","Group Policy Modification","Defense Evasion|Privilege Escalation","Indrik Spider"
|
||||
"T1547.014","Active Setup","Persistence|Privilege Escalation","no"
|
||||
"T1606.002","SAML Tokens","Credential Access","APT29|UNC2452"
|
||||
"T1606.001","Web Cookies","Credential Access","APT29|UNC2452"
|
||||
"T1606","Forge Web Credentials","Credential Access","no"
|
||||
"T1555.004","Windows Credential Manager","Credential Access","Stealth Falcon|OilRig|Turla"
|
||||
"T1059.008","Network Device CLI","Execution","no"
|
||||
"T1602.002","Network Device Configuration Dump","Collection","no"
|
||||
"T1542.005","TFTP Boot","Defense Evasion|Persistence","no"
|
||||
"T1542.004","ROMMONkit","Defense Evasion|Persistence","no"
|
||||
"T1602.001","SNMP (MIB Dump)","Collection","no"
|
||||
"T1602","Data from Configuration Repository","Collection","no"
|
||||
"T1601.002","Downgrade System Image","Defense Evasion","no"
|
||||
"T1601.001","Patch System Image","Defense Evasion","no"
|
||||
"T1601","Modify System Image","Defense Evasion","no"
|
||||
"T1600.002","Disable Crypto Hardware","Defense Evasion","no"
|
||||
"T1600.001","Reduce Key Space","Defense Evasion","no"
|
||||
"T1600","Weaken Encryption","Defense Evasion","no"
|
||||
"T1556.004","Network Device Authentication","Credential Access|Defense Evasion|Persistence","no"
|
||||
"T1599.001","Network Address Translation Traversal","Defense Evasion","no"
|
||||
"T1599","Network Boundary Bridging","Defense Evasion","no"
|
||||
"T1020.001","Traffic Duplication","Exfiltration","no"
|
||||
"T1557.002","ARP Cache Poisoning","Credential Access|Collection","Cleaver"
|
||||
"T1588.006","Vulnerabilities","Resource Development","Sandworm Team"
|
||||
"T1053.006","Systemd Timers","Execution|Persistence|Privilege Escalation","no"
|
||||
"T1562.008","Disable Cloud Logs","Defense Evasion","no"
|
||||
"T1547.012","Print Processors","Persistence|Privilege Escalation","no"
|
||||
"T1598.003","Spearphishing Link","Reconnaissance","Silent Librarian|Sidewinder|Sandworm Team|APT32|Kimsuky"
|
||||
"T1598.002","Spearphishing Attachment","Reconnaissance","Sidewinder"
|
||||
"T1598.001","Spearphishing Service","Reconnaissance","no"
|
||||
"T1598","Phishing for Information","Reconnaissance","ZIRCONIUM|APT28"
|
||||
"T1597.002","Purchase Technical Data","Reconnaissance","no"
|
||||
"T1597.001","Threat Intel Vendors","Reconnaissance","no"
|
||||
"T1597","Search Closed Sources","Reconnaissance","no"
|
||||
"T1596.005","Scan Databases","Reconnaissance","no"
|
||||
"T1596.004","CDNs","Reconnaissance","no"
|
||||
"T1596.003","Digital Certificates","Reconnaissance","no"
|
||||
"T1596.001","DNS/Passive DNS","Reconnaissance","no"
|
||||
"T1596.002","WHOIS","Reconnaissance","no"
|
||||
"T1596","Search Open Technical Databases","Reconnaissance","no"
|
||||
"T1595.002","Vulnerability Scanning","Reconnaissance","Volatile Cedar|APT28|Sandworm Team"
|
||||
"T1595.001","Scanning IP Blocks","Reconnaissance","no"
|
||||
"T1595","Active Scanning","Reconnaissance","no"
|
||||
"T1594","Search Victim-Owned Websites","Reconnaissance","Silent Librarian|Sandworm Team"
|
||||
"T1593.002","Search Engines","Reconnaissance","no"
|
||||
"T1593.001","Social Media","Reconnaissance","no"
|
||||
"T1593","Search Open Websites/Domains","Reconnaissance","Sandworm Team"
|
||||
"T1592.004","Client Configurations","Reconnaissance","HAFNIUM"
|
||||
"T1592.003","Firmware","Reconnaissance","no"
|
||||
"T1592.002","Software","Reconnaissance","Sandworm Team"
|
||||
"T1592.001","Hardware","Reconnaissance","no"
|
||||
"T1592","Gather Victim Host Information","Reconnaissance","no"
|
||||
"T1591.004","Identify Roles","Reconnaissance","no"
|
||||
"T1591.003","Identify Business Tempo","Reconnaissance","no"
|
||||
"T1591.001","Determine Physical Locations","Reconnaissance","no"
|
||||
"T1591.002","Business Relationships","Reconnaissance","Sandworm Team"
|
||||
"T1591","Gather Victim Org Information","Reconnaissance","no"
|
||||
"T1590.006","Network Security Appliances","Reconnaissance","no"
|
||||
"T1590.005","IP Addresses","Reconnaissance","HAFNIUM"
|
||||
"T1590.004","Network Topology","Reconnaissance","no"
|
||||
"T1590.003","Network Trust Dependencies","Reconnaissance","no"
|
||||
"T1590.002","DNS","Reconnaissance","no"
|
||||
"T1590.001","Domain Properties","Reconnaissance","Sandworm Team"
|
||||
"T1590","Gather Victim Network Information","Reconnaissance","HAFNIUM"
|
||||
"T1589.003","Employee Names","Reconnaissance","Silent Librarian|Sandworm Team"
|
||||
"T1589.002","Email Addresses","Reconnaissance","TA551|MuddyWater|HAFNIUM|APT32|Silent Librarian|Sandworm Team"
|
||||
"T1589.001","Credentials","Reconnaissance","APT28|Magic Hound|Chimera"
|
||||
"T1589","Gather Victim Identity Information","Reconnaissance","APT32"
|
||||
"T1588.005","Exploits","Resource Development","no"
|
||||
"T1588.004","Digital Certificates","Resource Development","Lazarus Group|Silent Librarian"
|
||||
"T1588.003","Code Signing Certificates","Resource Development","Wizard Spider"
|
||||
"T1588.002","Tool","Resource Development","MuddyWater|Silent Librarian|GALLIUM|Sandworm Team"
|
||||
"T1588.001","Malware","Resource Development","Turla|APT1"
|
||||
"T1588","Obtain Capabilities","Resource Development","no"
|
||||
"T1587.004","Exploits","Resource Development","no"
|
||||
"T1587.003","Digital Certificates","Resource Development","APT29|PROMETHIUM"
|
||||
"T1587.002","Code Signing Certificates","Resource Development","PROMETHIUM|Patchwork"
|
||||
"T1587.001","Malware","Resource Development","APT29|Lazarus Group|UNC2452|Sandworm Team|Turla|FIN7|Night Dragon|Cleaver"
|
||||
"T1587","Develop Capabilities","Resource Development","Kimsuky"
|
||||
"T1586.002","Email Accounts","Resource Development","Magic Hound|Kimsuky"
|
||||
"T1586.001","Social Media Accounts","Resource Development","no"
|
||||
"T1586","Compromise Accounts","Resource Development","no"
|
||||
"T1585.002","Email Accounts","Resource Development","Magic Hound|Silent Librarian|Sandworm Team|APT1"
|
||||
"T1585.001","Social Media Accounts","Resource Development","Fox Kitten|Sandworm Team|APT32|Cleaver"
|
||||
"T1585","Establish Accounts","Resource Development","Fox Kitten|APT17"
|
||||
"T1584.006","Web Services","Resource Development","Turla"
|
||||
"T1584.005","Botnet","Resource Development","no"
|
||||
"T1584.004","Server","Resource Development","Indrik Spider|Turla|APT16"
|
||||
"T1584.003","Virtual Private Server","Resource Development","Turla"
|
||||
"T1584.002","DNS Server","Resource Development","no"
|
||||
"T1584.001","Domains","Resource Development","APT29|UNC2452|APT1"
|
||||
"T1583.006","Web Services","Resource Development","ZIRCONIUM|MuddyWater|HAFNIUM|Lazarus Group|Turla|APT32|APT17|APT29"
|
||||
"T1583.005","Botnet","Resource Development","no"
|
||||
"T1583.004","Server","Resource Development","GALLIUM|Sandworm Team"
|
||||
"T1583.003","Virtual Private Server","Resource Development","HAFNIUM|TEMP.Veles"
|
||||
"T1583.002","DNS Server","Resource Development","no"
|
||||
"T1584","Compromise Infrastructure","Resource Development","no"
|
||||
"T1583.001","Domains","Resource Development","APT29|Mustang Panda|ZIRCONIUM|UNC2452|Lazarus Group|Silent Librarian|menuPass|Sandworm Team|APT32|Kimsuky|APT1|APT28"
|
||||
"T1583","Acquire Infrastructure","Resource Development","no"
|
||||
"T1564.007","VBA Stomping","Defense Evasion","no"
|
||||
"T1558.004","AS-REP Roasting","Credential Access","no"
|
||||
"T1580","Cloud Infrastructure Discovery","Discovery","no"
|
||||
"T1218.012","Verclsid","Defense Evasion","no"
|
||||
"T1205.001","Port Knocking","Defense Evasion|Persistence|Command And Control","PROMETHIUM"
|
||||
"T1564.006","Run Virtual Instance","Defense Evasion","no"
|
||||
"T1564.005","Hidden File System","Defense Evasion","Strider|Equation"
|
||||
"T1556.003","Pluggable Authentication Modules","Credential Access|Defense Evasion|Persistence","no"
|
||||
"T1574.012","COR_PROFILER","Persistence|Privilege Escalation|Defense Evasion","Blue Mockingbird"
|
||||
"T1562.007","Disable or Modify Cloud Firewall","Defense Evasion","no"
|
||||
"T1098.004","SSH Authorized Keys","Persistence","no"
|
||||
"T1480.001","Environmental Keying","Defense Evasion","APT41|Equation"
|
||||
"T1059.007","JavaScript","Execution","MuddyWater|Turla|Higaisa|Sidewinder|Evilnum|Kimsuky|FIN6|APT32|FIN7|Cobalt Group|Molerats|TA505|Silence|Leafminer"
|
||||
"T1578.004","Revert Cloud Instance","Defense Evasion","no"
|
||||
"T1578.003","Delete Cloud Instance","Defense Evasion","no"
|
||||
"T1578.001","Create Snapshot","Defense Evasion","no"
|
||||
"T1578.002","Create Cloud Instance","Defense Evasion","no"
|
||||
"T1127.001","MSBuild","Defense Evasion","Frankenstein"
|
||||
"T1027.005","Indicator Removal from Tools","Defense Evasion","Operation Wocao|GALLIUM|TEMP.Veles|Patchwork|APT3|Turla|OilRig|Deep Panda"
|
||||
"T1562.006","Indicator Blocking","Defense Evasion","no"
|
||||
"T1573.002","Asymmetric Cryptography","Command And Control","Operation Wocao|Tropic Trooper|Cobalt Group|OilRig|FIN8|FIN6"
|
||||
"T1573.001","Symmetric Cryptography","Command And Control","Mustang Panda|Darkhotel|ZIRCONIUM|Higaisa|Frankenstein|Inception|APT28|APT33|BRONZE BUTLER|Stealth Falcon|Lazarus Group"
|
||||
"T1573","Encrypted Channel","Command And Control","Tropic Trooper"
|
||||
"T1027.004","Compile After Delivery","Defense Evasion","Gamaredon Group|Rocke|MuddyWater"
|
||||
"T1574.004","Dylib Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1546.015","Component Object Model Hijacking","Privilege Escalation|Persistence","APT28"
|
||||
"T1071.004","DNS","Command And Control","Chimera|APT39|Tropic Trooper|OilRig|Ke3chang|Cobalt Group|APT18|APT41|FIN7"
|
||||
"T1071.003","Mail Protocols","Command And Control","Turla|Kimsuky|APT32|SilverTerrier|APT28"
|
||||
"T1071.002","File Transfer Protocols","Command And Control","Kimsuky|APT41|SilverTerrier|Honeybee"
|
||||
"T1071.001","Web Protocols","Command And Control","APT29|Mustang Panda|Windshift|TA551|Higaisa|HAFNIUM|Sidewinder|Chimera|UNC2452|Sandworm Team|TA505|Rocke|APT39|Tropic Trooper|MuddyWater|Wizard Spider|Inception|APT41|SilverTerrier|APT28|WIRTE|APT33|FIN4|Night Dragon|APT18|APT38|APT19|Cobalt Group|Rancor|Orangeworm|Threat Group-3390|Ke3chang|Turla|APT37|Dark Caracal|Lazarus Group|BRONZE BUTLER|APT32|Magic Hound|OilRig|Gamaredon Group|Stealth Falcon"
|
||||
"T1572","Protocol Tunneling","Command And Control","Chimera|Fox Kitten|OilRig|Cobalt Group|FIN6"
|
||||
"T1048.003","Exfiltration Over Unencrypted/Obfuscated Non-C2 Protocol","Exfiltration","Wizard Spider|FIN6|APT32|APT33|Thrip|FIN8|OilRig|Lazarus Group"
|
||||
"T1048.002","Exfiltration Over Asymmetric Encrypted Non-C2 Protocol","Exfiltration","APT29|UNC2452"
|
||||
"T1048.001","Exfiltration Over Symmetric Encrypted Non-C2 Protocol","Exfiltration","no"
|
||||
"T1001.003","Protocol Impersonation","Command And Control","Higaisa|Lazarus Group"
|
||||
"T1001.002","Steganography","Command And Control","APT29|Axiom"
|
||||
"T1001.001","Junk Data","Command And Control","APT28"
|
||||
"T1132.002","Non-Standard Encoding","Command And Control","no"
|
||||
"T1132.001","Standard Encoding","Command And Control","HAFNIUM|TA551|Sandworm Team|Tropic Trooper|MuddyWater|APT33|APT19|Lazarus Group|BRONZE BUTLER|Patchwork"
|
||||
"T1090.004","Domain Fronting","Command And Control","APT29"
|
||||
"T1090.003","Multi-hop Proxy","Command And Control","APT28|Operation Wocao|Inception|FIN4|APT29"
|
||||
"T1090.002","External Proxy","Command And Control","APT39|Silence|GALLIUM|MuddyWater|APT3|FIN5|Lazarus Group|menuPass|APT28"
|
||||
"T1090.001","Internal Proxy","Command And Control","APT29|Higaisa|UNC2452|Operation Wocao|APT39|Strider"
|
||||
"T1102.003","One-Way Communication","Command And Control","Leviathan"
|
||||
"T1102.002","Bidirectional Communication","Command And Control","ZIRCONIUM|MuddyWater|APT28|APT29|Sandworm Team|APT39|APT12|FIN7|Turla|APT37|Magic Hound|Carbanak"
|
||||
"T1102.001","Dead Drop Resolver","Command And Control","Rocke|APT41|BRONZE BUTLER|RTM|Patchwork"
|
||||
"T1571","Non-Standard Port","Command And Control","Sandworm Team|Rocke|DarkVishnya|Silence|APT-C-36|Magic Hound|APT33|APT32|TEMP.Veles|Lazarus Group|FIN7"
|
||||
"T1074.002","Remote Data Staging","Collection","APT29|Chimera|UNC2452|Threat Group-3390|menuPass|FIN6|Night Dragon|FIN8"
|
||||
"T1074.001","Local Data Staging","Collection","Mustang Panda|Sidewinder|Chimera|Kimsuky|APT39|Operation Wocao|GALLIUM|TEMP.Veles|Honeybee|Patchwork|Dragonfly 2.0|Leviathan|APT3|FIN5|menuPass|Lazarus Group|Threat Group-3390|APT28"
|
||||
"T1078.004","Cloud Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","APT33"
|
||||
"T1564.004","NTFS File Attributes","Defense Evasion","APT32"
|
||||
"T1564.003","Hidden Window","Defense Evasion","Higaisa|Gorgon Group|Deep Panda|DarkHydrus|CopyKittens|APT19|APT32|APT28|APT3|Magic Hound"
|
||||
"T1078.003","Local Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","HAFNIUM|Turla|Operation Wocao|PROMETHIUM|Tropic Trooper|FIN10|Stolen Pencil|APT32"
|
||||
"T1078.002","Domain Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","Indrik Spider|Chimera|Operation Wocao|Sandworm Team|Wizard Spider|APT29|TA505|APT3|Threat Group-1314"
|
||||
"T1078.001","Default Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","no"
|
||||
"T1564.002","Hidden Users","Defense Evasion","no"
|
||||
"T1574.006","Dynamic Linker Hijacking","Persistence|Privilege Escalation|Defense Evasion","APT41|Rocke"
|
||||
"T1574.002","DLL Side-Loading","Persistence|Privilege Escalation|Defense Evasion","Mustang Panda|Higaisa|BlackTech|Sidewinder|Chimera|BRONZE BUTLER|Naikon|APT41|GALLIUM|Tropic Trooper|Patchwork|APT19|APT32|APT3|menuPass|Threat Group-3390"
|
||||
"T1574.001","DLL Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","Evilnum|APT41|Whitefly|RTM|Threat Group-3390|menuPass"
|
||||
"T1574.008","Path Interception by Search Order Hijacking","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574.007","Path Interception by PATH Environment Variable","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574.009","Path Interception by Unquoted Path","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574.011","Services Registry Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574.005","Executable Installer File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574.010","Services File Permissions Weakness","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1574","Hijack Execution Flow","Persistence|Privilege Escalation|Defense Evasion","no"
|
||||
"T1069.001","Local Groups","Discovery","Chimera|Operation Wocao|Turla|OilRig|admin@338"
|
||||
"T1570","Lateral Tool Transfer","Lateral Movement","Chimera|GALLIUM|Operation Wocao|APT32|Wizard Spider|Turla|FIN10"
|
||||
"T1568.003","DNS Calculation","Command And Control","APT12"
|
||||
"T1204.002","Malicious File","Execution","Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|Kimsuky|FIN6|PROMETHIUM|APT30|Windshift|APT33|Sandworm Team|Naikon|Whitefly|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Wizard Spider|Mofang|Frankenstein|RTM|Inception|BlackTech|APT-C-36|Machete|admin@338|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|BRONZE BUTLER|FIN7|Dragonfly 2.0|APT19|Dark Caracal|Cobalt Group|Gorgon Group|Patchwork|MuddyWater|DarkHydrus|OilRig|APT32|Rancor|Lazarus Group|APT29|APT28|APT37|FIN8|Elderwood|menuPass|PLATINUM|TA459|Leviathan"
|
||||
"T1204.001","Malicious Link","Execution","APT28|APT29|Mustang Panda|Sidewinder|ZIRCONIUM|MuddyWater|Evilnum|Sandworm Team|Wizard Spider|Patchwork|Windshift|APT32|Molerats|Mofang|BlackTech|TA505|OilRig|Machete|Leviathan|FIN8|FIN4|Elderwood|Dragonfly 2.0|Cobalt Group|APT39|Night Dragon|APT33|Turla"
|
||||
"T1195.003","Compromise Hardware Supply Chain","Initial Access","no"
|
||||
"T1195.002","Compromise Software Supply Chain","Initial Access","APT29|UNC2452|Cobalt Group|GOLD SOUTHFIELD|Dragonfly|Sandworm Team|APT41"
|
||||
"T1195.001","Compromise Software Dependencies and Development Tools","Initial Access","no"
|
||||
"T1568.001","Fast Flux DNS","Command And Control","menuPass|TA505"
|
||||
"T1052.001","Exfiltration over USB","Exfiltration","Mustang Panda|Tropic Trooper"
|
||||
"T1569.002","Service Execution","Execution","Chimera|Operation Wocao|Wizard Spider|Blue Mockingbird|APT39|APT41|Silence|FIN6|APT32|Honeybee|Ke3chang"
|
||||
"T1569.001","Launchctl","Execution","no"
|
||||
"T1569","System Services","Execution","no"
|
||||
"T1568.002","Domain Generation Algorithms","Command And Control","TA551|APT41"
|
||||
"T1568","Dynamic Resolution","Command And Control","APT29|UNC2452"
|
||||
"T1011.001","Exfiltration Over Bluetooth","Exfiltration","no"
|
||||
"T1567.002","Exfiltration to Cloud Storage","Exfiltration","ZIRCONIUM|HAFNIUM|Chimera|Leviathan|Turla"
|
||||
"T1567.001","Exfiltration to Code Repository","Exfiltration","no"
|
||||
"T1059.006","Python","Execution","ZIRCONIUM|MuddyWater|Turla|Operation Wocao|Kimsuky|APT29|Rocke|BRONZE BUTLER|APT39|Dragonfly 2.0|Machete"
|
||||
"T1059.005","Visual Basic","Execution","Mustang Panda|Windshift|Higaisa|Sidewinder|APT39|Machete|Operation Wocao|Kimsuky|Lazarus Group|APT33|Sandworm Team|Gamaredon Group|Sharpshooter|Molerats|Frankenstein|Inception|APT-C-36|Rancor|Patchwork|MuddyWater|Honeybee|FIN7|APT37|BRONZE BUTLER|APT32|Turla|TA505|Silence|WIRTE|FIN4|Cobalt Group|Gorgon Group|Leviathan|TA459|Magic Hound"
|
||||
"T1059.004","Unix Shell","Execution","Rocke|APT41"
|
||||
"T1059.003","Windows Command Shell","Execution","APT29|Mustang Panda|ZIRCONIUM|TA551|Higaisa|Indrik Spider|Chimera|UNC2452|Fox Kitten|Machete|Operation Wocao|Wizard Spider|FIN6|TA505|Blue Mockingbird|Tropic Trooper|Frankenstein|OilRig|Lazarus Group|Honeybee|Cobalt Group|FIN7|APT41|GALLIUM|Turla|Silence|APT32|Darkhotel|MuddyWater|APT18|APT38|Gorgon Group|Dark Caracal|Rancor|Ke3chang|Dragonfly 2.0|Leviathan|APT37|FIN8|APT28|Magic Hound|Sowbug|BRONZE BUTLER|FIN10|menuPass|Threat Group-3390|Gamaredon Group|Patchwork|Suckfly|Threat Group-1314|APT3|admin@338|APT1"
|
||||
"T1059.002","AppleScript","Execution","no"
|
||||
"T1059.001","PowerShell","Execution","Mustang Panda|Indrik Spider|HAFNIUM|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Sandworm Team|Operation Wocao|Lazarus Group|Chimera|Blue Mockingbird|APT39|DarkVishnya|Molerats|Wizard Spider|Frankenstein|Inception|Silence|APT41|Kimsuky|GALLIUM|TA505|WIRTE|TEMP.Veles|APT33|Gallmaker|Turla|APT19|Dragonfly 2.0|APT28|Thrip|Cobalt Group|DarkHydrus|Gorgon Group|Leviathan|TA459|MuddyWater|FIN8|Magic Hound|CopyKittens|OilRig|BRONZE BUTLER|FIN10|Threat Group-3390|APT32|FIN7|menuPass|Patchwork|Stealth Falcon|FIN6|Poseidon Group|APT3|APT29|Deep Panda"
|
||||
"T1567","Exfiltration Over Web Service","Exfiltration","APT28"
|
||||
"T1497.003","Time Based Evasion","Defense Evasion|Discovery","no"
|
||||
"T1497.002","User Activity Based Checks","Defense Evasion|Discovery","Darkhotel|FIN7"
|
||||
"T1497.001","System Checks","Defense Evasion|Discovery","Darkhotel|Evilnum|Frankenstein"
|
||||
"T1498.002","Reflection Amplification","Impact","no"
|
||||
"T1498.001","Direct Network Flood","Impact","no"
|
||||
"T1566.003","Spearphishing via Service","Initial Access","Ajax Security Team|Lazarus Group|Magic Hound|Windshift|FIN6|OilRig|Dark Caracal"
|
||||
"T1566.002","Spearphishing Link","Initial Access","Mustang Panda|ZIRCONIUM|MuddyWater|Sidewinder|Evilnum|Sandworm Team|Wizard Spider|APT1|Windshift|Molerats|Mofang|BlackTech|Machete|Kimsuky|TA505|Stolen Pencil|APT39|FIN4|APT32|Night Dragon|Cobalt Group|Turla|APT28|Dragonfly 2.0|OilRig|APT33|APT29|Leviathan|Elderwood|FIN8|Patchwork|Magic Hound"
|
||||
"T1566.001","Spearphishing Attachment","Initial Access","Ajax Security Team|Mustang Panda|TA551|Higaisa|Sidewinder|APT1|FIN6|APT30|Windshift|APT33|Sandworm Team|Naikon|Gamaredon Group|Sharpshooter|Molerats|Mofang|Wizard Spider|RTM|Frankenstein|Inception|BlackTech|APT-C-36|APT41|Machete|admin@338|Kimsuky|APT12|TA505|Silence|The White Company|APT39|FIN4|Darkhotel|Gallmaker|Tropic Trooper|Gorgon Group|Rancor|DarkHydrus|Cobalt Group|FIN7|APT19|Lazarus Group|OilRig|APT32|BRONZE BUTLER|Dragonfly 2.0|MuddyWater|APT28|FIN8|TA459|Elderwood|APT29|Leviathan|Patchwork|APT37|menuPass|PLATINUM"
|
||||
"T1566","Phishing","Initial Access","GOLD SOUTHFIELD|Dragonfly"
|
||||
"T1565.003","Runtime Data Manipulation","Impact","APT38"
|
||||
"T1565.002","Transmitted Data Manipulation","Impact","APT38"
|
||||
"T1565.001","Stored Data Manipulation","Impact","FIN4|APT38"
|
||||
"T1565","Data Manipulation","Impact","no"
|
||||
"T1564.001","Hidden Files and Directories","Defense Evasion","Mustang Panda|Rocke|APT32|Tropic Trooper|Lazarus Group|APT28"
|
||||
"T1564","Hide Artifacts","Defense Evasion","no"
|
||||
"T1563.002","RDP Hijacking","Lateral Movement","no"
|
||||
"T1563.001","SSH Hijacking","Lateral Movement","no"
|
||||
"T1563","Remote Service Session Hijacking","Lateral Movement","no"
|
||||
"T1518.001","Security Software Discovery","Discovery","Windshift|Sidewinder|Operation Wocao|Wizard Spider|Turla|Rocke|Frankenstein|The White Company|Cobalt Group|Darkhotel|MuddyWater|Tropic Trooper|FIN8|Patchwork|Naikon"
|
||||
"T1069.003","Cloud Groups","Discovery","no"
|
||||
"T1069.002","Domain Groups","Discovery","Turla|Inception|OilRig|Dragonfly 2.0|Ke3chang"
|
||||
"T1087.004","Cloud Account","Discovery","no"
|
||||
"T1087.003","Email Account","Discovery","Sandworm Team|TA505"
|
||||
"T1087.002","Domain Account","Discovery","MuddyWater|Fox Kitten|Operation Wocao|Wizard Spider|Chimera|Turla|Sandworm Team|Dragonfly 2.0|BRONZE BUTLER|OilRig|menuPass|FIN6|Poseidon Group|Ke3chang"
|
||||
"T1087.001","Local Account","Discovery","Chimera|Fox Kitten|Turla|Poseidon Group|OilRig|Ke3chang|APT32|APT1|Threat Group-3390|APT3|admin@338"
|
||||
"T1553.004","Install Root Certificate","Defense Evasion","no"
|
||||
"T1562.004","Disable or Modify System Firewall","Defense Evasion","APT29|UNC2452|Operation Wocao|Rocke|Lazarus Group|Kimsuky|Dragonfly 2.0|Carbanak"
|
||||
"T1562.003","Impair Command History Logging","Defense Evasion","no"
|
||||
"T1562.002","Disable Windows Event Logging","Defense Evasion","APT29|UNC2452|Threat Group-3390"
|
||||
"T1562.001","Disable or Modify Tools","Defense Evasion","APT29|MuddyWater|UNC2452|Wizard Spider|FIN6|Gamaredon Group|BRONZE BUTLER|Rocke|Kimsuky|Turla|Night Dragon|Gorgon Group|Lazarus Group|Putter Panda"
|
||||
"T1562","Impair Defenses","Defense Evasion","no"
|
||||
"T1003.004","LSA Secrets","Credential Access","OilRig|MuddyWater|menuPass|Leafminer|Ke3chang|Dragonfly 2.0|APT33|Threat Group-3390"
|
||||
"T1003.005","Cached Domain Credentials","Credential Access","OilRig|MuddyWater|Leafminer|APT33"
|
||||
"T1561.002","Disk Structure Wipe","Impact","Sandworm Team|Lazarus Group|APT38|APT37"
|
||||
"T1561.001","Disk Content Wipe","Impact","Lazarus Group"
|
||||
"T1561","Disk Wipe","Impact","no"
|
||||
"T1560.003","Archive via Custom Method","Collection","Mustang Panda|Lazarus Group|Kimsuky|CopyKittens|FIN6"
|
||||
"T1560.002","Archive via Library","Collection","Lazarus Group|Threat Group-3390"
|
||||
"T1560.001","Archive via Utility","Collection","APT29|Mustang Panda|HAFNIUM|UNC2452|Fox Kitten|Operation Wocao|Chimera|APT41|GALLIUM|Turla|Gallmaker|APT33|APT39|MuddyWater|Magic Hound|FIN8|BRONZE BUTLER|CopyKittens|Sowbug|APT3|menuPass|APT1|Ke3chang"
|
||||
"T1560","Archive Collected Data","Collection","menuPass|APT32|Honeybee|Patchwork|APT28|Dragonfly 2.0|FIN6|Lazarus Group|Ke3chang"
|
||||
"T1499.004","Application or System Exploitation","Impact","no"
|
||||
"T1499.003","Application Exhaustion Flood","Impact","no"
|
||||
"T1499.002","Service Exhaustion Flood","Impact","no"
|
||||
"T1499.001","OS Exhaustion Flood","Impact","no"
|
||||
"T1491.002","External Defacement","Impact","Sandworm Team"
|
||||
"T1491.001","Internal Defacement","Impact","Lazarus Group"
|
||||
"T1114.003","Email Forwarding Rule","Collection","Silent Librarian|Kimsuky"
|
||||
"T1114.002","Remote Email Collection","Collection","APT29|HAFNIUM|Chimera|UNC2452|APT1|FIN4|Dragonfly 2.0|APT28|Leafminer|Ke3chang"
|
||||
"T1114.001","Local Email Collection","Collection","Chimera|Magic Hound|APT1"
|
||||
"T1134.005","SID-History Injection","Defense Evasion|Privilege Escalation","no"
|
||||
"T1134.004","Parent PID Spoofing","Defense Evasion|Privilege Escalation","no"
|
||||
"T1134.003","Make and Impersonate Token","Defense Evasion|Privilege Escalation","no"
|
||||
"T1134.002","Create Process with Token","Defense Evasion|Privilege Escalation","Turla|Lazarus Group"
|
||||
"T1134.001","Token Impersonation/Theft","Defense Evasion|Privilege Escalation","APT28"
|
||||
"T1213.002","Sharepoint","Collection","Chimera|Ke3chang|APT28"
|
||||
"T1213.001","Confluence","Collection","no"
|
||||
"T1555.003","Credentials from Web Browsers","Credential Access","Ajax Security Team|ZIRCONIUM|FIN6|Sandworm Team|Inception|Stealth Falcon|OilRig|Leafminer|APT33|APT3|Kimsuky|TA505|Stolen Pencil|MuddyWater|APT37|Patchwork|Molerats"
|
||||
"T1555.002","Securityd Memory","Credential Access","no"
|
||||
"T1555.001","Keychain","Credential Access","no"
|
||||
"T1559.002","Dynamic Data Exchange","Execution","Sidewinder|Sharpshooter|TA505|MuddyWater|Gallmaker|Patchwork|Cobalt Group|APT37|APT28|FIN7"
|
||||
"T1559.001","Component Object Model","Execution","Gamaredon Group|MuddyWater"
|
||||
"T1559","Inter-Process Communication","Execution","no"
|
||||
"T1558.002","Silver Ticket","Credential Access","no"
|
||||
"T1558.001","Golden Ticket","Credential Access","Ke3chang"
|
||||
"T1558","Steal or Forge Kerberos Tickets","Credential Access","no"
|
||||
"T1557.001","LLMNR/NBT-NS Poisoning and SMB Relay","Credential Access|Collection","Wizard Spider"
|
||||
"T1557","Man-in-the-Middle","Credential Access|Collection","Kimsuky"
|
||||
"T1556.002","Password Filter DLL","Credential Access|Defense Evasion|Persistence","Strider"
|
||||
"T1556.001","Domain Controller Authentication","Credential Access|Defense Evasion|Persistence","Chimera"
|
||||
"T1556","Modify Authentication Process","Credential Access|Defense Evasion|Persistence","no"
|
||||
"T1056.004","Credential API Hooking","Collection|Credential Access","PLATINUM"
|
||||
"T1056.003","Web Portal Capture","Collection|Credential Access","no"
|
||||
"T1056.002","GUI Input Capture","Collection|Credential Access","FIN4"
|
||||
"T1056.001","Keylogging","Collection|Credential Access","Ajax Security Team|Operation Wocao|APT32|Sandworm Team|APT39|APT41|Kimsuky|menuPass|Stolen Pencil|FIN4|APT38|OilRig|Ke3chang|PLATINUM|Sowbug|Magic Hound|Group5|Lazarus Group|Threat Group-3390|APT3|Darkhotel|APT28"
|
||||
"T1555","Credentials from Password Stores","Credential Access","APT29|Evilnum|UNC2452|FIN6|APT39|OilRig|MuddyWater|Leafminer|APT33|Stealth Falcon"
|
||||
"T1552.005","Cloud Instance Metadata API","Credential Access","no"
|
||||
"T1003.008","/etc/passwd and /etc/shadow","Credential Access","no"
|
||||
"T1003.007","Proc Filesystem","Credential Access","no"
|
||||
"T1003.006","DCSync","Credential Access","APT29|UNC2452|Operation Wocao"
|
||||
"T1558.003","Kerberoasting","Credential Access","APT29|UNC2452|Operation Wocao|Wizard Spider"
|
||||
"T1552.006","Group Policy Preferences","Credential Access","APT33"
|
||||
"T1003.003","NTDS","Credential Access","Mustang Panda|HAFNIUM|Fox Kitten|menuPass|Wizard Spider|Chimera|FIN6|Dragonfly 2.0"
|
||||
"T1003.002","Security Account Manager","Credential Access","Wizard Spider|Threat Group-3390|Ke3chang|GALLIUM|Night Dragon|Dragonfly 2.0|menuPass"
|
||||
"T1003.001","LSASS Memory","Credential Access","HAFNIUM|Fox Kitten|Operation Wocao|Kimsuky|Sandworm Team|Whitefly|Blue Mockingbird|Silence|Threat Group-3390|Leviathan|APT41|GALLIUM|TEMP.Veles|APT33|APT39|Stolen Pencil|APT32|Leafminer|Magic Hound|Lazarus Group|MuddyWater|PLATINUM|FIN8|OilRig|BRONZE BUTLER|FIN6|APT3|APT28|APT1|Ke3chang|Cleaver"
|
||||
"T1110.004","Credential Stuffing","Credential Access","Chimera"
|
||||
"T1110.003","Password Spraying","Credential Access","Silent Librarian|Chimera|APT28|APT33|Leafminer|Lazarus Group"
|
||||
"T1110.002","Password Cracking","Credential Access","FIN6|APT41|Dragonfly 2.0|APT3"
|
||||
"T1110.001","Password Guessing","Credential Access","APT28"
|
||||
"T1021.006","Windows Remote Management","Lateral Movement","APT29|UNC2452|Chimera|Wizard Spider|Threat Group-3390"
|
||||
"T1021.005","VNC","Lateral Movement","Fox Kitten|GCMAN"
|
||||
"T1021.004","SSH","Lateral Movement","Fox Kitten|Rocke|TEMP.Veles|Leviathan|APT39|OilRig|menuPass|GCMAN"
|
||||
"T1021.003","Distributed Component Object Model","Lateral Movement","no"
|
||||
"T1021.002","SMB/Windows Admin Shares","Lateral Movement","Fox Kitten|APT41|Operation Wocao|Wizard Spider|Chimera|Blue Mockingbird|APT39|APT32|Orangeworm|FIN8|APT3|Lazarus Group|Threat Group-1314|Turla|Deep Panda|Ke3chang"
|
||||
"T1021.001","Remote Desktop Protocol","Lateral Movement","Fox Kitten|Chimera|Blue Mockingbird|Wizard Spider|Silence|APT41|TEMP.Veles|Leviathan|APT39|Stolen Pencil|Cobalt Group|Dragonfly 2.0|FIN8|APT3|OilRig|FIN10|menuPass|Patchwork|FIN6|Lazarus Group|APT1|Axiom"
|
||||
"T1554","Compromise Client Software Binary","Persistence","no"
|
||||
"T1036.006","Space after Filename","Defense Evasion","no"
|
||||
"T1036.005","Match Legitimate Name or Location","Defense Evasion","APT29|Mustang Panda|Sidewinder|Darkhotel|Lazarus Group|Indrik Spider|UNC2452|Fox Kitten|Machete|Chimera|PROMETHIUM|Rocke|Sandworm Team|APT39|Blue Mockingbird|Whitefly|Tropic Trooper|Silence|APT41|menuPass|TEMP.Veles|MuddyWater|BRONZE BUTLER|Sowbug|APT32|Patchwork|Poseidon Group|admin@338|Carbanak|APT1"
|
||||
"T1036.004","Masquerade Task or Service","Defense Evasion","ZIRCONIUM|APT29|Higaisa|UNC2452|Fox Kitten|Kimsuky|Lazarus Group|PROMETHIUM|Wizard Spider|APT-C-36|Carbanak|APT32|FIN6|FIN7"
|
||||
"T1036.003","Rename System Utilities","Defense Evasion","menuPass|APT32|GALLIUM"
|
||||
"T1036.002","Right-to-Left Override","Defense Evasion","BRONZE BUTLER|BlackTech|Ke3chang|Scarlet Mimic"
|
||||
"T1036.001","Invalid Code Signature","Defense Evasion","Windshift|APT37"
|
||||
"T1553.003","SIP and Trust Provider Hijacking","Defense Evasion","no"
|
||||
"T1553.002","Code Signing","Defense Evasion","APT29|GALLIUM|UNC2452|Wizard Spider|Kimsuky|PROMETHIUM|Patchwork|Silence|APT41|FIN6|TA505|FIN7|Honeybee|Leviathan|CopyKittens|Winnti Group|Suckfly|Molerats|Darkhotel"
|
||||
"T1553.001","Gatekeeper Bypass","Defense Evasion","no"
|
||||
"T1553","Subvert Trust Controls","Defense Evasion","no"
|
||||
"T1027.003","Steganography","Defense Evasion","TA551|BRONZE BUTLER|Tropic Trooper|MuddyWater|APT37"
|
||||
"T1027.002","Software Packing","Defense Evasion","ZIRCONIUM|Lazarus Group|TA505|Rocke|GALLIUM|The White Company|APT39|APT38|Dark Caracal|Elderwood|APT3|Patchwork|APT29|Night Dragon"
|
||||
"T1027.001","Binary Padding","Defense Evasion","Mustang Panda|Higaisa|Gamaredon Group|Patchwork|APT32|Leviathan|BRONZE BUTLER|Moafee"
|
||||
"T1222.002","Linux and Mac File and Directory Permissions Modification","Defense Evasion","Rocke|APT32"
|
||||
"T1222.001","Windows File and Directory Permissions Modification","Defense Evasion","Wizard Spider"
|
||||
"T1552.004","Private Keys","Credential Access","APT29|UNC2452|Operation Wocao|Rocke"
|
||||
"T1552.003","Bash History","Credential Access","no"
|
||||
"T1552.002","Credentials in Registry","Credential Access","APT32"
|
||||
"T1552.001","Credentials In Files","Credential Access","Fox Kitten|Leafminer|APT33|OilRig|TA505|Stolen Pencil|MuddyWater|APT3"
|
||||
"T1552","Unsecured Credentials","Credential Access","no"
|
||||
"T1216.001","PubPrn","Defense Evasion","APT32"
|
||||
"T1070.006","Timestomp","Defense Evasion","APT29|UNC2452|Chimera|Kimsuky|Rocke|TEMP.Veles|APT32|Lazarus Group|APT28"
|
||||
"T1070.005","Network Share Connection Removal","Defense Evasion","Threat Group-3390"
|
||||
"T1070.004","File Deletion","Defense Evasion","APT39|Mustang Panda|Chimera|Evilnum|UNC2452|Operation Wocao|FIN6|Sandworm Team|Rocke|Tropic Trooper|Gamaredon Group|Wizard Spider|APT41|Kimsuky|Silence|The White Company|TEMP.Veles|APT32|APT38|Patchwork|Honeybee|Cobalt Group|Dragonfly 2.0|menuPass|FIN8|OilRig|FIN5|BRONZE BUTLER|Magic Hound|APT3|Threat Group-3390|FIN10|APT28|Group5|Lazarus Group|APT18|APT29"
|
||||
"T1070.003","Clear Command History","Defense Evasion","APT41"
|
||||
"T1550.004","Web Session Cookie","Defense Evasion|Lateral Movement","APT29|UNC2452"
|
||||
"T1550.001","Application Access Token","Defense Evasion|Lateral Movement","APT28"
|
||||
"T1550.003","Pass the Ticket","Defense Evasion|Lateral Movement","APT32|BRONZE BUTLER|APT29"
|
||||
"T1550.002","Pass the Hash","Defense Evasion|Lateral Movement","Chimera|Kimsuky|GALLIUM|APT32|Night Dragon|APT28|APT1"
|
||||
"T1550","Use Alternate Authentication Material","Defense Evasion|Lateral Movement","APT29|UNC2452"
|
||||
"T1548.004","Elevated Execution with Prompt","Privilege Escalation|Defense Evasion","no"
|
||||
"T1548.003","Sudo and Sudo Caching","Privilege Escalation|Defense Evasion","no"
|
||||
"T1548.002","Bypass User Account Control","Privilege Escalation|Defense Evasion","Evilnum|APT37|MuddyWater|Honeybee|Cobalt Group|Threat Group-3390|BRONZE BUTLER|Patchwork|APT29"
|
||||
"T1548.001","Setuid and Setgid","Privilege Escalation|Defense Evasion","no"
|
||||
"T1548","Abuse Elevation Control Mechanism","Privilege Escalation|Defense Evasion","no"
|
||||
"T1136.003","Cloud Account","Persistence","no"
|
||||
"T1070.002","Clear Linux or Mac System Logs","Defense Evasion","Rocke"
|
||||
"T1070.001","Clear Windows Event Logs","Defense Evasion","Chimera|Operation Wocao|APT41|APT38|Dragonfly 2.0|APT32|FIN8|FIN5|APT28"
|
||||
"T1136.002","Domain Account","Persistence","HAFNIUM|GALLIUM"
|
||||
"T1136.001","Local Account","Persistence","Fox Kitten|APT39|APT41|Dragonfly 2.0|Leafminer|APT3"
|
||||
"T1547.011","Plist Modification","Persistence|Privilege Escalation","no"
|
||||
"T1547.010","Port Monitors","Persistence|Privilege Escalation","no"
|
||||
"T1547.009","Shortcut Modification","Persistence|Privilege Escalation","APT39|Darkhotel|APT29|Gorgon Group|Dragonfly 2.0|Lazarus Group|Leviathan"
|
||||
"T1547.008","LSASS Driver","Persistence|Privilege Escalation","no"
|
||||
"T1547.007","Re-opened Applications","Persistence|Privilege Escalation","no"
|
||||
"T1547.006","Kernel Modules and Extensions","Persistence|Privilege Escalation","no"
|
||||
"T1547.005","Security Support Provider","Persistence|Privilege Escalation","Lazarus Group"
|
||||
"T1547.004","Winlogon Helper DLL","Persistence|Privilege Escalation","Wizard Spider|Tropic Trooper|Turla"
|
||||
"T1547.003","Time Providers","Persistence|Privilege Escalation","no"
|
||||
"T1546.014","Emond","Privilege Escalation|Persistence","no"
|
||||
"T1546.013","PowerShell Profile","Privilege Escalation|Persistence","Turla"
|
||||
"T1546.012","Image File Execution Options Injection","Privilege Escalation|Persistence","TEMP.Veles"
|
||||
"T1218.008","Odbcconf","Defense Evasion","Cobalt Group"
|
||||
"T1546.011","Application Shimming","Privilege Escalation|Persistence","FIN7"
|
||||
"T1547.002","Authentication Package","Persistence|Privilege Escalation","no"
|
||||
"T1546.010","AppInit DLLs","Privilege Escalation|Persistence","APT39"
|
||||
"T1546.009","AppCert DLLs","Privilege Escalation|Persistence","Honeybee"
|
||||
"T1218.007","Msiexec","Defense Evasion","ZIRCONIUM|Molerats|Machete|TA505|Rancor"
|
||||
"T1546.008","Accessibility Features","Privilege Escalation|Persistence","Fox Kitten|APT41|APT3|APT29|Deep Panda|Axiom"
|
||||
"T1546.007","Netsh Helper DLL","Privilege Escalation|Persistence","no"
|
||||
"T1546.006","LC_LOAD_DYLIB Addition","Privilege Escalation|Persistence","no"
|
||||
"T1546.005","Trap","Privilege Escalation|Persistence","no"
|
||||
"T1546.004","Unix Shell Configuration Modification","Privilege Escalation|Persistence","no"
|
||||
"T1546.003","Windows Management Instrumentation Event Subscription","Privilege Escalation|Persistence","Mustang Panda|UNC2452|APT33|Blue Mockingbird|Turla|Leviathan|APT29"
|
||||
"T1546.002","Screensaver","Privilege Escalation|Persistence","no"
|
||||
"T1546.001","Change Default File Association","Privilege Escalation|Persistence","Kimsuky"
|
||||
"T1547.001","Registry Run Keys / Startup Folder","Persistence|Privilege Escalation","Windshift|Mustang Panda|ZIRCONIUM|Higaisa|Sidewinder|APT28|Wizard Spider|PROMETHIUM|Rocke|Tropic Trooper|Gamaredon Group|Sharpshooter|Molerats|Silence|RTM|Inception|APT41|Kimsuky|APT33|APT39|APT32|APT18|Turla|APT19|Honeybee|Dark Caracal|Threat Group-3390|Cobalt Group|Ke3chang|Gorgon Group|Dragonfly 2.0|APT37|MuddyWater|Leviathan|APT3|BRONZE BUTLER|Magic Hound|FIN7|FIN10|Patchwork|FIN6|Lazarus Group|Putter Panda|APT29|Darkhotel"
|
||||
"T1218.002","Control Panel","Defense Evasion","no"
|
||||
"T1218.010","Regsvr32","Defense Evasion","TA551|Blue Mockingbird|Inception|WIRTE|APT19|Cobalt Group|Leviathan|APT32|Deep Panda"
|
||||
"T1218.009","Regsvcs/Regasm","Defense Evasion","no"
|
||||
"T1218.005","Mshta","Defense Evasion","Mustang Panda|TA551|Sidewinder|Lazarus Group|Inception|Kimsuky|APT32|MuddyWater|FIN7"
|
||||
"T1218.004","InstallUtil","Defense Evasion","Mustang Panda|menuPass"
|
||||
"T1218.001","Compiled HTML File","Defense Evasion","APT41|Silence|Lazarus Group|Dark Caracal|OilRig"
|
||||
"T1218.003","CMSTP","Defense Evasion","Cobalt Group|MuddyWater"
|
||||
"T1218.011","Rundll32","Defense Evasion","HAFNIUM|TA551|UNC2452|APT41|Gamaredon Group|APT32|Sandworm Team|Blue Mockingbird|TA505|MuddyWater|APT29|APT19|CopyKittens|APT3|Carbanak|APT28"
|
||||
"T1547","Boot or Logon Autostart Execution","Persistence|Privilege Escalation","no"
|
||||
"T1546","Event Triggered Execution","Privilege Escalation|Persistence","no"
|
||||
"T1098.003","Add Office 365 Global Administrator Role","Persistence","no"
|
||||
"T1098.002","Exchange Email Delegate Permissions","Persistence","APT29|UNC2452|Magic Hound"
|
||||
"T1098.001","Additional Cloud Credentials","Persistence","APT29|UNC2452"
|
||||
"T1543.004","Launch Daemon","Persistence|Privilege Escalation","no"
|
||||
"T1543.003","Windows Service","Persistence|Privilege Escalation","PROMETHIUM|Blue Mockingbird|DarkVishnya|Wizard Spider|APT32|APT41|Kimsuky|Tropic Trooper|Cobalt Group|Ke3chang|FIN7|APT19|Honeybee|Threat Group-3390|APT3|Lazarus Group|Carbanak"
|
||||
"T1543.002","Systemd Service","Persistence|Privilege Escalation","Rocke"
|
||||
"T1543.001","Launch Agent","Persistence|Privilege Escalation","no"
|
||||
"T1037.005","Startup Items","Persistence|Privilege Escalation","no"
|
||||
"T1037.004","RC Scripts","Persistence|Privilege Escalation","no"
|
||||
"T1055.012","Process Hollowing","Defense Evasion|Privilege Escalation","Threat Group-3390|Gorgon Group|menuPass|Patchwork"
|
||||
"T1055.013","Process Doppelgänging","Defense Evasion|Privilege Escalation","Leafminer"
|
||||
"T1055.011","Extra Window Memory Injection","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.014","VDSO Hijacking","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.009","Proc Memory","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.008","Ptrace System Calls","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.005","Thread Local Storage","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.004","Asynchronous Procedure Call","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.003","Thread Execution Hijacking","Defense Evasion|Privilege Escalation","no"
|
||||
"T1055.002","Portable Executable Injection","Defense Evasion|Privilege Escalation","Rocke|Gorgon Group"
|
||||
"T1055.001","Dynamic-link Library Injection","Defense Evasion|Privilege Escalation","Wizard Spider|TA505|Turla|Tropic Trooper|Lazarus Group|Putter Panda"
|
||||
"T1037.003","Network Logon Script","Persistence|Privilege Escalation","no"
|
||||
"T1543","Create or Modify System Process","Persistence|Privilege Escalation","no"
|
||||
"T1037.002","Logon Script (Mac)","Persistence|Privilege Escalation","no"
|
||||
"T1037.001","Logon Script (Windows)","Persistence|Privilege Escalation","Cobalt Group|APT28"
|
||||
"T1542.003","Bootkit","Persistence|Defense Evasion","APT41|Lazarus Group|APT28"
|
||||
"T1542.002","Component Firmware","Persistence|Defense Evasion","Equation"
|
||||
"T1542.001","System Firmware","Persistence|Defense Evasion","no"
|
||||
"T1505.003","Web Shell","Persistence","Sandworm Team|HAFNIUM|Volatile Cedar|Fox Kitten|Operation Wocao|Kimsuky|Tropic Trooper|GALLIUM|Threat Group-3390|TEMP.Veles|Leviathan|APT39|Dragonfly 2.0|APT32|OilRig|Deep Panda"
|
||||
"T1505.002","Transport Agent","Persistence","no"
|
||||
"T1505.001","SQL Stored Procedures","Persistence","no"
|
||||
"T1053.003","Cron","Execution|Persistence|Privilege Escalation","Rocke"
|
||||
"T1053.004","Launchd","Execution|Persistence|Privilege Escalation","no"
|
||||
"T1053.001","At (Linux)","Execution|Persistence|Privilege Escalation","no"
|
||||
"T1053.005","Scheduled Task","Execution|Persistence|Privilege Escalation","Mustang Panda|Higaisa|UNC2452|Fox Kitten|Molerats|Machete|Operation Wocao|Chimera|Gamaredon Group|Blue Mockingbird|MuddyWater|Wizard Spider|Frankenstein|APT-C-36|BRONZE BUTLER|APT41|GALLIUM|Silence|TEMP.Veles|APT33|APT39|Cobalt Group|Rancor|Dragonfly 2.0|OilRig|Patchwork|FIN8|menuPass|FIN10|FIN7|APT32|Stealth Falcon|FIN6|APT3|APT29"
|
||||
"T1053.002","At (Windows)","Execution|Persistence|Privilege Escalation","BRONZE BUTLER|Threat Group-3390|APT18"
|
||||
"T1542","Pre-OS Boot","Defense Evasion|Persistence","no"
|
||||
"T1137.001","Office Template Macros","Persistence","MuddyWater"
|
||||
"T1137.004","Outlook Home Page","Persistence","OilRig"
|
||||
"T1137.003","Outlook Forms","Persistence","no"
|
||||
"T1137.005","Outlook Rules","Persistence","no"
|
||||
"T1137.006","Add-ins","Persistence","Naikon"
|
||||
"T1137.002","Office Test","Persistence","APT28"
|
||||
"T1531","Account Access Removal","Impact","no"
|
||||
"T1539","Steal Web Session Cookie","Credential Access","Evilnum"
|
||||
"T1529","System Shutdown/Reboot","Impact","Lazarus Group|APT38|APT37"
|
||||
"T1518","Software Discovery","Discovery","Mustang Panda|Windshift|MuddyWater|Windigo|Sidewinder|Operation Wocao|BRONZE BUTLER|Tropic Trooper|Inception"
|
||||
"T1547.013","XDG Autostart Entries","Persistence|Privilege Escalation","no"
|
||||
"T1534","Internal Spearphishing","Lateral Movement","Gamaredon Group"
|
||||
"T1528","Steal Application Access Token","Credential Access","APT28"
|
||||
"T1535","Unused/Unsupported Cloud Regions","Defense Evasion","no"
|
||||
"T1525","Implant Internal Image","Persistence","no"
|
||||
"T1538","Cloud Service Dashboard","Discovery","no"
|
||||
"T1530","Data from Cloud Storage Object","Collection","Fox Kitten"
|
||||
"T1578","Modify Cloud Compute Infrastructure","Defense Evasion","no"
|
||||
"T1537","Transfer Data to Cloud Account","Exfiltration","no"
|
||||
"T1526","Cloud Service Discovery","Discovery","no"
|
||||
"T1505","Server Software Component","Persistence","no"
|
||||
"T1499","Endpoint Denial of Service","Impact","Sandworm Team"
|
||||
"T1497","Virtualization/Sandbox Evasion","Defense Evasion|Discovery","Darkhotel"
|
||||
"T1498","Network Denial of Service","Impact","APT28"
|
||||
"T1496","Resource Hijacking","Impact","Blue Mockingbird|Rocke|APT41|Lazarus Group"
|
||||
"T1495","Firmware Corruption","Impact","no"
|
||||
"T1491","Defacement","Impact","no"
|
||||
"T1490","Inhibit System Recovery","Impact","no"
|
||||
"T1489","Service Stop","Impact","Wizard Spider|Lazarus Group"
|
||||
"T1486","Data Encrypted for Impact","Impact","Indrik Spider|APT41|TA505|APT38"
|
||||
"T1485","Data Destruction","Impact","Sandworm Team|Lazarus Group|APT38"
|
||||
"T1484","Domain Policy Modification","Defense Evasion|Privilege Escalation","no"
|
||||
"T1482","Domain Trust Discovery","Discovery","APT29|Chimera|UNC2452"
|
||||
"T1480","Execution Guardrails","Defense Evasion","no"
|
||||
"T1222","File and Directory Permissions Modification","Defense Evasion","no"
|
||||
"T1220","XSL Script Processing","Defense Evasion","Higaisa|Cobalt Group"
|
||||
"T1221","Template Injection","Defense Evasion","Gamaredon Group|Frankenstein|Inception|APT28|Tropic Trooper|Dragonfly 2.0|DarkHydrus"
|
||||
"T1189","Drive-by Compromise","Initial Access","Machete|Windigo|Dragonfly|PROMETHIUM|Turla|Windshift|RTM|Darkhotel|APT38|Dragonfly 2.0|Leafminer|Lazarus Group|BRONZE BUTLER|APT19|APT32|Threat Group-3390|Dark Caracal|Elderwood|APT37|Patchwork|PLATINUM"
|
||||
"T1190","Exploit Public-Facing Application","Initial Access","Volatile Cedar|UNC2452|Fox Kitten|Operation Wocao|APT28|APT29|GOLD SOUTHFIELD|Blue Mockingbird|Rocke|APT39|BlackTech|APT41|GALLIUM|Night Dragon|Axiom"
|
||||
"T1210","Exploitation of Remote Services","Lateral Movement","Fox Kitten|menuPass|Wizard Spider|Threat Group-3390|APT28"
|
||||
"T1217","Browser Bookmark Discovery","Discovery","Chimera|Fox Kitten"
|
||||
"T1213","Data from Information Repositories","Collection","Fox Kitten|FIN6|Turla"
|
||||
"T1197","BITS Jobs","Defense Evasion|Persistence","APT39|Patchwork|APT41|Leviathan"
|
||||
"T1219","Remote Access Software","Command And Control","Mustang Panda|MuddyWater|Evilnum|GOLD SOUTHFIELD|Sandworm Team|DarkVishnya|RTM|Kimsuky|Night Dragon|Thrip|Cobalt Group|Carbanak"
|
||||
"T1195","Supply Chain Compromise","Initial Access","no"
|
||||
"T1204","User Execution","Execution","no"
|
||||
"T1212","Exploitation for Credential Access","Credential Access","no"
|
||||
"T1211","Exploitation for Defense Evasion","Defense Evasion","APT28"
|
||||
"T1200","Hardware Additions","Initial Access","DarkVishnya"
|
||||
"T1202","Indirect Command Execution","Defense Evasion","no"
|
||||
"T1201","Password Policy Discovery","Discovery","Chimera|Turla|OilRig"
|
||||
"T1207","Rogue Domain Controller","Defense Evasion","no"
|
||||
"T1203","Exploitation for Client Execution","Execution","Mustang Panda|Darkhotel|Higaisa|HAFNIUM|Sidewinder|Sandworm Team|MuddyWater|Frankenstein|Inception|BlackTech|APT41|admin@338|Threat Group-3390|APT12|The White Company|APT33|APT32|APT28|Tropic Trooper|BRONZE BUTLER|Lazarus Group|Cobalt Group|APT37|Patchwork|APT29|TA459|Leviathan|Elderwood"
|
||||
"T1216","Signed Script Proxy Execution","Defense Evasion","no"
|
||||
"T1199","Trusted Relationship","Initial Access","Sandworm Team|GOLD SOUTHFIELD|APT28|menuPass"
|
||||
"T1218","Signed Binary Proxy Execution","Defense Evasion","no"
|
||||
"T1205","Traffic Signaling","Defense Evasion|Persistence|Command And Control","no"
|
||||
"T1176","Browser Extensions","Persistence","Kimsuky|Stolen Pencil"
|
||||
"T1175","Component Object Model and Distributed COM","Lateral Movement|Execution","no"
|
||||
"T1187","Forced Authentication","Credential Access","DarkHydrus|Dragonfly 2.0"
|
||||
"T1185","Man in the Browser","Collection","no"
|
||||
"T1149","LC_MAIN Hijacking","Defense Evasion","no"
|
||||
"T1134","Access Token Manipulation","Defense Evasion|Privilege Escalation","FIN6|Blue Mockingbird"
|
||||
"T1136","Create Account","Persistence","no"
|
||||
"T1137","Office Application Startup","Persistence","Gamaredon Group|APT32"
|
||||
"T1140","Deobfuscate/Decode Files or Information","Defense Evasion","APT39|APT29|ZIRCONIUM|Higaisa|UNC2452|Rocke|Sandworm Team|Gamaredon Group|Molerats|Frankenstein|Turla|WIRTE|Darkhotel|Tropic Trooper|Gorgon Group|menuPass|Honeybee|Threat Group-3390|APT19|Leviathan|MuddyWater|APT28|OilRig|BRONZE BUTLER"
|
||||
"T1135","Network Share Discovery","Discovery","Chimera|Operation Wocao|Wizard Spider|APT32|APT39|DarkVishnya|APT41|Tropic Trooper|APT1|Dragonfly 2.0|Sowbug"
|
||||
"T1153","Source","Execution","no"
|
||||
"T1133","External Remote Services","Persistence|Initial Access","APT29|UNC2452|Operation Wocao|Wizard Spider|Kimsuky|GOLD SOUTHFIELD|Chimera|Sandworm Team|APT41|GALLIUM|TEMP.Veles|Night Dragon|OilRig|Dragonfly 2.0|Ke3chang|FIN5|Threat Group-3390|APT18"
|
||||
"T1132","Data Encoding","Command And Control","no"
|
||||
"T1129","Shared Modules","Execution","no"
|
||||
"T1127","Trusted Developer Utilities Proxy Execution","Defense Evasion","no"
|
||||
"T1125","Video Capture","Collection","Silence|FIN7"
|
||||
"T1124","System Time Discovery","Discovery","Darkhotel|ZIRCONIUM|Higaisa|Sidewinder|Chimera|Operation Wocao|The White Company|Lazarus Group|BRONZE BUTLER|Turla"
|
||||
"T1123","Audio Capture","Collection","APT37"
|
||||
"T1120","Peripheral Device Discovery","Discovery","Operation Wocao|Turla|APT37|Gamaredon Group|Equation|APT28"
|
||||
"T1119","Automated Collection","Collection","Mustang Panda|Sidewinder|Chimera|menuPass|Operation Wocao|Gamaredon Group|Tropic Trooper|Frankenstein|APT1|APT28|Patchwork|OilRig|FIN5|Threat Group-3390|FIN6"
|
||||
"T1115","Clipboard Data","Collection","Operation Wocao|APT39|APT38"
|
||||
"T1114","Email Collection","Collection","Silent Librarian"
|
||||
"T1113","Screen Capture","Collection","GOLD SOUTHFIELD|Gamaredon Group|APT39|Silence|MuddyWater|OilRig|Dragonfly 2.0|Dark Caracal|FIN7|BRONZE BUTLER|Magic Hound|Group5|APT28"
|
||||
"T1112","Modify Registry","Defense Evasion","Operation Wocao|Kimsuky|Lazarus Group|Gamaredon Group|Blue Mockingbird|Wizard Spider|Silence|APT41|Turla|APT32|APT38|Dragonfly 2.0|APT19|Threat Group-3390|Patchwork|Gorgon Group|Honeybee|FIN8"
|
||||
"T1111","Two-Factor Authentication Interception","Credential Access","Chimera|Operation Wocao"
|
||||
"T1110","Brute Force","Credential Access","APT28|Fox Kitten|DarkVishnya|APT39|OilRig|FIN5|Turla"
|
||||
"T1108","Redundant Access","Defense Evasion|Persistence","no"
|
||||
"T1106","Native API","Execution","Higaisa|menuPass|Operation Wocao|Chimera|Gamaredon Group|Tropic Trooper|Sharpshooter|Turla|Silence|APT37|Gorgon Group"
|
||||
"T1105","Ingress Tool Transfer","Command And Control","HAFNIUM|APT29|Ajax Security Team|Mustang Panda|Windshift|Darkhotel|ZIRCONIUM|TA551|Volatile Cedar|Indrik Spider|Evilnum|Sidewinder|UNC2452|Fox Kitten|Kimsuky|Operation Wocao|Chimera|Sandworm Team|Whitefly|Rocke|APT39|Tropic Trooper|Sharpshooter|Molerats|Frankenstein|Silence|APT-C-36|APT41|GALLIUM|TA505|WIRTE|APT33|MuddyWater|APT18|APT38|Rancor|Cobalt Group|Gorgon Group|Turla|OilRig|Dragonfly 2.0|APT37|Leviathan|FIN8|PLATINUM|Elderwood|APT3|Magic Hound|APT32|BRONZE BUTLER|FIN7|menuPass|Gamaredon Group|Patchwork|Lazarus Group|Threat Group-3390|APT28"
|
||||
"T1104","Multi-Stage Channels","Command And Control","APT41|MuddyWater|APT3"
|
||||
"T1102","Web Service","Command And Control","Fox Kitten|Turla|APT32|Gamaredon Group|Rocke|Inception|FIN6"
|
||||
"T1098","Account Manipulation","Persistence","APT3|Dragonfly 2.0|Lazarus Group"
|
||||
"T1095","Non-Application Layer Protocol","Command And Control","HAFNIUM|Operation Wocao|FIN6|APT29|PLATINUM|APT3"
|
||||
"T1092","Communication Through Removable Media","Command And Control","APT28"
|
||||
"T1091","Replication Through Removable Media","Lateral Movement|Initial Access","Mustang Panda|Tropic Trooper|Darkhotel|APT28"
|
||||
"T1090","Proxy","Command And Control","Windigo|Fox Kitten|Operation Wocao|Sandworm Team|Blue Mockingbird|APT41|Turla"
|
||||
"T1087","Account Discovery","Discovery","APT29|UNC2452"
|
||||
"T1083","File and Directory Discovery","Discovery","APT29|Mustang Panda|Darkhotel|Windigo|Sidewinder|Chimera|UNC2452|Fox Kitten|menuPass|APT39|Sandworm Team|Operation Wocao|Gamaredon Group|Tropic Trooper|Inception|APT41|Kimsuky|APT32|MuddyWater|APT18|Dragonfly 2.0|Leafminer|Honeybee|Dark Caracal|Magic Hound|APT3|BRONZE BUTLER|Sowbug|APT28|Patchwork|Lazarus Group|Dust Storm|admin@338|Turla|Ke3chang"
|
||||
"T1082","System Information Discovery","Discovery","APT29|Mustang Panda|Windshift|ZIRCONIUM|Higaisa|Windigo|Sidewinder|UNC2452|Chimera|Operation Wocao|Wizard Spider|Rocke|Sandworm Team|Blue Mockingbird|Tropic Trooper|Frankenstein|Inception|Kimsuky|Darkhotel|MuddyWater|APT18|APT37|APT19|Honeybee|APT32|Magic Hound|Sowbug|OilRig|APT3|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|admin@338|Turla|Ke3chang"
|
||||
"T1080","Taint Shared Content","Lateral Movement","Gamaredon Group|BRONZE BUTLER|Darkhotel"
|
||||
"T1078","Valid Accounts","Defense Evasion|Persistence|Privilege Escalation|Initial Access","APT29|Silent Librarian|UNC2452|Fox Kitten|Operation Wocao|Chimera|Sandworm Team|Wizard Spider|Silence|APT41|GALLIUM|TEMP.Veles|APT39|FIN4|Night Dragon|Dragonfly 2.0|FIN8|APT33|Leviathan|OilRig|FIN5|menuPass|FIN10|APT28|Suckfly|FIN6|Threat Group-3390|APT18|PittyTiger|Carbanak"
|
||||
"T1074","Data Staged","Collection","Wizard Spider"
|
||||
"T1072","Software Deployment Tools","Execution|Lateral Movement","Silence|APT32|Threat Group-1314"
|
||||
"T1071","Application Layer Protocol","Command And Control","Rocke|Magic Hound|Dragonfly 2.0"
|
||||
"T1070","Indicator Removal on Host","Defense Evasion","APT29|UNC2452"
|
||||
"T1069","Permission Groups Discovery","Discovery","APT29|UNC2452|TA505|APT3"
|
||||
"T1068","Exploitation for Privilege Escalation","Privilege Escalation","ZIRCONIUM|Turla|Whitefly|APT33|Cobalt Group|PLATINUM|FIN8|APT32|Threat Group-3390|FIN6|APT28"
|
||||
"T1064","Scripting","Defense Evasion|Execution","no"
|
||||
"T1062","Hypervisor","Persistence","no"
|
||||
"T1061","Graphical User Interface","Execution","no"
|
||||
"T1059","Command and Scripting Interpreter","Execution","Windigo|Fox Kitten|APT32|Whitefly|APT39|Dragonfly 2.0|APT19|FIN7|OilRig|FIN5|Stealth Falcon|FIN6|Ke3chang"
|
||||
"T1057","Process Discovery","Discovery","APT29|Mustang Panda|Windshift|Higaisa|Sidewinder|Chimera|UNC2452|Operation Wocao|Rocke|Frankenstein|Inception|Darkhotel|MuddyWater|APT1|APT38|Tropic Trooper|APT37|Honeybee|OilRig|APT3|Magic Hound|APT28|Winnti Group|Stealth Falcon|Poseidon Group|Lazarus Group|Molerats|Turla|Deep Panda|Ke3chang"
|
||||
"T1056","Input Capture","Collection|Credential Access","APT39"
|
||||
"T1055","Process Injection","Defense Evasion|Privilege Escalation","Operation Wocao|APT32|Sharpshooter|Silence|APT41|Kimsuky|Turla|Cobalt Group|APT37|Honeybee|PLATINUM"
|
||||
"T1053","Scheduled Task/Job","Execution|Persistence|Privilege Escalation","no"
|
||||
"T1052","Exfiltration Over Physical Medium","Exfiltration","no"
|
||||
"T1051","Shared Webroot","Lateral Movement","no"
|
||||
"T1049","System Network Connections Discovery","Discovery","Mustang Panda|MuddyWater|Chimera|Sandworm Team|Operation Wocao|Tropic Trooper|APT41|APT38|GALLIUM|APT32|APT1|APT3|OilRig|menuPass|Threat Group-3390|Poseidon Group|admin@338|Turla|Ke3chang"
|
||||
"T1048","Exfiltration Over Alternative Protocol","Exfiltration","no"
|
||||
"T1047","Windows Management Instrumentation","Execution","Mustang Panda|Windshift|UNC2452|Operation Wocao|Chimera|Blue Mockingbird|Wizard Spider|Frankenstein|APT41|FIN6|GALLIUM|APT32|MuddyWater|OilRig|Threat Group-3390|Leviathan|FIN8|menuPass|Stealth Falcon|Lazarus Group|APT29|Deep Panda"
|
||||
"T1046","Network Service Scanning","Discovery","Chimera|Fox Kitten|Operation Wocao|Rocke|DarkVishnya|APT41|Tropic Trooper|APT39|APT32|OilRig|Leafminer|Cobalt Group|menuPass|Suckfly|FIN6|Threat Group-3390"
|
||||
"T1043","Commonly Used Port","Command And Control","OilRig|APT28|TEMP.Veles|Night Dragon|APT29|APT18|APT19|FIN7|Dragonfly 2.0|FIN8|APT37|Magic Hound|APT3|Lazarus Group|Threat Group-3390"
|
||||
"T1041","Exfiltration Over C2 Channel","Exfiltration","ZIRCONIUM|Higaisa|Chimera|APT39|Operation Wocao|Sandworm Team|MuddyWater|Wizard Spider|Frankenstein|Kimsuky|GALLIUM|APT32|APT3|Gamaredon Group|Stealth Falcon|Lazarus Group|Ke3chang"
|
||||
"T1040","Network Sniffing","Credential Access|Discovery","Kimsuky|Sandworm Team|DarkVishnya|APT33|Stolen Pencil|APT28"
|
||||
"T1039","Data from Network Shared Drive","Collection","Chimera|Fox Kitten|Gamaredon Group|Sowbug|BRONZE BUTLER|menuPass"
|
||||
"T1037","Boot or Logon Initialization Scripts","Persistence|Privilege Escalation","Rocke"
|
||||
"T1036","Masquerading","Defense Evasion","APT29|Mustang Panda|ZIRCONIUM|TA551|UNC2452|Windshift|APT32|BRONZE BUTLER|menuPass|PLATINUM|Dragonfly 2.0"
|
||||
"T1034","Path Interception","Persistence|Privilege Escalation","no"
|
||||
"T1033","System Owner/User Discovery","Discovery","Windshift|ZIRCONIUM|Sidewinder|Chimera|Sandworm Team|Operation Wocao|Wizard Spider|Frankenstein|APT41|GALLIUM|Tropic Trooper|APT39|MuddyWater|APT32|APT37|APT19|Dragonfly 2.0|OilRig|Magic Hound|FIN10|Gamaredon Group|Patchwork|Stealth Falcon|Lazarus Group|APT3"
|
||||
"T1030","Data Transfer Size Limits","Exfiltration","Threat Group-3390"
|
||||
"T1029","Scheduled Transfer","Exfiltration","Higaisa"
|
||||
"T1027","Obfuscated Files or Information","Defense Evasion","APT39|Mustang Panda|Windshift|TA551|Higaisa|Sidewinder|UNC2452|Fox Kitten|GOLD SOUTHFIELD|Operation Wocao|Kimsuky|FIN6|Chimera|Gamaredon Group|Rocke|Sandworm Team|Blue Mockingbird|Whitefly|Molerats|Wizard Spider|Mofang|Frankenstein|Inception|APT-C-36|APT41|GALLIUM|Turla|TA505|Silence|APT33|Night Dragon|Darkhotel|Gallmaker|APT29|APT18|Tropic Trooper|Patchwork|APT37|Honeybee|menuPass|Leafminer|Cobalt Group|Threat Group-3390|Dark Caracal|APT19|FIN8|BlackOasis|MuddyWater|Elderwood|Leviathan|FIN7|Magic Hound|OilRig|APT3|APT32|Group5|Dust Storm|Lazarus Group|Putter Panda|APT28"
|
||||
"T1026","Multiband Communication","Command And Control","Lazarus Group"
|
||||
"T1025","Data from Removable Media","Collection","Turla|Gamaredon Group|APT28"
|
||||
"T1021","Remote Services","Lateral Movement","no"
|
||||
"T1020","Automated Exfiltration","Exfiltration","Sidewinder|Gamaredon Group|Tropic Trooper|Frankenstein|Honeybee"
|
||||
"T1018","Remote System Discovery","Discovery","APT29|UNC2452|Chimera|Fox Kitten|Operation Wocao|Sandworm Team|Rocke|Wizard Spider|Silence|GALLIUM|APT39|APT32|Dragonfly 2.0|Deep Panda|Threat Group-3390|Leafminer|Ke3chang|FIN8|FIN5|APT3|BRONZE BUTLER|menuPass|FIN6|Turla"
|
||||
"T1016","System Network Configuration Discovery","Discovery","ZIRCONIUM|Mustang Panda|Higaisa|Sidewinder|Chimera|Operation Wocao|Wizard Spider|Sandworm Team|Tropic Trooper|Frankenstein|APT41|GALLIUM|APT32|Darkhotel|MuddyWater|APT1|APT19|Dragonfly 2.0|OilRig|Magic Hound|menuPass|Threat Group-3390|Stealth Falcon|Lazarus Group|APT3|Naikon|admin@338|Turla|Ke3chang"
|
||||
"T1014","Rootkit","Defense Evasion","Rocke|APT41|APT28|Winnti Group"
|
||||
"T1012","Query Registry","Discovery","ZIRCONIUM|Chimera|Fox Kitten|APT39|Operation Wocao|APT32|Dragonfly 2.0|Threat Group-3390|OilRig|Stealth Falcon|Lazarus Group|Turla"
|
||||
"T1011","Exfiltration Over Other Network Medium","Exfiltration","no"
|
||||
"T1010","Application Window Discovery","Discovery","Lazarus Group"
|
||||
"T1008","Fallback Channels","Command And Control","Carbanak|APT41|OilRig|Lazarus Group"
|
||||
"T1007","System Service Discovery","Discovery","Chimera|Operation Wocao|BRONZE BUTLER|APT1|OilRig|Poseidon Group|admin@338|Turla|Ke3chang"
|
||||
"T1006","Direct Volume Access","Defense Evasion","no"
|
||||
"T1005","Data from Local System","Collection","APT29|Windigo|UNC2452|Fox Kitten|Sandworm Team|Operation Wocao|FIN6|Gamaredon Group|APT39|Frankenstein|Inception|Kimsuky|GALLIUM|Turla|menuPass|Dragonfly 2.0|Dark Caracal|Honeybee|APT37|APT28|APT3|BRONZE BUTLER|Patchwork|Stealth Falcon|Lazarus Group|Dust Storm|Threat Group-3390|APT1|Ke3chang"
|
||||
"T1003","OS Credential Dumping","Credential Access","APT39|Frankenstein|APT32|APT28|Leviathan|Sowbug|Suckfly|Poseidon Group|Axiom"
|
||||
"T1001","Data Obfuscation","Command And Control","Operation Wocao|Axiom"
|
||||
|
@@ -1 +0,0 @@
|
||||
arn,latestCount,numDataPoints,avgApiCalls,stdevApiCalls
|
||||
|
@@ -1 +0,0 @@
|
||||
bucket_name,remote_ip,earliest,latest
|
||||
|
@@ -1 +0,0 @@
|
||||
earliest,latest,userName,eventName
|
||||
|
@@ -1 +0,0 @@
|
||||
firstTime,lastTime,requestingAccountId,requestedAccountId
|
||||
|
@@ -1 +0,0 @@
|
||||
earliest,latest,awsRegion
|
||||
|
@@ -1 +0,0 @@
|
||||
firstTime,lastTime,process
|
||||
|
@@ -1 +0,0 @@
|
||||
arn,firstTime,lastTime
|
||||
|
@@ -1,17 +0,0 @@
|
||||
prohibited_applications,isProhibited
|
||||
winword.exe,prohibited
|
||||
EXCEL.EXE,prohibited
|
||||
OUTLOOK.EXE,prohibited
|
||||
POWERPNT.EXE,prohibited
|
||||
visio.exe,prohibited
|
||||
mspub.exe,prohibited
|
||||
Acrobat.exe,prohibited
|
||||
Acrord32.exe,prohibited
|
||||
chrome.exe,prohibited
|
||||
iexplore.exe,prohibited
|
||||
opera.exe,prohibited
|
||||
firefox.exe,prohibited
|
||||
java.exe,prohibited
|
||||
powershell.exe,prohibited
|
||||
mshta.exe, prohibited
|
||||
zoom.exe,prohibitied
|
||||
|
-20
@@ -1,20 +0,0 @@
|
||||
app,note
|
||||
remcom.exe,ESCU - This process is an open source replacement to psexec and is not typically seen in an enterprise environment.
|
||||
pwdump.exe,ESCU - This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
pwdump2.exe,ESCU - This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
nc.exe,ESCU - This process is an open source tool used for network communications.
|
||||
wce.exe,ESCU - This process is associated with a tool used to dump hashes and execute pass-the-hash and pass-the-ticket attacks.
|
||||
cain.exe,ESCU - This process is associated with a tool used to collect user credentials and execute attacks.
|
||||
nmap.exe,ESCU - This process is an open source network mapping tool used to identify hosts and listening services on a network.
|
||||
kidlogger.exe,ESCU - This process is associated with a tool used to collect keyboard input on a host.
|
||||
isass.exe,ESCU - This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
svch0st.exe,ESCU - This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
at.exe,ESCU - This process is used to schedule other processes to run. schtasks.exe should be used instead as it provides more flexibility.
|
||||
getmail.exe,ESCU - This process is seen to be used by attackers to extract email files from host machines.
|
||||
ntdll.exe,ESCU - This process was identified as malicious by DHS Alert TA18-074A.
|
||||
netpass.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and attackers use this tool to recover all network passwords stored on your system for the current logged-on user.
|
||||
WebBrowserPassView.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and is used by attackers as a password recovery tool that reveals the passwords stored in Web Browsers.
|
||||
OutlookAddressBookView.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and is used by attackers to steal the details of all recipients stored in the address books of Microsoft Outlook.
|
||||
mailpv.exe,ESCU - This process was identified by DHS Alert TA18-201A and attackers use this tool is a password-recovery tool that reveals the passwords and other account details from various email clients.
|
||||
NLBrute.exe,ESCU - This process was identified in the SamSam Ransomware Campaign and attackers use this tool to brute force RDP instances with a range of commonly used passwords.
|
||||
selfdel.exe,ESCU - This executable was delivered in the SamSam Ransomware Campain and the attackers levereged this binary to delete its malicilous activities.
|
||||
|
-20
@@ -1,20 +0,0 @@
|
||||
app,note
|
||||
remcom.exe,ESCU - This process is an open source replacement to psexec and is not typically seen in an enterprise environment.
|
||||
pwdump.exe,ESCU - This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
pwdump2.exe,ESCU - This process is associated with a tool used to dump password hashes on a Windows system.
|
||||
nc.exe,ESCU - This process is an open source tool used for network communications.
|
||||
wce.exe,ESCU - This process is associated with a tool used to dump hashes and execute pass-the-hash and pass-the-ticket attacks.
|
||||
cain.exe,ESCU - This process is associated with a tool used to collect user credentials and execute attacks.
|
||||
nmap.exe,ESCU - This process is an open source network mapping tool used to identify hosts and listening services on a network.
|
||||
kidlogger.exe,ESCU - This process is associated with a tool used to collect keyboard input on a host.
|
||||
isass.exe,ESCU - This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
svch0st.exe,ESCU - This process name is used by attackers to hide in plain sight and look like a legitimate Windows system process.
|
||||
at.exe,ESCU - This process is used to schedule other processes to run. schtasks.exe should be used instead as it provides more flexibility.
|
||||
getmail.exe,ESCU - This process is seen to be used by attackers to extract email files from host machines.
|
||||
ntdll.exe,ESCU - This process was identified as malicious by DHS Alert TA18-074A.
|
||||
netpass.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and attackers use this tool to recover all network passwords stored on your system for the current logged-on user.
|
||||
WebBrowserPassView.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and is used by attackers as a password recovery tool that reveals the passwords stored in Web Browsers.
|
||||
OutlookAddressBookView.exe,ESCU - This process was identified as malicious by DHS Alert TA18-201A and is used by attackers to steal the details of all recipients stored in the address books of Microsoft Outlook.
|
||||
mailpv.exe,ESCU - This process was identified by DHS Alert TA18-201A and attackers use this tool is a password-recovery tool that reveals the passwords and other account details from various email clients.
|
||||
NLBrute.exe,ESCU - This process was identified in the SamSam Ransomware Campaign and attackers use this tool to brute force RDP instances with a range of commonly used passwords.
|
||||
selfdel.exe,ESCU - This executable was delivered in the SamSam Ransomware Campain and the attackers levereged this binary to delete its malicilous activities.
|
||||
|
-299
@@ -1,299 +0,0 @@
|
||||
Extensions,Name
|
||||
.enc,.CryptoHasYou.
|
||||
.777,777
|
||||
.R4A,7ev3n
|
||||
.R5A,7ev3n
|
||||
.7h9r,7h9r
|
||||
.8lock8,8lock8
|
||||
.encrypt,Alpha Ransomware
|
||||
.amba,AMBA
|
||||
.adk,Angry Duck
|
||||
.encrypted,Apocalypse
|
||||
.SecureCrypted,Apocalypse
|
||||
.FuckYourData,Apocalypse
|
||||
.unavailable,Apocalypse
|
||||
.bleepYourFiles,Apocalypse
|
||||
.Where_my_files.txt,Apocalypse
|
||||
.encrypted,ApocalypseVM
|
||||
.locked,ApocalypseVM
|
||||
.locky,AutoLocky
|
||||
.adr,BaksoCrypt
|
||||
.bart.zip,Bart
|
||||
.bart,Bart
|
||||
.perl,Bart
|
||||
.clf,BitCryptor
|
||||
.bitstak,BitStak
|
||||
.Silent,BlackShades Crypter
|
||||
.blocatto,Blocatto
|
||||
.lock,Brazilian
|
||||
.cry,Central Security Treatment Organization
|
||||
.cerber,Cerber
|
||||
.cerber2,Cerber
|
||||
.cerber3,Cerber
|
||||
.clf,CoinVault
|
||||
.coverton,Coverton
|
||||
.enigma,Coverton
|
||||
.czvxce,Coverton
|
||||
.criptiko,CryFile
|
||||
.criptoko,CryFile
|
||||
.criptokod,CryFile
|
||||
.cripttt,CryFile
|
||||
.aga,CryFile
|
||||
.cry,CryLocker
|
||||
.ENCRYPTED,Crypren
|
||||
.crypt38,Crypt38
|
||||
.scl,CryptFIle2
|
||||
.crinf,CryptInfinite
|
||||
.frtrss,CryptoFortress
|
||||
.clf,CryptoGraphic Locker
|
||||
.crjoker,CryptoJoker
|
||||
.encrypted ,CryptoLocker
|
||||
.ENC,CryptoLocker
|
||||
.code,CryptoMix
|
||||
.scl,CryptoMix
|
||||
.crptrgr,CryptoRoger
|
||||
.locked,CryptoShocker
|
||||
.CryptoTorLocker2015!,CryptoTorLocker2015
|
||||
.crypt,CryptXXX
|
||||
.crypt,CryptXXX 2.0
|
||||
.crypt,CryptXXX 3.0
|
||||
.cryp1,CryptXXX 3.0
|
||||
.crypz,CryptXXX 3.0
|
||||
.cryptz,CryptXXX 3.0
|
||||
.cryp1,CryptXXX 3.1
|
||||
.ctbl,CTB-Locker
|
||||
.encrypted,CuteRansomware
|
||||
.ded,DEDCryptor
|
||||
.domino,Domino
|
||||
.locked,EDA2 / HiddenTear
|
||||
.isis,EduCrypt
|
||||
.locked,EduCrypt
|
||||
.ha3,El-Polocker
|
||||
.enigma,Enigma
|
||||
.1txt,Enigma
|
||||
.exotic,Exotic
|
||||
.locked,Fakben
|
||||
.fantom,Fantom
|
||||
.Z81928819,GhostCrypt
|
||||
.purge,Globe v1
|
||||
.globe,Globe v3
|
||||
.locked,GNL Locker
|
||||
.crypt,Gomasom
|
||||
.herbst,Herbst
|
||||
.cry,Hi Buddy!
|
||||
.locky,Hucky
|
||||
.crime,iLock
|
||||
.crime,iLockLight
|
||||
.btc,Jigsaw
|
||||
.kkk,Jigsaw
|
||||
.fun,Jigsaw
|
||||
.gws,Jigsaw
|
||||
.porno,Jigsaw
|
||||
.payransom,Jigsaw
|
||||
.payms,Jigsaw
|
||||
.paymst,Jigsaw
|
||||
.AFD,Jigsaw
|
||||
.paybtcs,Jigsaw
|
||||
.epic,Jigsaw
|
||||
.xyz,Jigsaw
|
||||
.locked,Job Crypter
|
||||
.encrypted,KeRanger
|
||||
.keybtc@inbox_com,KeyBTC
|
||||
.rip,Killer Locker
|
||||
.kimcilware,KimcilWare
|
||||
.locked,KimcilWare
|
||||
.kostya,Kostya
|
||||
.kratos,KratosCrypt
|
||||
.LeChiffre,LeChiffre
|
||||
.locky,Locky
|
||||
.zepto,Locky
|
||||
.odin,Locky
|
||||
.shit,Locky
|
||||
.thor,Locky
|
||||
.asier,Locky
|
||||
.zzzzz,Locky
|
||||
.osiris,Locky
|
||||
.lock93,Lock93
|
||||
.crime,Lortok
|
||||
.oor,LowLevel04
|
||||
.magic,Magic
|
||||
.Lock,MIRCOP
|
||||
.fucked,MireWare
|
||||
.fuck,MireWare
|
||||
.locked,MM Locker
|
||||
.KEYZ,Mobef
|
||||
.KEYH0LES,Mobef
|
||||
.crypted,Nemucod
|
||||
.odcodc,ODCODC
|
||||
.cbf,Offline ransomware
|
||||
.LOL!,OMG! Ransomware
|
||||
.OMG!,OMG! Ransomware
|
||||
.padcrypt,PadCrypt
|
||||
.locked,Philadelphia
|
||||
.locked,PokemonGO
|
||||
.filock,Popcorn Time
|
||||
.locky,PowerWare
|
||||
.crypt,R980
|
||||
.locked,RAA encryptor
|
||||
.RDM,Radamant
|
||||
.RRK,Radamant
|
||||
.RAD,Radamant
|
||||
.RADAMANT,Radamant
|
||||
.locked,Rakhni
|
||||
.kraken,Rakhni
|
||||
.darkness,Rakhni
|
||||
.nochance,Rakhni
|
||||
.oshit,Rakhni
|
||||
.oplata@qq_com,Rakhni
|
||||
.relock@qq_com,Rakhni
|
||||
.crypto,Rakhni
|
||||
.helpdecrypt@ukr.net,Rakhni
|
||||
.pizda@qq_com,Rakhni
|
||||
.dyatel@qq_com,Rakhni
|
||||
._ryp,Rakhni
|
||||
.nalog@qq_com,Rakhni
|
||||
.chifrator@qq_com,Rakhni
|
||||
.gruzin@qq_com,Rakhni
|
||||
.troyancoder@qq_com,Rakhni
|
||||
.encrypted,Rakhni
|
||||
.cry,Rakhni
|
||||
.AES256,Rakhni
|
||||
.enc,Rakhni
|
||||
.hb15,Rakhni
|
||||
.vscrypt,Rector
|
||||
.infected,Rector
|
||||
.bloc,Rector
|
||||
.korrektor,Rector
|
||||
.rekt,RektLocker
|
||||
.remind,RemindMe
|
||||
.crashed,RemindMe
|
||||
.rokku,Rokku
|
||||
.encryptedAES,Samas-Samsam
|
||||
.encryptedRSA,Samas-Samsam
|
||||
.encedRSA,Samas-Samsam
|
||||
.justbtcwillhelpyou,Samas-Samsam
|
||||
.btcbtcbtc,Samas-Samsam
|
||||
.btc-help-you,Samas-Samsam
|
||||
.only-we_can-help_you,Samas-Samsam
|
||||
.iwanthelpuuu,Samas-Samsam
|
||||
.notfoundrans,Samas-Samsam
|
||||
.encmywork,Samas-Samsam
|
||||
.weapologize,Samas-Samsam
|
||||
.stubbin,Samas-Samsam
|
||||
.areyoulovemyrans,Samas-Samsam
|
||||
.loveransisgood,Samas-Samsam
|
||||
.myransext2017,Samas-Samsam
|
||||
.disposed2017,Samas-Samsam
|
||||
.prosperous666,Samas-Samsam
|
||||
.supported2017,Samas-Samsam
|
||||
.country82000,Samas-Samsam
|
||||
.moments2900,Samas-Samsam
|
||||
.breeding123,Samas-Samsam
|
||||
.mention9823,Samas-Samsam
|
||||
.suppose666,Samas-Samsam
|
||||
.skjdthghh,Samas-Samsam
|
||||
.cifgksaffsfyghd,Samas-Samsam
|
||||
.iaufkakfhsaraf,Samas-Samsam
|
||||
.filegofprencrp,Samas-Samsam
|
||||
.weencedufiles,Samas-Samsam
|
||||
.encryptedyourfiles,Samas-Samsam
|
||||
.letmetrydecfiles,Samas-Samsam
|
||||
.otherinformation,Samas-Samsam
|
||||
.weareyourfriends,Samas-Samsam
|
||||
.noproblemwedecfiles,Samas-Samsam
|
||||
.powerfulldecrypt,Samas-Samsam
|
||||
.wowreadfordecryp,Samas-Samsam
|
||||
.wowwhereismyfiles,Samas-Samsam
|
||||
.helpmeencedfiles,Samas-Samsam
|
||||
.theworldisyours,Samas-Samsam
|
||||
.vekanhelpu,Samas-Samsam
|
||||
.howcanihelpusir,Samas-Samsam
|
||||
.VforVendetta,Samas-Samsam
|
||||
.checkdiskenced,Samas-Samsam
|
||||
.goforhelp,Samas-Samsam
|
||||
.iloveworld,Samas-Samsam
|
||||
.canihelpyou,Samas-Samsam
|
||||
.AreYouLoveMyRansFile,Samas-Samsam
|
||||
.fucku,Samas-Samsam
|
||||
.happenencedfiles,Samas-Samsam
|
||||
.iwishiyou,Samas-Samsam
|
||||
.powerfulldecryp,Samas-Samsam
|
||||
.suppose665,Samas-Samsam
|
||||
.Whereisyourfiles,Samas-Samsam
|
||||
.sanction,Sanction
|
||||
.locked,Shark
|
||||
.shino,ShinoLocker
|
||||
.locked,SkidLocker / Pompous
|
||||
.encrypted,Smrss32
|
||||
.RSNSlocked,SNSLocker
|
||||
.RSplited,SNSLocker
|
||||
.sport,Sport
|
||||
.locked,Stampado
|
||||
.locked,Strictor
|
||||
.surprise,Surprise
|
||||
.tzu,Surprise
|
||||
.szf,SZFLocker
|
||||
.xcri,TeleCrypt
|
||||
.vvv,TeslaCrypt 0.x - 2.2.0
|
||||
.ecc,TeslaCrypt 0.x - 2.2.0
|
||||
.exx,TeslaCrypt 0.x - 2.2.0
|
||||
.ezz,TeslaCrypt 0.x - 2.2.0
|
||||
.abc,TeslaCrypt 0.x - 2.2.0
|
||||
.aaa,TeslaCrypt 0.x - 2.2.0
|
||||
.zzz,TeslaCrypt 0.x - 2.2.0
|
||||
.xyz,TeslaCrypt 0.x - 2.2.0
|
||||
.micro,TeslaCrypt 3.0+
|
||||
.xxx,TeslaCrypt 3.0+
|
||||
.ttt,TeslaCrypt 3.0+
|
||||
.mp3,TeslaCrypt 3.0+
|
||||
.Encrypted,TorrentLocker
|
||||
.enc,TorrentLocker
|
||||
.toxcrypt,Toxcrypt
|
||||
.better_call_saul,Troldesh
|
||||
.xtbl,Troldesh
|
||||
.da_vinci_code,Troldesh
|
||||
.windows10,Troldesh
|
||||
.enc,TrueCrypter
|
||||
.locked,Turkish Ransom
|
||||
.H3LL,Ungluk
|
||||
.0x0,Ungluk
|
||||
.1999,Ungluk
|
||||
.CRRRT,Unlock92
|
||||
.CCCRRRPPP,Unlock92
|
||||
.vault,VaultCrypt
|
||||
.xort,VaultCrypt
|
||||
.trun,VaultCrypt
|
||||
.Venusf,VenusLocker
|
||||
.Venusp,VenusLocker
|
||||
.CrySiS,Virus-Encoder
|
||||
.xtbl,Virus-Encoder
|
||||
.wflx,WildFire Locker
|
||||
.EnCiPhErEd,Xorist
|
||||
.73i87A,Xorist
|
||||
.p5tkjw,Xorist
|
||||
.PoAr2w,Xorist
|
||||
.fileiscryptedhard,Xorist
|
||||
.encoderpass,Xorist
|
||||
.zc3791,Xorist
|
||||
.xrtn,XRTN
|
||||
.zcrypt,Zcrypt
|
||||
.crypto,Zimbra
|
||||
.vault,Zlader / Russian
|
||||
.zyklon,Zyklon
|
||||
.wncry,WannaCry
|
||||
.wcry,WannaCry
|
||||
.wnry,WannaCry
|
||||
.wncryt,WannaCry
|
||||
.WNCRYT,WannaCry
|
||||
.RYK,Ryuk
|
||||
.Clop,Clop
|
||||
.Cllp,Clop
|
||||
.JSWORM,JSWorm
|
||||
.NEMTY_*,Nemty
|
||||
.NEFILIM,Nefilim
|
||||
.OFFWHITE,Offwhite
|
||||
.TELEGRAM,Telegram
|
||||
.FUSION,Fusion
|
||||
.MILIHPEN,Milihpen
|
||||
.GANGBANG,Gangbang
|
||||
.reddot,RedDot
|
||||
|
-69
@@ -1,69 +0,0 @@
|
||||
ransomware_notes, status
|
||||
HELP_TO_SAVE_FILES.txt,True
|
||||
BitCryptorFileList.txt,True
|
||||
BUYUNLOCKCODE,True
|
||||
YOUR_FILES_ARE_ENCRYPTED.HTML,True
|
||||
Coin.Locker.txt,True
|
||||
DECRYPT_INSTRUCTIONS.HTML,True
|
||||
ReadDecryptFilesHere.txt,True
|
||||
HOW_DECRYPT.TXT,True
|
||||
READ IF YOU WANT YOUR FILES BACK.HTML,True
|
||||
GetYouFiles.txt,True
|
||||
HOW TO DECRYPT FILES.HTML,True
|
||||
DECRYPT_INSTRUCTION.TXT,True
|
||||
HELP_DECRYPT.TXT,True
|
||||
HELP_YOURFILES.HTML,True
|
||||
HowDecrypt.gif,True
|
||||
Decrypt All Files *.bmp,True
|
||||
cryptinfo.txt,True
|
||||
DECRYPT_Readme.TXT.ReadMe,True
|
||||
qwer.html,True
|
||||
qwer2.html,True
|
||||
Hellothere.txt,True
|
||||
FILESAREGONE.TXT,True
|
||||
HOW TO DECRYPT FILES.TXT,True
|
||||
DECRYPT_Readme.TXT.ReadMe,True
|
||||
README_DECRYPT_HYDRA_ID_*.txt,True
|
||||
DECRYPT_YOUR_FILES.HTML,True
|
||||
KryptoLocker_README.txt,True
|
||||
_Locky_recover_instructions.txt,True
|
||||
DECRYPT_Readme.TXT.ReadMe,True
|
||||
ATTENTION.RTF,True
|
||||
how to get data.txt,True
|
||||
IMPORTANT READ ME.txt,True
|
||||
UnblockFiles.vbs,True
|
||||
YOUR_FILES.url,True
|
||||
exit.hhr.obleep,True
|
||||
HOW_TO_DECRYPT.HTML,True
|
||||
HOW-TO-DECRYPT-FILES.HTML,True
|
||||
HELP_TO_SAVE_FILES.txt,True
|
||||
HELP_TO_SAVE_FILES.txt,True
|
||||
HELP_TO_SAVE_FILES.txt,True
|
||||
_H_e_l_p_RECOVER_INSTRUCTIONS+*.txt,True
|
||||
DECRYPT_INSTRUCTIONS.HTML,True
|
||||
README_DECRYPT_UMBRE_ID_*.txt,True
|
||||
Help_Decrypt.txt,True
|
||||
CryptLogFile.txt,True
|
||||
*@Please_Read_Me@.txt*,True
|
||||
*@WanaDecryptor@.exe*,True
|
||||
# DECRYPT MY FILES #.vbs,True
|
||||
# DECRYPT MY FILES #.html,True
|
||||
# DECRYPT MY FILES #.txt,True
|
||||
# DECRYPT MY FILES #.vbs,True
|
||||
# DECRYPT MY FILES #.html,True
|
||||
# DECRYPT MY FILES #.txt,True
|
||||
HELP_DECRYPT_YOUR_FILES.HTML,True
|
||||
*-HELP_FOR_DECRYPT_FILE.html,True
|
||||
*-SORRY-FOR-FILES.html,True
|
||||
*-READ-FOR-HELLPP.html,True
|
||||
RyukReadMe.html,True
|
||||
ClopReadMe.txt,True
|
||||
README_README.txt,True
|
||||
JSWORM-DECRYPT.html,True
|
||||
NEMTY_*-DECRYPT.txt,True
|
||||
NEFILIM-DECRYPT.txt,True
|
||||
OFFWHITE-MANUAL.txt,True
|
||||
TELEGRAM-RECOVER.txt,True
|
||||
FUSION-README.txt,True
|
||||
MILIHPEN-INSTRUCT.txt,True
|
||||
GANGBANG-NOTE.txt,True
|
||||
|
@@ -1,7 +0,0 @@
|
||||
process,allow_list
|
||||
splunk-regmon.exe,true
|
||||
winword.exe,true
|
||||
excel.exe,true
|
||||
outlook.exe,true
|
||||
powerpnt.exe,true
|
||||
visio.exe,true
|
||||
|
@@ -1 +0,0 @@
|
||||
process,allow_list
|
||||
|
@@ -1 +0,0 @@
|
||||
arn, latestCount, numDataPoints, avgApiCalls, stdevApiCalls
|
||||
|
@@ -1 +0,0 @@
|
||||
arn,latestCount,numDataPoints,avgApiCalls,stdevApiCalls
|
||||
|
@@ -1,5 +0,0 @@
|
||||
service,description,category
|
||||
*mpssvc*,Windows Firewall Service,security
|
||||
*wscsvc*,Windows Security Center Service,securty
|
||||
*windefend*,Windows Defender Service,security
|
||||
*sysmon*,Sysmon Driver,security
|
||||
|
-4
@@ -1,4 +0,0 @@
|
||||
file, note
|
||||
mssscardprv.ax,ESCU - File associated with Hidden Cobra malware https://www.us-cert.gov/ncas/analysis-reports/AR18-149A
|
||||
scardprv.dll,ESCU - File associated with Hidden Cobra malware https://www.us-cert.gov/ncas/analysis-reports/AR18-149A
|
||||
wmmvsvc.dll,ESCU - File associated with Hidden Cobra malware https://www.us-cert.gov/ncas/analysis-reports/AR18-149A
|
||||
|
@@ -1,9 +0,0 @@
|
||||
process_name,uncommon_default,category_default,analytic_story_default,kill_chain_phase_default,mitre_attack_default
|
||||
sethc.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
utilman.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
osk.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
magnify.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
narrator.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
displayswitch.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
atbroker.exe,true,needs_accessibility,Windows Privilege Escalation,Actions on Objectives,Execution|Accessibility Features
|
||||
quser.exe,true,,DHS Report TA18-074A|Unusual Processes,Actions on Objectives,Execution
|
||||
|
@@ -1 +0,0 @@
|
||||
process_name,uncommon_local,category_local,analytic_story_local,kill_chain_phase_local,mitre_attack_local
|
||||
|
Vendored
-40
@@ -1,40 +0,0 @@
|
||||
|
||||
# Application-level permissions
|
||||
|
||||
[]
|
||||
access = read : [ * ], write : [ admin, power ]
|
||||
|
||||
### EVENT TYPES
|
||||
|
||||
[eventtypes]
|
||||
export = system
|
||||
|
||||
[savedsearches]
|
||||
owner = admin
|
||||
|
||||
### PROPS
|
||||
|
||||
[props]
|
||||
export = system
|
||||
|
||||
|
||||
### TRANSFORMS
|
||||
|
||||
[transforms]
|
||||
export = system
|
||||
|
||||
|
||||
### LOOKUPS
|
||||
|
||||
[lookups]
|
||||
export = system
|
||||
|
||||
|
||||
### VIEWSTATES: even normal users should be able to create shared viewstates
|
||||
|
||||
[viewstates]
|
||||
access = read : [ * ], write : [ * ]
|
||||
export = system
|
||||
|
||||
[searchbnf]
|
||||
export = system
|
||||
Reference in New Issue
Block a user