Exemplo n.º 1
0
        public static int ProcessJSONEventData(String JSONData, OutputType OutputType, String Path, String YaraScan, YaraOptions YaraOptions)
        {
            // Yara options
            if (YaraScan != String.Empty)
            {
                byte[]           JSONByteArray = Encoding.ASCII.GetBytes(JSONData);
                List <YSMatches> Matches       = SilkUtility.YaraInstance.ScanMemory(JSONByteArray, SilkUtility.YaraRules, null, 0);
                SilkUtility.YaraRuleMatches.Clear();
                if (Matches.Count != 0)
                {
                    foreach (YSMatches Match in Matches)
                    {
                        SilkUtility.YaraRuleMatches.Add(Match.Rule.Identifier);
                        lock (ConsoleWriterLock)
                        {
                            SilkUtility.ReturnStatusMessage($"     -> Yara match: {Match.Rule.Identifier}", ConsoleColor.Magenta);
                        }
                    }

                    // Dynamically update the JSON object -> List<String> YaraRuleMatches
                    JObject obj = JObject.Parse(JSONData);
                    ((JArray)obj["YaraMatch"]).Add(SilkUtility.YaraRuleMatches);
                    JSONData = obj.ToString(Newtonsoft.Json.Formatting.None);
                }
            }

            if (YaraOptions == YaraOptions.All || YaraOptions == YaraOptions.None || (YaraScan != String.Empty && SilkUtility.YaraRuleMatches.Count > 0))
            {
                //--[Return Codes]
                // 0 == OK
                // 1 == File write failed
                // 2 == URL POST request failed
                // 3 == Eventlog write failed
                //--

                // Process JSON
                if (OutputType == OutputType.file)
                {
                    try
                    {
                        if (!File.Exists(Path))
                        {
                            File.WriteAllText(Path, (JSONData + Environment.NewLine));
                        }
                        else
                        {
                            File.AppendAllText(Path, (JSONData + Environment.NewLine));
                        }

                        return(0);
                    }
                    catch
                    {
                        return(1);
                    }
                }
                else if (OutputType == OutputType.url)
                {
                    try
                    {
                        string         responseFromServer = string.Empty;
                        HttpWebRequest webRequest         = (HttpWebRequest)WebRequest.Create(Path);
                        webRequest.Timeout     = 10000; // 10 second timeout
                        webRequest.Method      = "POST";
                        webRequest.ContentType = "application/json";
                        webRequest.Accept      = "application/json";
                        using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
                        {
                            streamWriter.Write(JSONData);
                            streamWriter.Flush();
                            streamWriter.Close();
                        }
                        var httpResponse = (HttpWebResponse)webRequest.GetResponse();
                        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
                        {
                            var result = streamReader.ReadToEnd();
                        }

                        return(0);
                    }
                    catch
                    {
                        return(2);
                    }
                }
                else
                {
                    Boolean WriteEvent = WriteEventLogEntry(JSONData, EventLogEntryType.Information, EventIds.Event, Path);
                    if (WriteEvent)
                    {
                        return(0);
                    }
                    else
                    {
                        return(3);
                    }
                }
            }
            else
            {
                return(0);
            }
        }
Exemplo n.º 2
0
        public static void StartTrace(CollectorType CollectorType, ulong TraceKeywords, OutputType OutputType, String Path, FilterOption FilterOption, Object FilterValue, String YaraScan, YaraOptions YaraOptions, String ProviderName = "", UserTraceEventLevel UserTraceEventLevel = UserTraceEventLevel.Informational)
        {
            // Is elevated?
            if (TraceEventSession.IsElevated() != true)
            {
                SilkUtility.ReturnStatusMessage("[!] The collector must be run as Administrator..", ConsoleColor.Red);
                return;
            }

            // Print status
            SilkUtility.ReturnStatusMessage("[>] Starting trace collector (Ctrl-c to stop)..", ConsoleColor.Yellow);
            SilkUtility.ReturnStatusMessage("[?] Events captured: 0", ConsoleColor.Green); // We will update this dynamically

            // The kernel collector has naming requirements
            if (CollectorType == CollectorType.Kernel)
            {
                SilkUtility.EventParseSessionName = KernelTraceEventParser.KernelSessionName;
            }
            else
            {
                // We add a GUID in case of concurrent SilkETW execution
                String RandId = Guid.NewGuid().ToString();
                SilkUtility.EventParseSessionName = ("SilkETWUserCollector_" + RandId);
            }

            // Create trace session
            using (var TraceSession = new TraceEventSession(SilkUtility.EventParseSessionName))
            {
                // The collector cannot survive process termination (safeguard)
                TraceSession.StopOnDispose = true;

                // Create event source
                using (var EventSource = new ETWTraceEventSource(SilkUtility.EventParseSessionName, TraceEventSourceType.Session))
                {
                    // Ctrl-c callback handler
                    SilkUtility.SetupCtrlCHandler(() =>
                    {
                        TerminateCollector();
                    });

                    // A DynamicTraceEventParser can understand how to read the embedded manifests that occur in the dataStream
                    var EventParser = new DynamicTraceEventParser(EventSource);

                    // Loop events as they arrive
                    EventParser.All += delegate(TraceEvent data)
                    {
                        // It's a bit ugly but ... ¯\_(ツ)_/¯
                        if (FilterOption != FilterOption.None)
                        {
                            if (FilterOption == FilterOption.Opcode && (byte)data.Opcode != (byte)FilterValue)
                            {
                                SilkUtility.ProcessEventData = false;
                            }
                            else if (FilterOption == FilterOption.ProcessID && data.ProcessID != (UInt32)FilterValue)
                            {
                                SilkUtility.ProcessEventData = false;
                            }
                            else if (FilterOption == FilterOption.ProcessName && data.ProcessName != (String)FilterValue)
                            {
                                SilkUtility.ProcessEventData = false;
                            }
                            else if (FilterOption == FilterOption.EventName && data.EventName != (String)FilterValue)
                            {
                                SilkUtility.ProcessEventData = false;
                            }
                            else
                            {
                                SilkUtility.ProcessEventData = true;
                            }
                        }
                        else
                        {
                            SilkUtility.ProcessEventData = true;
                        }

                        // Only process/serialize events if they match our filter
                        if (SilkUtility.ProcessEventData)
                        {
                            // Display running event count
                            SilkUtility.RunningEventCount += 1;
                            SilkUtility.UpdateEventCount("[?] Events captured: " + SilkUtility.RunningEventCount);

                            var eRecord = new EventRecordStruct
                            {
                                ProviderGuid    = data.ProviderGuid,
                                YaraMatch       = new List <String>(),
                                ProviderName    = data.ProviderName,
                                EventName       = data.EventName,
                                Opcode          = data.Opcode,
                                OpcodeName      = data.OpcodeName,
                                TimeStamp       = data.TimeStamp,
                                ThreadID        = data.ThreadID,
                                ProcessID       = data.ProcessID,
                                ProcessName     = data.ProcessName,
                                PointerSize     = data.PointerSize,
                                EventDataLength = data.EventDataLength
                            };
                            var EventProperties = new Hashtable();

                            // Try to parse event XML
                            try
                            {
                                StringReader  XmlStringContent   = new StringReader(data.ToString());
                                XmlTextReader EventElementReader = new XmlTextReader(XmlStringContent);
                                while (EventElementReader.Read())
                                {
                                    for (int AttribIndex = 0; AttribIndex < EventElementReader.AttributeCount; AttribIndex++)
                                    {
                                        EventElementReader.MoveToAttribute(AttribIndex);
                                        EventProperties.Add(EventElementReader.Name, EventElementReader.Value);
                                    }
                                }
                            }
                            catch
                            {
                                // For debugging (?), never seen this fail
                                EventProperties.Add("XmlEventParsing", "false");
                            }
                            eRecord.XmlEventData = EventProperties;

                            // Serialize to JSON
                            String JSONEventData = Newtonsoft.Json.JsonConvert.SerializeObject(eRecord);
                            int    ProcessResult = SilkUtility.ProcessJSONEventData(JSONEventData, OutputType, Path, YaraScan, YaraOptions);

                            // Verify that we processed the result successfully
                            if (ProcessResult != 0)
                            {
                                if (ProcessResult == 1)
                                {
                                    SilkUtility.ReturnStatusMessage("[!] The collector failed to write to file", ConsoleColor.Red);
                                }
                                else
                                {
                                    SilkUtility.ReturnStatusMessage("[!] The collector failed to POST the result", ConsoleColor.Red);
                                }

                                // Shut down the collector
                                TerminateCollector();
                            }
                        }
                    };

                    // Specify the providers details
                    if (CollectorType == CollectorType.Kernel)
                    {
                        TraceSession.EnableKernelProvider((KernelTraceEventParser.Keywords)TraceKeywords);
                    }
                    else
                    {
                        // Note that the collector doesn't know if you specified a wrong provider name,
                        // the only tell is that you won't get any events ;)
                        TraceSession.EnableProvider(ProviderName, (TraceEventLevel)UserTraceEventLevel, TraceKeywords);
                    }

                    // Continuously process all new events in the data source
                    EventSource.Process();

                    // Helper to clean up colloector
                    void TerminateCollector()
                    {
                        EventSource.StopProcessing();
                        TraceSession?.Stop();
                        Console.CursorVisible = true;
                        SilkUtility.ReturnStatusMessage("[+] Collector terminated", ConsoleColor.Green);
                    }
                }
            }
        }