Skip to main content
Splunk Lantern

First time seen command line argument

 

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.

Data required 

Endpoint data

Procedure

  1. To complete this process, your deployment needs to ingest process activity from your hosts with both the process name and command line from your endpoints.You should also ensure you are ingesting normalized endpoint data, populating the Processes node of the Endpoint data model in the Common Information Model (CIM). For information on installing and using the CIM, see the Common Information Model documentation.
  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. You can optimize it by specifying an index and adjusting the time range. 
|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 
|convert timeformat="%m/%d/%Y %H:%M:%S" 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.

Next steps

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.

You might also be interested in other processes associated with the Detecting techniques in the Orangeworm attack group and Monitoring command line interface actions use cases.