Managing Assets in Splunk Enterprise Security
Author: Ben Marrable
In general, assets tend to be more complex as every environment is different. The first point of call will be whether the business has an up to date CMDB but a lot of the time that’s unfortunately not the case, so alternatives can be spreadsheets, Active Directory, some kind of endpoint management solution logging into Splunk or ultimately a combination of many sources.
A good starting point is to build an initial asset list based on the network ranges in the environment to easily distinguish generic network devices etc. These provide the ability to categorise and prioritise devices that we don’t have the exact details for. Once we have the base network assets, we need to look for a more specific lists for servers, endpoints and network devices (firewalls, routers, switches, access points etc.).
What asset data do we need?
Field | Data Type | Description | Example |
---|---|---|---|
ip | pipe-delimited numbers | A pipe-delimited list of single IP address or IP ranges. An asset is required to have an entry in the ip, mac, nt_host, or dns fields. Do not use pipe-delimiting for more than one of these fields per asset. | 2.0.0.0/8 | 1.2.3.4 | 192.168.15.91 192.169.15.27 | 5.6.7.8 | 10.11.12.13 |
mac | pipe-delimited strings | A pipe-delimited list of MAC addresses. An asset is required to have an entry in the ip, mac, nt_host, or dns fields. Do not use pipe-delimiting for more than one of these fields per asset. | 00:25:bc:42:f4:60 | 00:50:ef:84:f1:21 | 00:50:ef:84:f1:20 |
nt_host | pipe-delimited strings | A pipe-delimited list of Windows machine names. An asset is required to have an entry in the ip, mac, nt_host, or dns fields. Do not use pipe-delimiting for more than one of these fields per asset. | ACME-0005 | SSPROCKETS-0102 | COSWCOGS-013 |
dns | pipe-delimited strings | A pipe-delimited list of DNS names. An asset is required to have an entry in the ip, mac, nt_host, or dns fields. Do not use pipe-delimiting for more than one of these fields per asset. | acme-0005.corp1.acmetech.org | SSPROCKETS-0102.spsp.com | COSWCOGS-013.cwcogs.com |
owner | string | The user or department associated with the device | f.prefect@acmetech.org, DevOps, Bill |
priority | string | Recommended. The priority assigned to the device for calculating the Urgency field for notable events on Incident Review. An “unknown” priority reduces the assigned Urgency by default. | unknown | low | medium | high | critical |
lat | string | The latitude of the asset | 41.040855 |
long | string | The longitude of the asset | 28.986183 |
city | string | The city in which the asset is located | Chicago |
country | string | The country in which the asset is located | USA |
bunit | string | Recommended. The business unit of the asset. Used for filtering by dashboards in Splunk Enterprise Security. | EMEA | NorCal |
category | pipe-delimited strings | Recommended. A pipe-delimited list of logical classifications for assets. Used for asset and identity correlation and categorization. | server | web_farm | cloud |
pci_domain | pipe-delimited strings | A pipe-delimited list of PCI domains. If left blank, defaults to untrust. | cardholder | trust | dmz | untrust |
is_expected | boolean | Indicates whether events from this asset should always be expected. | true | false (blank) |
should_timesync | boolean | Indicates whether this asset must be monitored for time-sync events. | true | false (blank) |
should_update | boolean | Indicates whether this asset must be monitored for system update events. | true | false (blank) |
requires_av | boolean | Indicates whether this asset must have anti-virus software installed. | true | false (blank) |
How do we gather this information?
As I said, the data can tend to come from a collection of sources, CMDB’s, spreadsheets, AD or some form of Splunk data. Here, I’m going to presume we have a csv dump with a variety of fields exported from our CMDB.
| inputlookup raw_assets_from_cmdb.csv | fields ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av, SystemType | fillnull value="" ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av | eval comment="Priority Definement" | eval priority=case( match(memberOf,"Critical\sPriority\sServers"),"critical", match(computerName,"criticalVirtualServer\d*"),"critical", match(memberOf,"High\sPriority\sServers"),"high", match(nt_host,"server"),"high", match(nt_host,"network_device"),"medium", match(nt_host,"desktop"),"low", match(nt_host,"laptop"),"low", 1==1,"low") | eval comment="Category Definement" | makemv delim="|" category | eval category=if(match(SystemType,"Server"),mvappend(category,"server"),category) | eval category=if(match(SystemType,"Desktop"),mvappend(category,"endpoint"),category) | eval category=if(match(nt_host,"VirtualServer"),mvappend(category,"virtual_machine"),category) | eval category=mvsort(mvdedup(category)) | eval category=mvjoin(category,"|") | eval comment="Department Possible Values Check" | eval bunit=case( bunit="IT","IT", bunit="Information Technology","IT", bunit="Legal","Legal", 1==1,"") | eval pci_domain="" | eval is_expected="false" | eval should_timesync="true" | eval should_update="true" | eval requires_av="true" | lookup asset_locations city, country OUTPUTNEW lat, long | table ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av | outputlookup assets_from_cmdb
Let’s break this search down, so we understand each part:
| inputlookup raw_assets_from_cmdb.csv | fields ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av, SystemType | fillnull value="" ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av
This section pulls the csv file and extracts only the fields required so that future calculation statements use less memory and perform better. It then fills all NULL values with an empty string, as certain calculation statements do not apply to NULL values.
| eval comment="Priority Definement" | eval priority=case( match(memberOf,"Critical\sPriority\sServers"),"critical", match(computerName,"criticalVirtualServer\d*"),"critical", match(memberOf,"High\sPriority\sServers"),"high", match(nt_host,"server"),"high", match(nt_host,"network_device"),"medium", match(nt_host,"desktop"),"low", match(nt_host,"laptop"),"low", 1==1,"low"
This section is about defining the priority for each Asset, priority is one of the most critical fields to define and to distinguish between Assets. Several attributes can be used to give some definition to the search, using a case statement hitting the highest priorities first. Attributes which are useful here are the OU that the account sits within the domain (which could be found with ldapfilter), groups the account is a member of (ldapgroup) and of course the hostname of the actual system. There may be many other fields within the export, such as description which could help with the priority definement.
| eval comment="Category Definement" | makemv delim="|" category | eval category=if(match(SystemType,"Server"),mvappend(category,"server"),category) | eval category=if(match(SystemType,"Desktop"),mvappend(category,"endpoint"),category) | eval category=if(match(nt_host,"VirtualServer"),mvappend(category,"virtual_machine"),category) | eval category=mvsort(mvdedup(category)) | eval category=mvjoin(category,"|")
Next we look at defining some categories, categories are useful for dividing data within Splunk, so we can see items such as the number of failed authentication to physical machines or to servers etc.
| eval comment="Department Possible Values Check" | eval bunit=case( bunit="IT","IT", bunit="Information Technology","IT", bunit="Legal","Legal", 1==1,""
This section looks to combine and clean some data which may be populated badly in the CMDB, restricting to match only certain bunits, as it’s quite common for Assets to have various spelling mistakes and alternative forms of departments within a CMDB list.
| eval pci_domain="" | eval is_expected="false" | eval should_timesync="true" | eval should_update="true" | eval requires_av="true"
Additionally we create a blank field for pci_domain as we are not pci relevant, set is_expected to false and the other values to true. It is recommended to calculate these fields wherever possible, using similar methods demonstrated above.
| lookup asset_locations city, country OUTPUTNEW lat, long
Here we poll the city and country held within the CMDB export to pull the latitude and longitude from a lookup containing those details for work locations within the business.
| table ip, mac, nt_host, dns, owner, priority, lat, long, city, country, bunit, category, pci_domain, is_expected, should_timesync, should_update, requires_av | outputlookup assets_from_cmdb
Finally we output the data into a lookup table file to incorporate into ES.
Get in Touch
Contact one of our expert team for more information.