Skip to main content
Splunk Lantern

First time seen command line argument

You might want to look for command line arguments that use a /c parameter to run a command that has not been previous seen when doing the following:

Prerequisites 

Content developed by the Splunk Security Research team requires the use of consistent, normalized data provided by the Common Information Model (CIM). This search requires the Endpoint data model. For information on installing and using the CIM, see the Common Information Model documentation.

Example

New command line arguments indicate new processes that might or might not be legitimate. You want to compare new arguments against ones already occurring on your network to decide if further investigation is necessary.

To optimize the search shown below, you should specify an index and a time range. 

  1. Ensure that your deployment is ingesting records process activity from your hosts to populate the Endpoint data model in the Processes node. You must be ingesting logs with both the process name and command line from your endpoints. The complete process name with command-line arguments are mapped to the "process" field in the Endpoint data model. 
  2. Run the support search, previously seen command line argument, before this search to create the baseline of known command-line arguments.
  3. Run the following search: 
|tstats summariesonly=true allow_old_summaries=true min(_time) AS firstTime max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE Processes.process_name = cmd.exe Processes.process = "* /c *" BY Processes.process Processes.process_name Processes.parent_process_name Processes.dest
|rename "Processes.*" as "*
|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(firstTime) 
|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(lastTime) 
|search [| tstats summariesonly=true allow_old_summaries=true earliest(_time) AS firstTime latest(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE Processes.process_name = cmd.exe Processes.process = "* /c *" BY Processes.process 
|rename "Processes.*" as "*"  
|inputlookup append=t previously_seen_cmd_line_arguments 
|stats min(firstTime) AS firstTime, max(lastTime) AS lastTime BY process 
|outputlookup previously_seen_cmd_line_arguments 
|eval newCmdLineArgument=if(firstTime >= relative_time(now(), "-70m@m"), 1, 0) |where newCmdLineArgument=1 
|`security_content_ctime(firstTime)` 
|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(lastTime) 
| table process] 

Search explanation

The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.

Splunk Search Explanation

|tstats summariesonly=true allow_old_summaries=true min(_time) AS firstTime max(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE Processes.process_name = cmd.exe Processes.process = "* /c *" BY Processes.process Processes.process_name Processes.parent_process_name Processes.dest

Query the Endpoint.Processes data model object for the process name "cmd.exe" and a process that includes /c, which runs a command. Return the first and last time that each matching command line argument was seen, as well as key information about the process that ran.

|rename "Processes.*" as "*"

Rename the data model object for better readability.

|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(firstTime) 

|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(lastTime)

Convert these times into readable strings.

|search [|tstats summariesonly=true allow_old_summaries=true earliest(_time) AS firstTime latest(_time) AS lastTime FROM datamodel=Endpoint.Processes WHERE Processes.process_name = cmd.exe Processes.process = "* /c *" BY Processes.process
|rename "Processes.*" as "*"
|inputlookup append=t previously_seen_cmd_line_arguments
|stats min(firstTime) AS firstTime, max(lastTime) AS lastTime BY process |outputlookup previously_seen_cmd_line_arguments
|eval newCmdLineArgument=if(firstTime >= relative_time(now(), "-70m@m"), 1, 0)
|where newCmdLineArgument=1
|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(firstTime)
|convert timeformat="%m/%d/%Y %H:%M:%S" ctime(lastTime)
|table process] 

Return results only from the data that has been summarized in TSIDX format for the selected data model.

Use both current summary data and summary data that was generated prior to any definition changes made to the data model.

Return all events where cmd.exe was used with a /c parameter in the command-line arguments to execute other commands/programs.

Rename the data model object for better readability.

Append the historical data to the results in the lookup file, previously_seen_cmd_line_arguments.

Recalculate the firstTime and lastTime field for command-line execution and output this data to the lookup file to update the local cache.

Return only those events that have first been seen in the past one hour.

Be sure to update the "-70m@m" value to match the search schedule.

Result

Legitimate programs can also use command-line arguments to execute. Verify the command-line arguments to check what command/program is being run. You can customize the first_time_seen_cmd_line_filter macro to exclude legitimate parent_process_name values. Investigate web and authentication activity on the destination. If you have the Splunk Enterprise Security app, you can leverage the Threat Intel Framework to watch for traffic from known malicious IP addresses.

For additional information about this search, such as its applicability to common frameworks and standards, see this project on GitHub.

  • Was this article helpful?