Пример #1
0
        public void PrepDomainUserRules()
        {
            try
            {
                if (MyOptions.DomainUsersWordlistRules.Count >= 1)
                {
                    foreach (string ruleName in MyOptions.DomainUsersWordlistRules)
                    {
                        ClassifierRule configClassifierRule =
                            MyOptions.ClassifierRules.First(thing => thing.RuleName == ruleName);

                        foreach (string user in MyOptions.DomainUsersToMatch)
                        {
                            if (user.Length < MyOptions.DomainUserMinLen)
                            {
                                Mq.Trace(String.Format("Skipping regex for \"{0}\".  Shorter than minimum chars: {1}", user, MyOptions.DomainUserMinLen));
                                continue;
                            }

                            // Use the null character to match begin and end of line
                            string pattern = "(| |'|\")" + Regex.Escape(user) + "(| |'|\")";
                            Regex  regex   = new Regex(pattern,
                                                       RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
                            configClassifierRule.Regexes.Add(regex);
                            Mq.Trace(String.Format("Adding regex {0} to rule {1}", regex, ruleName));
                        }
                    }
                }
            }
            catch (Exception)
            {
                Mq.Error("Something went wrong adding domain users to rules.");
            }
        }
Пример #2
0
        public void PrepDomainUserRules()
        {
            try
            {
                if (MyOptions.DomainUsersWordlistRules.Count >= 1)
                {
                    foreach (string ruleName in MyOptions.DomainUsersWordlistRules)
                    {
                        ClassifierRule configClassifierRule =
                            MyOptions.ClassifierRules.First(thing => thing.RuleName == ruleName);

                        foreach (string user in MyOptions.DomainUsersToMatch)
                        {
                            string pattern = "( |'|\")" + Regex.Escape(user) + "( |'|\")";
                            Regex  regex   = new Regex(pattern,
                                                       RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
                            configClassifierRule.Regexes.Add(regex);
                        }
                    }
                }
            }
            catch (Exception)
            {
                Mq.Error("Something went wrong adding domain users to rules.");
            }
        }
Пример #3
0
        public AdData()
        {
            Mq = BlockingMq.GetMq();

            // figure out domain context
            if (MyOptions.TargetDomain == null && MyOptions.TargetDc == null)
            {
                try
                {
                    DirectoryContext =
                        new DirectoryContext(DirectoryContextType.Domain, Domain.GetCurrentDomain().Name);
                }
                catch (Exception e)
                {
                    Mq.Error(
                        "Problem figuring out DirectoryContext, you might need to define manually with -d and/or -c.");
                    Mq.Degub(e.ToString());
                    Mq.Terminate();
                }
            }
            else if (!String.IsNullOrEmpty(MyOptions.TargetDc))
            {
                DirectoryContext = new DirectoryContext(DirectoryContextType.Domain, MyOptions.TargetDc);
            }
            else if (!String.IsNullOrEmpty(MyOptions.TargetDomain))
            {
                DirectoryContext = new DirectoryContext(DirectoryContextType.Domain, MyOptions.TargetDomain);
            }
            SetDomainUsersAndComputers();
        }
Пример #4
0
        internal void GetComputerShares(string computer)
        {
            // find the shares
            HostShareInfo[] hostShareInfos = GetHostShareInfo(computer);

            foreach (HostShareInfo hostShareInfo in hostShareInfos)
            {
                string shareName = GetShareName(hostShareInfo, computer);
                if (!String.IsNullOrWhiteSpace(shareName))
                {
                    bool matched = false;

                    // classify them
                    foreach (ClassifierRule classifier in MyOptions.ShareClassifiers)
                    {
                        ShareClassifier shareClassifier = new ShareClassifier(classifier);
                        if (shareClassifier.ClassifyShare(shareName))
                        {
                            matched = true;
                            break;
                        }
                    }
                    // by default all shares should go on to TreeWalker unless the classifier pulls them out.
                    // send them to TreeWalker
                    if (!matched)
                    {
                        if (IsShareReadable(shareName))
                        {
                            ShareResult shareResult = new ShareResult()
                            {
                                Listable  = true,
                                SharePath = shareName
                            };
                            Mq.ShareResult(shareResult);

                            Mq.Info("Creating a TreeWalker task for " + shareResult.SharePath);
                            TreeTaskScheduler.New(() =>
                            {
                                try
                                {
                                    TreeWalker.WalkTree(shareResult.SharePath);
                                }
                                catch (Exception e)
                                {
                                    Mq.Error("Exception in TreeWalker task for share " + shareResult.SharePath);
                                    Mq.Error(e.ToString());
                                }
                            });
                        }
                    }
                }
            }
        }
Пример #5
0
        public void Execute()
        {
            StartTime = DateTime.Now;
            // This is the main execution thread.
            Timer statusUpdateTimer =
                new Timer(TimeSpan.FromMinutes(1)
                          .TotalMilliseconds)
            {
                AutoReset = true
            };                        // Set the time (1 min in this case)

            statusUpdateTimer.Elapsed += TimedStatusUpdate;
            statusUpdateTimer.Start();

            // if we haven't been told what dir or computer to target, we're going to need to do share discovery. that means finding computers from the domain.
            if (MyOptions.PathTargets == null && MyOptions.ComputerTargets == null)
            {
                DomainDiscovery();
            }
            // if we've been told what computers to hit...
            else if (MyOptions.ComputerTargets != null)
            {
                ShareDiscovery(MyOptions.ComputerTargets);
            }
            // otherwise we should have a set of path targets...
            else if (MyOptions.PathTargets != null)
            {
                FileDiscovery(MyOptions.PathTargets);
            }
            // but if that hasn't been done, something has gone wrong.
            else
            {
                Mq.Error("OctoParrot says: AWK! I SHOULDN'T BE!");
            }

            waitHandle.WaitOne();

            StatusUpdate();
            DateTime finished = DateTime.Now;
            TimeSpan runSpan  = finished.Subtract(StartTime);

            Mq.Info("Finished at " + finished.ToLocalTime());
            Mq.Info("Snafflin' took " + runSpan);
            Mq.Finish();
        }
Пример #6
0
 private void GetDomainControllers()
 {
     try
     {
         DomainControllerCollection dcCollection = DomainController.FindAll(DirectoryContext);
         foreach (DomainController dc in dcCollection)
         {
             DomainControllers.Add(dc.IPAddress);
         }
     }
     catch (Exception e)
     {
         Mq.Error(
             "Something went wrong trying to find domain controllers. Try defining manually with -c?");
         Mq.Degub(e.ToString());
         Mq.Terminate();
     }
 }
Пример #7
0
        private void FileDiscovery(string[] pathTargets)
        {
            foreach (string pathTarget in pathTargets)
            {
                // ShareScanner Task Creation - this kicks off the rest of the flow
                Mq.Info("Creating a TreeWalker task for " + pathTarget);
                TreeTaskScheduler.New(() =>
                {
                    try
                    {
                        TreeWalker.WalkTree(pathTarget);
                    }
                    catch (Exception e)
                    {
                        Mq.Error("Exception in TreeWalker task for path " + pathTarget);
                        Mq.Error(e.ToString());
                    }
                });
            }

            Mq.Info("Created all TreeWalker tasks.");
        }
Пример #8
0
        private void DomainDiscovery()
        {
            Mq.Info("Getting users and computers from AD.");
            // We do this single threaded cos it's fast and not easily divisible.
            AdData        adData          = new ActiveDirectory.AdData();
            List <string> targetComputers = adData.GetDomainComputers();

            if (targetComputers == null)
            {
                Mq.Error(
                    "Something f****d out finding stuff in the domain. You must be holding it wrong.");
                while (true)
                {
                    Mq.Terminate();
                }
            }
            string numTargetComputers = targetComputers.Count.ToString();

            Mq.Info("Got " + numTargetComputers + " computers from AD.");
            if (targetComputers.Count == 0)
            {
                Mq.Error("Didn't find any domain computers. Seems weird. Try pouring water on it.");
                while (true)
                {
                    Mq.Terminate();
                }
            }
            // Push list of fun users to Options
            if (MyOptions.DomainUserRules)
            {
                foreach (string user in adData.GetDomainUsers())
                {
                    MyOptions.DomainUsersToMatch.Add(user);
                }
                PrepDomainUserRules();
            }
            // immediately call ShareDisco which should handle the rest.
            ShareDiscovery(targetComputers.ToArray());
        }
Пример #9
0
 private void ShareDiscovery(string[] computerTargets)
 {
     Mq.Info("Starting to look for readable shares...");
     foreach (string computer in computerTargets)
     {
         // ShareFinder Task Creation - this kicks off the rest of the flow
         Mq.Trace("Creating a sharefinder task for " + computer);
         ShareTaskScheduler.New(() =>
         {
             try
             {
                 ShareFinder shareFinder = new ShareFinder();
                 shareFinder.GetComputerShares(computer);
             }
             catch (Exception e)
             {
                 Mq.Error("Exception in ShareFinder task for host " + computer);
                 Mq.Error(e.ToString());
             }
         });
     }
     Mq.Info("Created all sharefinder tasks.");
 }
Пример #10
0
        private void ParseLogLevelString(string logLevelString)
        {
            switch (logLevelString.ToLower())
            {
            case "debug":
                LogLevel = LogLevel.Debug;
                Mq.Degub("Set verbosity level to degub.");
                break;

            case "degub":
                LogLevel = LogLevel.Debug;
                Mq.Degub("Set verbosity level to degub.");
                break;

            case "trace":
                LogLevel = LogLevel.Trace;
                Mq.Degub("Set verbosity level to trace.");
                break;

            case "data":
                LogLevel = LogLevel.Warn;
                Mq.Degub("Set verbosity level to data.");
                break;

            case "info":
                LogLevel = LogLevel.Info;
                Mq.Degub("Set verbosity level to info.");
                break;

            default:
                LogLevel = LogLevel.Info;
                Mq.Error("Invalid verbosity level " + logLevelString +
                         " falling back to default level (info).");
                break;
            }
        }
Пример #11
0
        private void DomainTargetDiscovery()
        {
            AdData        adData = null;
            List <string> targetComputers;


            // Give preference to explicit targets in the options file over LDAP computer discovery
            if (MyOptions.ComputerTargets != null)
            {
                Mq.Info("Using computer list from user-specified options.");

                targetComputers = new List <string>();
                foreach (string t in MyOptions.ComputerTargets)
                {
                    targetComputers.Add(t);
                }
                Mq.Info(string.Format("Took {0} computers specified in options file.", targetComputers.Count));
            }
            else
            {
                // We do this single threaded cos it's fast and not easily divisible.
                Mq.Info("Getting computers from AD.");

                // The AdData class set/get semantics have gotten wonky here.  Leaving as-is to minimize breakage/changes, but needs another look.
                // initialize it if we didn't already
                if (adData == null)
                {
                    adData = new AdData();
                }
                adData.SetDomainComputers(MyOptions.ComputerTargetsLdapFilter);

                targetComputers = adData.GetDomainComputers();
                Mq.Info(string.Format("Got {0} computers from AD.", targetComputers.Count));

                // if we're only scanning DFS shares then we can skip the SMB sharefinder and work from the list in AD, then jump to FileDiscovery().
                if (MyOptions.DfsOnly)
                {
                    FileDiscovery(MyOptions.DfsNamespacePaths.ToArray());
                }
            }

            if (targetComputers == null && MyOptions.DfsNamespacePaths == null)
            {
                Mq.Error(
                    "Something f****d out finding stuff in the domain. You must be holding it wrong.");
                while (true)
                {
                    Mq.Terminate();
                }
            }

            if (targetComputers.Count == 0 && MyOptions.DfsNamespacePaths.Count == 0)
            {
                Mq.Error("Didn't find any domain computers. Seems weird. Try pouring water on it.");
                while (true)
                {
                    Mq.Terminate();
                }
            }

            // call ShareDisco which should handle the rest.
            ShareDiscovery(targetComputers.ToArray());
            // ShareDiscovery(targetComputers.ToArray(), dfsShares);
        }
Пример #12
0
        public void Execute()
        {
            StartTime = DateTime.Now;
            // This is the main execution thread.
            Timer statusUpdateTimer =
                new Timer(TimeSpan.FromMinutes(1)
                          .TotalMilliseconds)
            {
                AutoReset = true
            };                        // Set the time (1 min in this case)

            statusUpdateTimer.Elapsed += TimedStatusUpdate;
            statusUpdateTimer.Start();


            // If we want to hunt for user IDs, we need data from the running user's domain.
            // Future - walk trusts
            if (MyOptions.DomainUserRules)
            {
                DomainUserDiscovery();
            }

            // Explicit folder setting overrides DFS
            if (MyOptions.PathTargets.Count != 0 && (MyOptions.DfsShareDiscovery || MyOptions.DfsOnly))
            {
                DomainDfsDiscovery();
            }

            if (MyOptions.PathTargets.Count == 0 && MyOptions.ComputerTargets == null)
            {
                if (MyOptions.DfsSharesDict.Count == 0)
                {
                    Mq.Info("Invoking DFS Discovery because no ComputerTargets or PathTargets were specified");
                    DomainDfsDiscovery();
                }

                if (!MyOptions.DfsOnly)
                {
                    Mq.Info("Invoking full domain computer discovery.");
                    DomainTargetDiscovery();
                }
                else
                {
                    Mq.Info("Skipping domain computer discovery.");
                    foreach (string share in MyOptions.DfsSharesDict.Keys)
                    {
                        if (!MyOptions.PathTargets.Contains(share))
                        {
                            MyOptions.PathTargets.Add(share);
                        }
                    }
                    Mq.Info("Starting TreeWalker tasks on DFS shares.");
                    FileDiscovery(MyOptions.PathTargets.ToArray());
                }
            }
            // otherwise we should have a set of path targets...
            else if (MyOptions.PathTargets.Count != 0)
            {
                FileDiscovery(MyOptions.PathTargets.ToArray());
            }
            // or we've been told what computers to hit...
            else if (MyOptions.ComputerTargets != null)
            {
                ShareDiscovery(MyOptions.ComputerTargets);
            }

            // but if that hasn't been done, something has gone wrong.
            else
            {
                Mq.Error("OctoParrot says: AWK! I SHOULDN'T BE!");
            }

            waitHandle.WaitOne();

            StatusUpdate();
            DateTime finished = DateTime.Now;
            TimeSpan runSpan  = finished.Subtract(StartTime);

            Mq.Info("Finished at " + finished.ToLocalTime());
            Mq.Info("Snafflin' took " + runSpan);
            Mq.Finish();
        }
Пример #13
0
        public void WalkTree(string currentDir)
        {
            // Walks a tree checking files and generating results as it goes.

            if (!Directory.Exists(currentDir))
            {
                return;
            }

            try
            {
                string[] files = Directory.GetFiles(currentDir);
                // check if we actually like the files
                foreach (string file in files)
                {
                    FileTaskScheduler.New(() =>
                    {
                        try
                        {
                            FileScanner.ScanFile(file);
                        }
                        catch (Exception e)
                        {
                            Mq.Error("Exception in FileScanner task for file " + file);
                            Mq.Trace(e.ToString());
                        }
                    });
                }
            }
            catch (UnauthorizedAccessException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (DirectoryNotFoundException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (IOException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (Exception e)
            {
                Mq.Degub(e.ToString());
                //continue;
            }

            try
            {
                string[] subDirs = Directory.GetDirectories(currentDir);
                // Create a new treewalker task for each subdir.
                if (subDirs.Length >= 1)
                {
                    foreach (string dirStr in subDirs)
                    {
                        bool scanDir = true;
                        foreach (ClassifierRule classifier in MyOptions.DirClassifiers)
                        {
                            try
                            {
                                DirClassifier dirClassifier = new DirClassifier(classifier);
                                DirResult     dirResult     = dirClassifier.ClassifyDir(dirStr);

                                if (dirResult.ScanDir == false)
                                {
                                    scanDir = false;
                                    break;
                                }
                            }
                            catch (Exception e)
                            {
                                Mq.Trace(e.ToString());
                                continue;
                            }
                        }
                        if (scanDir == true)
                        {
                            TreeTaskScheduler.New(() =>
                            {
                                try
                                {
                                    WalkTree(dirStr);
                                }
                                catch (Exception e)
                                {
                                    Mq.Error("Exception in TreeWalker task for dir " + dirStr);
                                    Mq.Error(e.ToString());
                                }
                            });
                        }
                        else
                        {
                            Mq.Trace("Skipped scanning on " + dirStr + " due to Discard rule match.");
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (DirectoryNotFoundException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (IOException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (Exception e)
            {
                Mq.Trace(e.ToString());
                //continue;
            }
        }
Пример #14
0
        public void WalkTree(string shareRoot)
        {
            try
            {
                // Walks a tree checking files and generating results as it goes.
                Stack <string> dirs = new Stack <string>(20);

                if (!Directory.Exists(shareRoot))
                {
                    return;
                }

                dirs.Push(shareRoot);

                while (dirs.Count > 0)
                {
                    string   currentDir = dirs.Pop();
                    string[] subDirs;
                    try
                    {
                        subDirs = Directory.GetDirectories(currentDir);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        //Mq.Trace(e.ToString());
                        continue;
                    }
                    catch (DirectoryNotFoundException)
                    {
                        //Mq.Trace(e.ToString());
                        continue;
                    }
                    catch (Exception e)
                    {
                        Mq.Trace(e.ToString());
                        continue;
                    }

                    string[] files = null;
                    try
                    {
                        files = Directory.GetFiles(currentDir);
                    }
                    catch (UnauthorizedAccessException)
                    {
                        //Mq.Trace(e.ToString());
                        continue;
                    }
                    catch (DirectoryNotFoundException)
                    {
                        //Mq.Trace(e.ToString());
                        continue;
                    }
                    catch (Exception e)
                    {
                        Mq.Trace(e.ToString());
                        continue;
                    }

                    // check if we actually like the files
                    foreach (string file in files)
                    {
                        FileTaskScheduler.New(() =>
                        {
                            try
                            {
                                FileScanner fileScanner = new FileScanner(file);
                            }
                            catch (Exception e)
                            {
                                Mq.Trace(e.ToString());
                            }
                        });
                    }

                    // Push the subdirectories onto the stack for traversal if they aren't on any discard-lists etc.
                    foreach (string dirStr in subDirs)
                    {
                        foreach (ClassifierRule classifier in MyOptions.DirClassifiers)
                        {
                            try
                            {
                                DirClassifier dirClassifier = new DirClassifier(classifier);
                                DirResult     dirResult     = dirClassifier.ClassifyDir(dirStr);
                                // TODO: concurrency uplift: when there is a pooled concurrency queue, just add the dir as a job to the queue
                                if (dirResult.ScanDir)
                                {
                                    dirs.Push(dirStr);
                                }
                            }
                            catch (Exception e)
                            {
                                Mq.Trace(e.ToString());
                                continue;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
            }
        }
Пример #15
0
        internal void GetComputerShares(string computer)
        {
            // find the shares
            HostShareInfo[] hostShareInfos = GetHostShareInfo(computer);

            foreach (HostShareInfo hostShareInfo in hostShareInfos)
            {
                string shareName = GetShareName(hostShareInfo, computer);
                if (!String.IsNullOrWhiteSpace(shareName))
                {
                    bool matched = false;

                    // SYSVOL and NETLOGON shares are replicated so they have special logic - do not use Classifiers for these
                    switch (hostShareInfo.shi1_netname.ToUpper())
                    {
                    case "SYSVOL":
                        if (MyOptions.ScanSysvol == true)
                        {
                            //  leave matched as false so that we don't suppress the TreeWalk for the first SYSVOL replica we see
                            //  toggle the flag so that any other shares replica will be skipped
                            MyOptions.ScanSysvol = false;
                            break;
                        }
                        matched = true;
                        break;

                    case "NETLOGON":
                        if (MyOptions.ScanNetlogon == true)
                        {
                            //  same as SYSVOL above
                            MyOptions.ScanNetlogon = false;
                            break;
                        }
                        matched = true;
                        break;

                    default:
                        // classify them
                        foreach (ClassifierRule classifier in MyOptions.ShareClassifiers)
                        {
                            ShareClassifier shareClassifier = new ShareClassifier(classifier);
                            if (shareClassifier.ClassifyShare(shareName))
                            {
                                matched = true;
                                break;
                            }
                        }
                        break;
                    }

                    // by default all shares should go on to TreeWalker unless the classifier pulls them out.
                    // send them to TreeWalker
                    if (!matched)
                    {
                        if (IsShareReadable(shareName))
                        {
                            ShareResult shareResult = new ShareResult()
                            {
                                Listable  = true,
                                SharePath = shareName
                            };
                            Mq.ShareResult(shareResult);

                            Mq.Info("Creating a TreeWalker task for " + shareResult.SharePath);
                            TreeTaskScheduler.New(() =>
                            {
                                try
                                {
                                    TreeWalker.WalkTree(shareResult.SharePath);
                                }
                                catch (Exception e)
                                {
                                    Mq.Error("Exception in TreeWalker task for share " + shareResult.SharePath);
                                    Mq.Error(e.ToString());
                                }
                            });
                        }
                    }
                }
            }
        }
Пример #16
0
        internal void GetComputerShares(string computer)
        {
            // find the shares
            HostShareInfo[] hostShareInfos = GetHostShareInfo(computer);

            foreach (HostShareInfo hostShareInfo in hostShareInfos)
            {
                // skip IPC$ and PRINT$ shares for #OPSEC!!!
                List <string> neverScan = new List <string> {
                    "ipc$", "print$"
                };
                if (neverScan.Contains(hostShareInfo.shi1_netname.ToLower()))
                {
                    continue;
                }

                string shareName = GetShareName(hostShareInfo, computer);
                if (!String.IsNullOrWhiteSpace(shareName))
                {
                    bool matched = false;

                    // SYSVOL and NETLOGON shares are replicated so they have special logic - do not use Classifiers for these
                    switch (hostShareInfo.shi1_netname.ToUpper())
                    {
                    case "SYSVOL":
                        if (MyOptions.ScanSysvol == true)
                        {
                            //  Leave matched as false so that we don't suppress the TreeWalk for the first SYSVOL replica we see.
                            //  Toggle the flag so that any other shares replica will be skipped
                            MyOptions.ScanSysvol = false;
                            break;
                        }
                        matched = true;
                        break;

                    case "NETLOGON":
                        if (MyOptions.ScanNetlogon == true)
                        {
                            //  Same logic as SYSVOL above
                            MyOptions.ScanNetlogon = false;
                            break;
                        }
                        matched = true;
                        break;

                    default:
                        // classify them
                        foreach (ClassifierRule classifier in MyOptions.ShareClassifiers)
                        {
                            ShareClassifier shareClassifier = new ShareClassifier(classifier);
                            if (shareClassifier.ClassifyShare(shareName))
                            {
                                // in this instance 'matched' means 'matched a discard rule, so don't send to treewalker'.
                                matched = true;
                                break;
                            }
                        }
                        break;
                    }

                    // by default all shares should go on to TreeWalker unless the classifier pulls them out.
                    // send them to TreeWalker
                    if (!matched)
                    {
                        // At least one classifier was matched so we will return this share to the results
                        ShareResult shareResult = new ShareResult()
                        {
                            Listable     = true,
                            SharePath    = shareName,
                            ShareComment = hostShareInfo.shi1_remark.ToString()
                        };

                        // Try to find this computer+share in the list of DFS targets


                        /*
                         *                      foreach (DFSShare dfsShare in MyOptions.DfsShares)
                         *                      {
                         *                          ///TODO: Add some logic to match cases where short hostnames is used in DFS target list
                         *                          if (dfsShare.RemoteServerName.Equals(computer, StringComparison.OrdinalIgnoreCase) &&
                         *                              dfsShare.Name.Equals(hostShareInfo.shi1_netname, StringComparison.OrdinalIgnoreCase))
                         *                          {
                         *                              // why the not operator?   if (!MyOptions.DfsNamespacePaths.Contains(dfsShare.DfsNamespacePath))
                         *                              if (MyOptions.DfsNamespacePaths.Contains(dfsShare.DfsNamespacePath))
                         *                              {
                         *                                  // remove the namespace path to make sure we don't kick it off again.
                         *                                  MyOptions.DfsNamespacePaths.Remove(dfsShare.DfsNamespacePath);
                         *                                  // sub out the \\computer\share path for the dfs namespace path. this makes sure we hit the most efficient endpoint.
                         *                                  shareName = dfsShare.DfsNamespacePath;
                         *                              }
                         *                              else // if that dfs namespace has already been removed from our list, skip further scanning of that share.
                         *                              {
                         *                                  skip = true;
                         *                              }
                         *
                         *                              // Found DFS target matching this computer+share - no further comparisons needed
                         *                              break;
                         *                          }
                         *                      }
                         */


                        // If this path can be accessed via DFS
                        if (MyOptions.DfsSharesDict.ContainsKey(shareName))
                        {
                            string dfsUncPath = MyOptions.DfsSharesDict[shareName];

                            Mq.Degub(String.Format("Matched host path {0} to DFS {1}", shareName, dfsUncPath));

                            // and if we haven't already scanned this share
                            if (MyOptions.DfsNamespacePaths.Contains(dfsUncPath))
                            {
                                Mq.Degub(String.Format("Will scan {0} using DFS referral instead of explicit host", dfsUncPath));

                                // sub out the \\computer\share path for the dfs namespace path. this makes sure we hit the most efficient endpoint.
                                shareResult.SharePath = dfsUncPath;

                                // remove the namespace path to make sure we don't kick it off again.
                                MyOptions.DfsNamespacePaths.Remove(dfsUncPath);
                            }
                            else // if that dfs path has already been removed from our list, skip further scanning of that share.
                            {
                                // Do we want to report a gray share result for these?  I think not.
                                // Mq.ShareResult(shareResult);
                                break;
                            }
                        }

                        //  If the share is readable then dig deeper.
                        if (IsShareReadable(shareResult.SharePath))
                        {
                            // Share is readable, report as green  (the old default/min of the Triage enum )
                            shareResult.Triage = Triage.Green;

                            try
                            {
                                DirectoryInfo dirInfo = new DirectoryInfo(shareResult.SharePath);

                                //EffectivePermissions.RwStatus rwStatus = effectivePermissions.CanRw(dirInfo);

                                shareResult.RootModifyable = false;
                                shareResult.RootWritable   = false;
                                shareResult.RootReadable   = true;

                                /*
                                 * if (rwStatus.CanWrite || rwStatus.CanModify)
                                 * {
                                 *  triage = Triage.Yellow;
                                 * }
                                 */
                            }
                            catch (System.UnauthorizedAccessException e)
                            {
                                Mq.Error("Failed to get permissions on " + shareResult.SharePath);
                            }

                            if (MyOptions.ScanFoundShares)
                            {
                                Mq.Trace("Creating a TreeWalker task for " + shareResult.SharePath);
                                TreeTaskScheduler.New(() =>
                                {
                                    try
                                    {
                                        TreeWalker.WalkTree(shareResult.SharePath);
                                    }
                                    catch (Exception e)
                                    {
                                        Mq.Error("Exception in TreeWalker task for share " + shareResult.SharePath);
                                        Mq.Error(e.ToString());
                                    }
                                });
                            }
                            Mq.ShareResult(shareResult);
                        }
                        else if (MyOptions.LogDeniedShares == true)
                        {
                            Mq.ShareResult(shareResult);
                        }
                    }
                }
            }
        }
Пример #17
0
        public void SetDomainComputers(string LdapFilter)
        {
            DirectorySearch ds = GetDirectorySearcher();

            List <string> domainComputers = new List <string>();

            try
            {
                if (!MyOptions.DfsOnly)
                {
                    // if we aren't limiting the scan to DFS shares then let's get some computer targets.

                    List <string> ldapPropertiesList = new List <string> {
                        "name", "dNSHostName", "lastLogonTimeStamp"
                    };
                    string ldapFilter = LdapFilter;

                    // extremely dirty hack to break a sig I once saw for Snaffler's LDAP queries. ;-)
                    int num = random.Next(1, 5);
                    while (num > 0)
                    {
                        Guid guid = Guid.NewGuid();
                        ldapPropertiesList.Add(guid.ToString());
                        --num;
                    }
                    string[] ldapProperties = ldapPropertiesList.ToArray();

                    IEnumerable <SearchResultEntry> searchResultEntries = ds.QueryLdap(ldapFilter, ldapProperties, System.DirectoryServices.Protocols.SearchScope.Subtree);

                    // set a window of "the last 4 months" - if a computer hasn't logged in to the domain in 4 months it's probably gone.
                    DateTime validLltsWindow = DateTime.Now.AddMonths(-4);
                    foreach (SearchResultEntry resEnt in searchResultEntries)
                    {
                        int  uacFlags;
                        bool success =
                            int.TryParse(resEnt.GetProperty("userAccountControl"),
                                         out uacFlags);

                        UserAccountControlFlags userAccFlags = (UserAccountControlFlags)uacFlags;

                        if (userAccFlags.HasFlag(UserAccountControlFlags.AccountDisabled))
                        {
                            continue;
                        }

                        try
                        {
                            // get the last logon timestamp value as a datetime
                            string lltsString = resEnt.GetProperty("lastlogontimestamp");
                            long   lltsLong;
                            long.TryParse(lltsString, out lltsLong);
                            DateTime lltsDateTime = DateTime.FromFileTime(lltsLong);
                            // compare it to our window, and if lltsDateTime is older, skip the computer acct.
                            if (lltsDateTime <= validLltsWindow)
                            {
                                continue;
                            }
                        }
                        catch (Exception e)
                        {
                            Mq.Error("Error calculating lastLogonTimeStamp for computer account " + resEnt.DistinguishedName);
                        }

                        if (!String.IsNullOrEmpty(resEnt.GetProperty("dNSHostName")))
                        {
                            string computerName = resEnt.GetProperty("dNSHostName");
                            domainComputers.Add(computerName);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Mq.Trace(e.ToString());
            }

            this._domainComputers = domainComputers;
        }
Пример #18
0
        public bool Parse(string[] args)
        {
            Mq.Info("Parsing args...");
            var success = false;

            // define args
            var outFileArg = new ValueArgument <string>('o', "outfile",
                                                        "Path for output file. You probably want this if you're not using -s.");
            var verboseArg = new ValueArgument <string>('v', "verbosity",
                                                        "Controls verbosity level, options are Trace (most verbose), Debug (less verbose), Info (less verbose still, default), and Data (results only). e.g '-v debug' ");
            var helpArg = new SwitchArgument('h', "help", "Displays this help.", false);
            //var extMatchArg = new ValueArgument<string>('e', "extmatch",
            //    "Path to wordlist for searching by exact extension match.");
            //var nameMatchArg = new ValueArgument<string>('n', "namematch",
            //    "Path to wordlist for searching by exact filename match.");
            //var grepMatchArg = new ValueArgument<string>('g', "grepmatch",
            //    "Path to wordlist for searching by grepping the contents of files with \"interesting\" extensions.");
            //var partialMatchArg = new ValueArgument<string>('p', "partialmatch",
            //    "Path to wordlist for searching by partial filename match.");
            //var pathMatchArg = new ValueArgument<string>('a', "pathmatch",
            //    "Path to wordlist for searching by partial path match.");
            //var extSkipMatchArg = new ValueArgument<string>('x', "extskipmatch",
            //    "Path to wordlist for extensions that should be skipped.");
            var stdOutArg = new SwitchArgument('s', "stdout",
                                               "Enables outputting results to stdout as soon as they're found. You probably want this if you're not using -o.",
                                               false);
            var mirrorArg = new ValueArgument <string>('m', "mirror",
                                                       "Enables and assigns an output dir for snaffler to automatically take a copy of any found files.");
            var fileHuntArg = new SwitchArgument('f', "filehuntoff",
                                                 "Disables file discovery, will only perform computer and share discovery.", false);
            var dirTargetArg = new ValueArgument <string>('i', "dirtarget",
                                                          "Disables computer and share discovery, requires a path to a directory in which to perform file discovery.");
            var maxThreadsArg = new ValueArgument <int>('t', "threads", "Maximum number of threads. Default 30.");
            var domainArg     = new ValueArgument <string>('d', "domain",
                                                           "Domain to search for computers to search for shares on to search for files in. Easy.");
            var adminshareArg = new SwitchArgument('a', "cdolla",
                                                   "Enables scanning of C$ shares if found. Can be prone to false positives but more thorough.", false);
            var domainControllerArg = new ValueArgument <string>('c', "domaincontroller",
                                                                 "Domain controller to query for a list of domain computers.");
            var maxGrepSizeArg = new ValueArgument <long>('r', "maxgrepsize",
                                                          "The maximum size file (in bytes) to search inside for interesting strings. Defaults to 500k.");
            var grepContextArg = new ValueArgument <int>('j', "grepcontext",
                                                         "How many bytes of context either side of found strings in files to show, e.g. -j 200");

            // list of letters i haven't used yet: bklquwyz

            var parser = new CommandLineParser.CommandLineParser();

            parser.Arguments.Add(outFileArg);
            parser.Arguments.Add(helpArg);
            //parser.Arguments.Add(extMatchArg);
            //parser.Arguments.Add(nameMatchArg);
            //parser.Arguments.Add(grepMatchArg);
            //parser.Arguments.Add(extSkipMatchArg);
            //parser.Arguments.Add(partialMatchArg);
            parser.Arguments.Add(stdOutArg);
            parser.Arguments.Add(mirrorArg);
            parser.Arguments.Add(fileHuntArg);
            parser.Arguments.Add(dirTargetArg);
            parser.Arguments.Add(maxThreadsArg);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(verboseArg);
            parser.Arguments.Add(adminshareArg);
            parser.Arguments.Add(domainControllerArg);
            parser.Arguments.Add(maxGrepSizeArg);
            parser.Arguments.Add(grepContextArg);

            // extra check to handle builtin behaviour from cmd line arg parser
            if ((args.Contains("--help") || args.Contains("/?") || args.Contains("help") || args.Contains("-h") || args.Length == 0))
            {
                parser.ShowUsage();
                Environment.Exit(0);
            }

            try
            {
                parser.ParseCommandLine(args);

                // get the args into our config


                // output args
                if (outFileArg.Parsed && (outFileArg.Value != null))
                {
                    LogToFile   = true;
                    LogFilePath = outFileArg.Value;
                    Mq.Degub("Logging to file at " + LogFilePath);
                }

                // Set loglevel.
                if (verboseArg.Parsed)
                {
                    var logLevelString = verboseArg.Value;
                    switch (logLevelString.ToLower())
                    {
                    case "debug":
                        LogLevel = LogLevel.Debug;
                        Mq.Degub("Set verbosity level to degub.");
                        break;

                    case "degub":
                        LogLevel = LogLevel.Debug;
                        Mq.Degub("Set verbosity level to degub.");
                        break;

                    case "trace":
                        LogLevel = LogLevel.Trace;
                        Mq.Degub("Set verbosity level to trace.");
                        break;

                    case "data":
                        LogLevel = LogLevel.Warn;
                        Mq.Degub("Set verbosity level to data.");
                        break;

                    default:
                        LogLevel = LogLevel.Info;
                        Mq.Error("Invalid verbosity level " + logLevelString +
                                 " falling back to default level (info).");
                        break;
                    }
                }

                // if enabled, display findings to the console
                LogToConsole = stdOutArg.Parsed;
                Mq.Degub("Enabled logging to stdout.");

                if (maxThreadsArg.Parsed)
                {
                    MaxThreads = maxThreadsArg.Value;
                    Mq.Degub("Max threads set to " + maxThreadsArg.Value);
                }

                // args that tell us about targeting
                if ((domainArg.Parsed) && (domainArg.Value != null))
                {
                    TargetDomain = domainArg.Value;
                    Mq.Degub("Target domain is " + domainArg.Value);
                }

                if ((domainControllerArg.Parsed) && (domainControllerArg.Value != null))
                {
                    TargetDc = domainControllerArg.Value;
                    Mq.Degub("Target DC is " + domainControllerArg.Value);
                }

                if (dirTargetArg.Parsed)
                {
                    ShareFinderEnabled = false;
                    DirTarget          = dirTargetArg.Value;
                    Mq.Degub("Disabled finding shares.");
                    Mq.Degub("Target path is " + dirTargetArg.Value);
                }

                if (adminshareArg.Parsed)
                {
                    ScanCDollarShares = true;
                    Mq.Degub("Scanning of C$ shares enabled.");
                }

                // if the user passes the various MatchArgs with no value, that disables them.
                // Otherwise load their wordlist into the appropriate config item.

                /*
                 * if (extMatchArg.Parsed)
                 * {
                 *  if (extMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactExtensionCheck = false;
                 *      Mq.Degub("Disabled matching based on exact file extension match.");
                 *  }
                 *  else
                 *  {
                 *      ExtensionsToKeep = File.ReadAllLines(extMatchArg.Value);
                 *      Mq.Degub("Using file at " + extMatchArg.Value + " for exact file extension matching.");
                 *  }
                 * }
                 *
                 * if (pathMatchArg.Parsed)
                 * {
                 *  if (pathMatchArg.Value.Length <= 0)
                 *  {
                 *      PartialPathCheck = false;
                 *      Mq.Degub("Disabled matching based on partial file path.");
                 *  }
                 *  else
                 *  {
                 *      PathsToKeep = File.ReadAllLines(pathMatchArg.Value);
                 *      Mq.Degub("Using file at " + pathMatchArg.Value + " for partial file path matching.");
                 *  }
                 * }
                 *
                 * if (extSkipMatchArg.Parsed)
                 * {
                 *  if (extSkipMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactExtensionSkipCheck = false;
                 *      Mq.Degub("Disabled skipping files with extensions on skip-list.");
                 *  }
                 *  else
                 *  {
                 *      ExtSkipList = File.ReadAllLines(extSkipMatchArg.Value);
                 *      Mq.Degub("Using file at " + extSkipMatchArg.Value + " for extension skip-list.");
                 *  }
                 * }
                 *
                 * if (nameMatchArg.Parsed)
                 * {
                 *  if (nameMatchArg.Value.Length <= 0)
                 *  {
                 *      ExactNameCheck = false;
                 *      Mq.Degub("Disabled matching based on exact file name");
                 *  }
                 *  else
                 *  {
                 *      FileNamesToKeep = File.ReadAllLines(nameMatchArg.Value);
                 *      Mq.Degub("Using file at " + nameMatchArg.Value + " for exact file name matching.");
                 *  }
                 * }
                 *
                 * if (grepMatchArg.Parsed)
                 * {
                 *  if (grepMatchArg.Value.Length <= 0)
                 *  {
                 *      GrepByExtensionCheck = false;
                 *      Mq.Degub("Disabled matching based on file contents.");
                 *  }
                 *  else
                 *  {
                 *      GrepStrings = File.ReadAllLines(grepMatchArg.Value);
                 *      Mq.Degub("Using file at " + grepMatchArg.Value + " for file contents matching.");
                 *  }
                 * }
                 *
                 * if (partialMatchArg.Parsed)
                 * {
                 *  if (partialMatchArg.Value.Length <= 0)
                 *  {
                 *      PartialNameCheck = false;
                 *      Mq.Degub("Disabled partial file name matching.");
                 *  }
                 *  else
                 *  {
                 *      NameStringsToKeep = File.ReadAllLines(partialMatchArg.Value);
                 *      Mq.Degub("Using file at " + partialMatchArg.Value + " for partial file name matching.");
                 *  }
                 * }
                 */
                if (maxGrepSizeArg.Parsed)
                {
                    MaxSizeToGrep = maxGrepSizeArg.Value;
                    Mq.Degub("We won't bother looking inside files if they're bigger than " + MaxSizeToGrep + " bytes");
                }

                // how many bytes
                if (grepContextArg.Parsed)
                {
                    GrepContextBytes = grepContextArg.Value;
                    Mq.Degub(
                        "We'll show you " + grepContextArg.Value + " bytes of context around matches inside files.");
                }

                // if enabled, grab a copy of files that we like.
                if (mirrorArg.Parsed)
                {
                    if (mirrorArg.Value.Length <= 0)
                    {
                        Mq.Error("-m or -mirror arg requires a path value.");
                        throw new ArgumentException("Invalid argument combination.");
                    }

                    EnableMirror = true;
                    MirrorPath   = mirrorArg.Value.TrimEnd('\\');
                    Mq.Degub("Mirroring matched files to path " + MirrorPath);
                }

                if (!LogToConsole && !LogToFile)
                {
                    Mq.Error(
                        "\nYou didn't enable output to file or to the console so you won't see any results or debugs or anything. Your l0ss.");
                    throw new ArgumentException("Pointless argument combination.");
                }
            }
            catch (Exception e)
            {
                Mq.Error(e.ToString());
                throw;
            }
            success = true;
            return(success);
        }
Пример #19
0
        public void WalkTree(string currentDir, int delayTime = 1)
        {
            // Walks a tree checking files and generating results as it goes.

            if (!Directory.Exists(currentDir))
            {
                return;
            }

            try
            {
                string[] files = Directory.GetFiles(currentDir);
                // check if we actually like the files
                foreach (string file in files)
                {
                    //FileTaskScheduler.New(() =>
                    //{
                    try
                    {
                        FileScanner.ScanFile(file);
                    }
                    catch (Exception e)
                    {
                        Mq.Error("Exception in FileScanner task for file " + file);
                        Mq.Trace(e.ToString());
                    }

                    //Mq.Info("Sleeping " + delayTime.ToString() + " Seconds");
                    System.Threading.Thread.Sleep(delayTime);
                    //});
                }
            }
            catch (UnauthorizedAccessException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (DirectoryNotFoundException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (Exception e)
            {
                Mq.Trace(e.ToString());
                //continue;
            }

            try
            {
                string[] subDirs = Directory.GetDirectories(currentDir);
                // Create a new treewalker task for each subdir.
                if (subDirs.Length >= 1)
                {
                    foreach (string dirStr in subDirs)
                    {
                        Mq.Degub($"Processing directory {dirStr}");
                        foreach (ClassifierRule classifier in MyOptions.DirClassifiers)
                        {
                            try
                            {
                                DirClassifier dirClassifier = new DirClassifier(classifier);
                                DirResult     dirResult     = dirClassifier.ClassifyDir(dirStr);

                                if (dirResult.ScanDir)
                                {
                                    //TreeTaskScheduler.New(() =>
                                    //{
                                    try
                                    {
                                        WalkTree(dirStr, delayTime);
                                    }
                                    catch (Exception e)
                                    {
                                        Mq.Error("Exception in TreeWalker task for dir " + dirStr);
                                        Mq.Error(e.ToString());
                                    }
                                    //});
                                }
                            }
                            catch (Exception e)
                            {
                                Mq.Trace(e.ToString());
                                continue;
                            }

                            // Mq.Info("Sleeping " + delayTime.ToString() + " Seconds");
                            System.Threading.Thread.Sleep(delayTime);
                        }
                    }
                }
            }
            catch (UnauthorizedAccessException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (DirectoryNotFoundException)
            {
                //Mq.Trace(e.ToString());
                //continue;
            }
            catch (Exception e)
            {
                Mq.Trace(e.ToString());
                //continue;
            }
        }