diff --git a/docs/field-details.asciidoc b/docs/field-details.asciidoc index e8034c4b5c..fff6f56423 100644 --- a/docs/field-details.asciidoc +++ b/docs/field-details.asciidoc @@ -1967,7 +1967,7 @@ type: keyword ==== Field Reuse -The `hash` fields are expected to be nested at: `file.hash`, `process.hash`. +The `hash` fields are expected to be nested at: `file.hash`, `process.hash`, `process.parent.hash`. Note also that the `hash` fields are not expected to be used directly at the top level. diff --git a/generated/beats/fields.ecs.yml b/generated/beats/fields.ecs.yml index 09e80d5d47..928af80de5 100644 --- a/generated/beats/fields.ecs.yml +++ b/generated/beats/fields.ecs.yml @@ -2465,6 +2465,26 @@ The field should be absent if there is no exit code for the event (e.g. process start).' example: 137 + - name: parent.hash.md5 + level: extended + type: keyword + ignore_above: 1024 + description: MD5 hash. + - name: parent.hash.sha1 + level: extended + type: keyword + ignore_above: 1024 + description: SHA1 hash. + - name: parent.hash.sha256 + level: extended + type: keyword + ignore_above: 1024 + description: SHA256 hash. + - name: parent.hash.sha512 + level: extended + type: keyword + ignore_above: 1024 + description: SHA512 hash. - name: parent.name level: extended type: keyword diff --git a/generated/csv/fields.csv b/generated/csv/fields.csv index b698234b8c..dc86ea2210 100644 --- a/generated/csv/fields.csv +++ b/generated/csv/fields.csv @@ -318,6 +318,10 @@ ECS_Version,Indexed,Field_Set,Field,Type,Level,Example,Description 1.4.0-dev,true,process,process.parent.executable,keyword,extended,/usr/bin/ssh,Absolute path to the process executable. 1.4.0-dev,true,process,process.parent.executable.text,text,extended,/usr/bin/ssh,Absolute path to the process executable. 1.4.0-dev,true,process,process.parent.exit_code,long,extended,137,The exit code of the process. +1.4.0-dev,true,process,process.parent.hash.md5,keyword,extended,,MD5 hash. +1.4.0-dev,true,process,process.parent.hash.sha1,keyword,extended,,SHA1 hash. +1.4.0-dev,true,process,process.parent.hash.sha256,keyword,extended,,SHA256 hash. +1.4.0-dev,true,process,process.parent.hash.sha512,keyword,extended,,SHA512 hash. 1.4.0-dev,true,process,process.parent.name,keyword,extended,ssh,Process name. 1.4.0-dev,true,process,process.parent.name.text,text,extended,ssh,Process name. 1.4.0-dev,true,process,process.parent.pgid,long,extended,,Identifier of the group of processes the process belongs to. diff --git a/generated/ecs/ecs_flat.yml b/generated/ecs/ecs_flat.yml index 5216b4029e..7538268550 100644 --- a/generated/ecs/ecs_flat.yml +++ b/generated/ecs/ecs_flat.yml @@ -4040,6 +4040,50 @@ process.parent.exit_code: order: 29 short: The exit code of the process. type: long +process.parent.hash.md5: + dashed_name: hash-md5 + description: MD5 hash. + flat_name: process.parent.hash.md5 + ignore_above: 1024 + level: extended + name: md5 + order: 0 + original_fieldset: hash + short: MD5 hash. + type: keyword +process.parent.hash.sha1: + dashed_name: hash-sha1 + description: SHA1 hash. + flat_name: process.parent.hash.sha1 + ignore_above: 1024 + level: extended + name: sha1 + order: 1 + original_fieldset: hash + short: SHA1 hash. + type: keyword +process.parent.hash.sha256: + dashed_name: hash-sha256 + description: SHA256 hash. + flat_name: process.parent.hash.sha256 + ignore_above: 1024 + level: extended + name: sha256 + order: 2 + original_fieldset: hash + short: SHA256 hash. + type: keyword +process.parent.hash.sha512: + dashed_name: hash-sha512 + description: SHA512 hash. + flat_name: process.parent.hash.sha512 + ignore_above: 1024 + level: extended + name: sha512 + order: 3 + original_fieldset: hash + short: SHA512 hash. + type: keyword process.parent.name: dashed_name: process-parent-name description: 'Process name. diff --git a/generated/ecs/ecs_nested.yml b/generated/ecs/ecs_nested.yml index 10bc0b8708..58bef2ac07 100644 --- a/generated/ecs/ecs_nested.yml +++ b/generated/ecs/ecs_nested.yml @@ -2698,6 +2698,7 @@ hash: expected: - file - process + - process.parent top_level: false short: Hashes, usually file hashes. title: Hash @@ -4438,6 +4439,50 @@ process: order: 29 short: The exit code of the process. type: long + parent.hash.md5: + dashed_name: hash-md5 + description: MD5 hash. + flat_name: process.parent.hash.md5 + ignore_above: 1024 + level: extended + name: md5 + order: 0 + original_fieldset: hash + short: MD5 hash. + type: keyword + parent.hash.sha1: + dashed_name: hash-sha1 + description: SHA1 hash. + flat_name: process.parent.hash.sha1 + ignore_above: 1024 + level: extended + name: sha1 + order: 1 + original_fieldset: hash + short: SHA1 hash. + type: keyword + parent.hash.sha256: + dashed_name: hash-sha256 + description: SHA256 hash. + flat_name: process.parent.hash.sha256 + ignore_above: 1024 + level: extended + name: sha256 + order: 2 + original_fieldset: hash + short: SHA256 hash. + type: keyword + parent.hash.sha512: + dashed_name: hash-sha512 + description: SHA512 hash. + flat_name: process.parent.hash.sha512 + ignore_above: 1024 + level: extended + name: sha512 + order: 3 + original_fieldset: hash + short: SHA512 hash. + type: keyword parent.name: dashed_name: process-parent-name description: 'Process name. diff --git a/generated/elasticsearch/6/template.json b/generated/elasticsearch/6/template.json index 93628ac71a..750c01fdb9 100644 --- a/generated/elasticsearch/6/template.json +++ b/generated/elasticsearch/6/template.json @@ -1518,6 +1518,26 @@ "exit_code": { "type": "long" }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "name": { "fields": { "text": { diff --git a/generated/elasticsearch/7/template.json b/generated/elasticsearch/7/template.json index 053d9ae09e..ae8b1a3636 100644 --- a/generated/elasticsearch/7/template.json +++ b/generated/elasticsearch/7/template.json @@ -1517,6 +1517,26 @@ "exit_code": { "type": "long" }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, "name": { "fields": { "text": { diff --git a/schemas/hash.yml b/schemas/hash.yml index 7a3f815613..1c6f21c131 100644 --- a/schemas/hash.yml +++ b/schemas/hash.yml @@ -16,6 +16,7 @@ expected: - file - process + - process.parent fields: diff --git a/scripts/schema_reader.py b/scripts/schema_reader.py index 2d1e84be93..bc4170bff3 100644 --- a/scripts/schema_reader.py +++ b/scripts/schema_reader.py @@ -130,11 +130,14 @@ def duplicate_reusable_fieldsets(schema, fields_flat, fields_nested): if 'reusable' in schema: for new_nesting in schema['reusable']['expected']: + split_flat_name = new_nesting.split('.', 1) + top_level = split_flat_name[0] # List field set names expected under another field set. # E.g. host.nestings = [ 'geo', 'os', 'user' ] - if 'nestings' not in fields_nested[new_nesting]: - fields_nested[new_nesting]['nestings'] = [] - fields_nested[new_nesting]['nestings'].append(schema['name']) + if 'nestings' not in fields_nested[top_level]: + fields_nested[top_level]['nestings'] = [] + if schema['name'] not in fields_nested[top_level]['nestings']: + fields_nested[top_level]['nestings'].append(schema['name']) # Explicitly list all leaf fields coming from field set reuse. for (name, field) in schema['fields'].items(): @@ -150,7 +153,13 @@ def duplicate_reusable_fieldsets(schema, fields_flat, fields_nested): fields_flat[destination_name] = copied_field # Nested: use original flat name under the destination fieldset - fields_nested[new_nesting]['fields'][field['flat_name']] = copied_field + # If the nesting is being inserted anywhere except the top level, combine the flat name + # of the destination location with the flat name of the field to be inserted + if len(split_flat_name) == 1: + new_flat_name = field['flat_name'] + else: + new_flat_name = split_flat_name[1] + "." + field['flat_name'] + fields_nested[top_level]['fields'][new_flat_name] = copied_field # Main