TL;DR - I want a query to search through Windows Security Event Logs (Type 4688 - A new process has been created) and return all processes along with their parent process name sorted by host. This will eventually be a dashboard for any process that violates common parent/child relationships (ie. lsass.exe started by calc.exe).
Problem:
Windows Security Event Logs do not record the name of the parent process of newly started processes (Type 4688) only the hex value of the Parent Process ID (Creator_Process_ID). But because I have these logs, I can manually use the Creator_Process_ID and find the event that has the same host and a New_Process_ID value that matches the Creator_Process_ID from the event in question.
I have created two separate queries:
One that returns all processes along with their associated host and process ID
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 | rename New_Process_ID as PID host as Source New_Process_Name as Process | dedup PID Source | table PID Source Process
A second that returns all processes along with their associated Creator_Process_ID
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 New_Process_Name=*smss.exe | table host New_Process_Name Creator_Process_ID
I now need to figure out how to map the Creator_Process_ID from the second query to the name of the process from that host/PID from the first query. I have tried some JOIN
queries but am not knowledgeable enough in such things to know if that is even the right approach.
Thanks for the help.
May be more efficient to store the results of the first query in a lookup csv and use that in your second query. I assume new processes do not get added very frequently, you could schedule the first query to run once a day (or more freq, if needed). Here's how you could do that. Once you have setup the .csv file as a lookup table & set appropriate lookup definition, run this at whatever frequency
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 | rename New_Process_ID as PID host as Source New_Process_Name as Process | dedup PID Source | fields PID Source Process | outputlookup lookupfile.csv
Once you have that (you can verify by running |inputlookup lookupfile.csv
), use lookup
command to get process name in second query. Like this
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 New_Process_Name=*smss.exe | lookup PID AS Creator_Process_ID OUTPUT Source | table host New_Process_Name Creator_Process_ID Source
http://docs.splunk.com/Documentation/Splunk/6.5.0/SearchReference/Lookup
May be more efficient to store the results of the first query in a lookup csv and use that in your second query. I assume new processes do not get added very frequently, you could schedule the first query to run once a day (or more freq, if needed). Here's how you could do that. Once you have setup the .csv file as a lookup table & set appropriate lookup definition, run this at whatever frequency
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 | rename New_Process_ID as PID host as Source New_Process_Name as Process | dedup PID Source | fields PID Source Process | outputlookup lookupfile.csv
Once you have that (you can verify by running |inputlookup lookupfile.csv
), use lookup
command to get process name in second query. Like this
index=wineventlog sourcetype=WinEventLog:Security EventCode=4688 New_Process_Name=*smss.exe | lookup PID AS Creator_Process_ID OUTPUT Source | table host New_Process_Name Creator_Process_ID Source
http://docs.splunk.com/Documentation/Splunk/6.5.0/SearchReference/Lookup
Incomplete solution: Note that your "dedup PID Source" command in the first search discards multiple new process events, since the PID (Process ID) is quite frequently reused on Windows (i.e. even within 1 hour on my test system), so you are only collecting the latest Process name tied to that PID at the time of the search -- i.e. not necessarily the Process name / PID that was the "Creator_Process_ID" in your second search. Instead try "| table _time PID Source Process | sort PID - _time" or "| stats count values(Process) by PID" to see what you are discarding.
Unfortunately this rather common use case appears to be a rather complex one to solve efficiently.
Update: Just noticed that Win 10 and Server 2016 added "Creator_Process_Name" field which would help identify parent & child process in the same event, and Sysmon new process Event ID 1 also includes "ParentImage" name as well. ( ref msft ref securityaffairs ref sec:4688 ref sysmon:1)
1: https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4688
2: https://securityaffairs.co/wordpress/65570/hacking/powershell-attacks.html
3: https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=4688
4: https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?source=Sysmon&eventID=1
Thanks for the answer. I will play around with this today.
Processes could be starting all the time, so this may not work for real time detection but should suffice for doing historical analysis.
Can I manually run the lookup whenever I want and then follow up with the second query as needed?
End goal is to turn this into a dashboard panel so ultimately I would want both queries to run on demand in some sort of automated or 'one-click' fashion.
Yes, you can manually run to generate the lookup file. The other option would be to join the two queries, but anytime you use sub-searches, the queries run longer.
Just got it working, at least manually. Seems like it does the lookup portion separately so that part of the resulting table takes a small amount of time longer to generate but the results are exactly what I was looking for. Thanks.