Пример #1
0
        public DirResult ClassifyDir(string dir)
        {
            BlockingMq Mq        = BlockingMq.GetMq();
            DirResult  dirResult = new DirResult()
            {
                DirPath = dir,
                Triage  = ClassifierRule.Triage,
                ScanDir = true,
            };
            // check if it matches
            TextClassifier textClassifier = new TextClassifier(ClassifierRule);
            TextResult     textResult     = textClassifier.TextMatch(dir);

            if (textResult != null)
            {
                // if it does, see what we're gonna do with it
                switch (ClassifierRule.MatchAction)
                {
                case MatchAction.Discard:
                    dirResult.ScanDir = false;
                    return(dirResult);

                case MatchAction.Snaffle:
                    dirResult.Triage = ClassifierRule.Triage;
                    Mq.DirResult(dirResult);
                    return(dirResult);

                default:
                    Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                    return(null);
                }
            }
            return(dirResult);
        }
Пример #2
0
        public bool ClassifyShare(string share)
        {
            BlockingMq Mq = BlockingMq.GetMq();

            // first time we hit sysvol, toggle the flag and keep going. every other time, bail out.
            if (share.ToLower().EndsWith("sysvol"))
            {
                if (MyOptions.ScanSysvol == false)
                {
                    return(true);
                }
                MyOptions.ScanSysvol = false;
            }
            ;
            // same for netlogon
            if (share.ToLower().EndsWith("netlogon"))
            {
                if (MyOptions.ScanNetlogon == false)
                {
                    return(true);
                }
                MyOptions.ScanNetlogon = false;
            }
            // check if it matches
            TextClassifier textClassifier = new TextClassifier(ClassifierRule);
            TextResult     textResult     = textClassifier.TextMatch(share);

            if (textResult != null)
            {
                // if it does, see what we're gonna do with it
                switch (ClassifierRule.MatchAction)
                {
                case MatchAction.Discard:
                    return(true);

                case MatchAction.Snaffle:
                    // in this context snaffle means 'send a report up the queue but don't scan the share'
                    if (IsShareReadable(share))
                    {
                        ShareResult shareResult = new ShareResult()
                        {
                            Triage    = ClassifierRule.Triage,
                            Listable  = true,
                            SharePath = share
                        };
                        Mq.ShareResult(shareResult);
                    }
                    return(true);

                default:
                    Mq.Error("You've got a misconfigured share ClassifierRule named " + ClassifierRule.RuleName + ".");
                    return(false);
                }
            }
            return(false);
        }
Пример #3
0
        public bool ClassifyShare(string share)
        {
            BlockingMq Mq = BlockingMq.GetMq();

            // check if the share has a matching classifier
            TextClassifier textClassifier = new TextClassifier(ClassifierRule);
            TextResult     textResult     = textClassifier.TextMatch(share);

            if (textResult != null)
            {
                // if it does, see what we're gonna do with it
                switch (ClassifierRule.MatchAction)
                {
                case MatchAction.Discard:
                    return(true);

                case MatchAction.Snaffle:
                    // in this context snaffle means 'send a report up the queue but don't scan the share'
                    if (IsShareReadable(share))
                    {
                        ShareResult shareResult = new ShareResult()
                        {
                            Triage    = ClassifierRule.Triage,
                            Listable  = true,
                            SharePath = share
                        };
                        Mq.ShareResult(shareResult);
                    }
                    return(true);

                default:
                    Mq.Error("You've got a misconfigured share ClassifierRule named " + ClassifierRule.RuleName + ".");
                    return(false);
                }
            }
            return(false);
        }
Пример #4
0
        public bool ClassifyFile(FileInfo fileInfo)
        {
            BlockingMq Mq = BlockingMq.GetMq();
            // figure out what part we gonna look at
            string stringToMatch = null;

            switch (ClassifierRule.MatchLocation)
            {
            case MatchLoc.FileExtension:
                stringToMatch = fileInfo.Extension;
                // special handling to treat files named like 'thing.kdbx.bak'
                if (stringToMatch == ".bak")
                {
                    // strip off .bak
                    string subName = fileInfo.Name.Replace(".bak", "");
                    stringToMatch = Path.GetExtension(subName);
                    // if this results in no file extension, put it back.
                    if (stringToMatch == "")
                    {
                        stringToMatch = ".bak";
                    }
                }
                // this is insane that i have to do this but apparently files with no extension return
                // this bullshit
                if (stringToMatch == "")
                {
                    return(false);
                }
                break;

            case MatchLoc.FileName:
                stringToMatch = fileInfo.Name;
                break;

            case MatchLoc.FilePath:
                stringToMatch = fileInfo.FullName;
                break;

            case MatchLoc.FileLength:
                if (!SizeMatch(fileInfo))
                {
                    return(false);
                }
                else
                {
                    break;
                }

            default:
                Mq.Error("You've got a misconfigured file classifier rule named " + ClassifierRule.RuleName + ".");
                return(false);
            }

            TextResult textResult = null;

            if (!String.IsNullOrEmpty(stringToMatch))
            {
                TextClassifier textClassifier = new TextClassifier(ClassifierRule);
                // check if it matches
                textResult = textClassifier.TextMatch(stringToMatch);
                if (textResult == null)
                {
                    // if it doesn't we just bail now.
                    return(false);
                }
            }

            FileResult fileResult;

            // if it matches, see what we're gonna do with it
            switch (ClassifierRule.MatchAction)
            {
            case MatchAction.Discard:
                // chuck it.
                return(true);

            case MatchAction.Snaffle:
                // snaffle that bad boy
                fileResult = new FileResult(fileInfo)
                {
                    MatchedRule = ClassifierRule,
                    TextResult  = textResult
                };
                Mq.FileResult(fileResult);
                return(true);

            case MatchAction.CheckForKeys:
                // do a special x509 dance
                if (x509PrivKeyMatch(fileInfo))
                {
                    fileResult = new FileResult(fileInfo)
                    {
                        MatchedRule = ClassifierRule
                    };
                    Mq.FileResult(fileResult);
                }
                return(true);

            case MatchAction.Relay:
                // bounce it on to the next ClassifierRule
                // TODO concurrency uplift make this a new task on the poolq
                try
                {
                    ClassifierRule nextRule =
                        MyOptions.ClassifierRules.First(thing => thing.RuleName == ClassifierRule.RelayTarget);

                    if (nextRule.EnumerationScope == EnumerationScope.ContentsEnumeration)
                    {
                        ContentClassifier nextContentClassifier = new ContentClassifier(nextRule);
                        nextContentClassifier.ClassifyContent(fileInfo);
                        return(true);
                    }
                    else if (nextRule.EnumerationScope == EnumerationScope.FileEnumeration)
                    {
                        FileClassifier nextFileClassifier = new FileClassifier(nextRule);
                        nextFileClassifier.ClassifyFile(fileInfo);
                        return(true);
                    }
                    else
                    {
                        Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                        return(false);
                    }
                }
                catch (IOException e)
                {
                    Mq.Trace(e.ToString());
                }
                catch (Exception e)
                {
                    Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                    Mq.Trace(e.ToString());
                }
                return(false);

            case MatchAction.EnterArchive:
                // do a special looking inside archive files dance using
                // https://github.com/adamhathcock/sharpcompress
                // TODO FUUUUUCK
                throw new NotImplementedException("Haven't implemented walking dir structures inside archives. Prob needs pool queue.");

            default:
                Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                return(false);
            }
        }
Пример #5
0
        public void ClassifyContent(FileInfo fileInfo)
        {
            BlockingMq Mq = BlockingMq.GetMq();
            FileResult fileResult;

            try
            {
                if (MyOptions.MaxSizeToGrep >= fileInfo.Length)
                {
                    // figure out if we need to look at the content as bytes or as string.
                    switch (ClassifierRule.MatchLocation)
                    {
                    case MatchLoc.FileContentAsBytes:
                        byte[] fileBytes = File.ReadAllBytes(fileInfo.FullName);
                        if (ByteMatch(fileBytes))
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    case MatchLoc.FileContentAsString:
                        string fileString = File.ReadAllText(fileInfo.FullName);

                        TextClassifier textClassifier = new TextClassifier(ClassifierRule);
                        TextResult     textResult     = textClassifier.TextMatch(fileString);
                        if (textResult != null)
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule,
                                TextResult  = textResult
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    case MatchLoc.FileLength:
                        bool lengthResult = SizeMatch(fileInfo);
                        if (lengthResult)
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    case MatchLoc.FileMD5:
                        bool Md5Result = MD5Match(fileInfo);
                        if (Md5Result)
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    default:
                        Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                        return;
                    }
                }
                else
                {
                    Mq.Trace("The following file was bigger than the MaxSizeToGrep config parameter:" + fileInfo.FullName);
                }
            }
            catch (UnauthorizedAccessException)
            {
                Mq.Error($"Not authorized to access file: {fileInfo.FullName}");
                return;
            }
            catch (IOException e)
            {
                Mq.Error($"IO Exception on file: {fileInfo.FullName}. {e.Message}");
                return;
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                return;
            }
        }
Пример #6
0
        public void ClassifyContent(FileInfo fileInfo)
        {
            BlockingMq Mq = BlockingMq.GetMq();
            FileResult fileResult;

            try
            {
                if (MyOptions.MaxSizeToGrep >= fileInfo.Length)
                {
                    // figure out if we need to look at the content as bytes or as string.
                    switch (ClassifierRule.MatchLocation)
                    {
                    case MatchLoc.FileContentAsBytes:
                        byte[] fileBytes = File.ReadAllBytes(fileInfo.FullName);
                        if (ByteMatch(fileBytes))
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    case MatchLoc.FileContentAsString:
                        try
                        {
                            string fileString;

#if ULTRASNAFFLER
                            // if it's an office doc or a PDF or something, parse it to a string first i guess?
                            List <string> parsedExtensions = new List <string>()
                            {
                                ".doc", ".docx", ".xls", ".xlsx", ".eml", ".msg", ".pdf", ".ppt", ".pptx", ".rtf", ".docm", ".xlsm", ".pptm", ".dot", ".dotx", ".dotm", ".xlt", ".xlsm", ".xltm"
                            };

                            if (parsedExtensions.Contains(fileInfo.Extension))
                            {
                                fileString = ParseFileToString(fileInfo);
                            }
                            else
                            {
                                fileString = File.ReadAllText(fileInfo.FullName);
                            }
#else
                            fileString = File.ReadAllText(fileInfo.FullName);
#endif
                            TextClassifier textClassifier = new TextClassifier(ClassifierRule);
                            TextResult     textResult     = textClassifier.TextMatch(fileString);
                            if (textResult != null)
                            {
                                fileResult = new FileResult(fileInfo)
                                {
                                    MatchedRule = ClassifierRule,
                                    TextResult  = textResult
                                };

                                Mq.FileResult(fileResult);
                            }
                        }
                        catch (UnauthorizedAccessException)
                        {
                            return;
                        }
                        catch (IOException)
                        {
                            return;
                        }
                        return;

                    case MatchLoc.FileLength:
                        bool lengthResult = SizeMatch(fileInfo);
                        if (lengthResult)
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    case MatchLoc.FileMD5:
                        bool Md5Result = MD5Match(fileInfo);
                        if (Md5Result)
                        {
                            fileResult = new FileResult(fileInfo)
                            {
                                MatchedRule = ClassifierRule
                            };
                            Mq.FileResult(fileResult);
                        }
                        return;

                    default:
                        Mq.Error("You've got a misconfigured file ClassifierRule named " + ClassifierRule.RuleName + ".");
                        return;
                    }
                }
                else
                {
                    Mq.Trace("The following file was bigger than the MaxSizeToGrep config parameter:" + fileInfo.FullName);
                }
            }
            catch (UnauthorizedAccessException)
            {
                Mq.Error($"Not authorized to access file: {fileInfo.FullName}");
                return;
            }
            catch (IOException e)
            {
                Mq.Error($"IO Exception on file: {fileInfo.FullName}. {e.Message}");
                return;
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                return;
            }
        }