コード例 #1
0
        public static JObject GetFileDaclJObject(string filePathString)
        {
            JObject      fileDaclsJObject = new JObject();
            FileSecurity filePathSecObj   = new FileSecurity();

            try
            {
                filePathSecObj = File.GetAccessControl(filePathString);
            }
            catch (System.ArgumentException e)
            {
                Console.WriteLine("Tried to check file permissions on invalid path: " + filePathString.ToString());
                return(fileDaclsJObject);
            }

            AuthorizationRuleCollection fileAccessRules =
                filePathSecObj.GetAccessRules(true, true, typeof(SecurityIdentifier));

            foreach (FileSystemAccessRule fileAccessRule in fileAccessRules)
            {
                // get inheritance and access control type values
                string isInheritedString = "False";
                if (fileAccessRule.IsInherited)
                {
                    isInheritedString = "True";
                }
                string accessControlTypeString = "Allow";
                if (fileAccessRule.AccessControlType == AccessControlType.Deny)
                {
                    accessControlTypeString = "Deny";
                }

                // get the user's SID
                string identityReferenceString = fileAccessRule.IdentityReference.ToString();
                string displayNameString       = LDAPstuff.GetUserFromSid(identityReferenceString);
                // get the rights
                string fileSystemRightsString = fileAccessRule.FileSystemRights.ToString();
                // strip spaces
                fileSystemRightsString = fileSystemRightsString.Replace(" ", "");
                // turn them into an array
                string[] fileSystemRightsArray = fileSystemRightsString.Split(',');
                // then into a JArray
                JArray fileSystemRightsJArray = new JArray();
                foreach (string x in fileSystemRightsArray)
                {
                    fileSystemRightsJArray.Add(x);
                }

                JObject fileDaclJObject = new JObject();
                fileDaclJObject.Add("Display Name", displayNameString);
                fileDaclJObject.Add("Allow or Deny?", accessControlTypeString);
                fileDaclJObject.Add("Inherited?", isInheritedString);
                fileDaclJObject.Add("Rights", fileSystemRightsJArray);
                fileDaclsJObject.Add(identityReferenceString, fileDaclJObject);
            }

            return(fileDaclsJObject);
        }
コード例 #2
0
        private JObject GetAssessedGroupMember(JToken member)
        {
            JObject assessedMember = new JObject();

            assessedMember.Add("Name", Utility.GetSafeString(member, "@name"));
            assessedMember.Add("Action", Utility.GetSafeString(member, "@action"));
            string memberSid = Utility.GetSafeString(member, "@sid");

            if (memberSid.Length > 0)
            {
                assessedMember.Add("SID", memberSid);
                if (GlobalVar.OnlineChecks)
                {
                    string resolvedSID = LDAPstuff.GetUserFromSid(memberSid);
                    assessedMember.Add("Display Name From SID", resolvedSID);
                }
            }
            return(assessedMember);
        }
コード例 #3
0
        private static void Main(string[] args)
        {
            DateTime grouper2StartTime = DateTime.Now;

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            ValueArgument <string> htmlArg             = new ValueArgument <string>('f', "html", "Path for html output file.");
            SwitchArgument         debugArg            = new SwitchArgument('v', "verbose", "Enables debug mode. Probably quite noisy and rarely necessary. Will also show you the names of any categories of policies" +
                                                                            " that Grouper saw but didn't have any means of processing. I eagerly await your pull request.", false);
            SwitchArgument offlineArg = new SwitchArgument('o', "offline",
                                                           "Disables checks that require LDAP comms with a DC or SMB comms with file shares found in policy settings. Requires that you define a value for -s.",
                                                           false);
            ValueArgument <string> sysvolArg =
                new ValueArgument <string>('s', "sysvol", "Set the path to a domain SYSVOL directory.");
            ValueArgument <int> intlevArg = new ValueArgument <int>('i', "interestlevel",
                                                                    "The minimum interest level to display. i.e. findings with an interest level lower than x will not be seen in output. Defaults to 1, i.e. show " +
                                                                    "everything except some extremely dull defaults. If you want to see those too, do -i 0.");
            ValueArgument <int>    threadsArg = new ValueArgument <int>('t', "threads", "Max number of threads. Defaults to 10.");
            ValueArgument <string> domainArg  =
                new ValueArgument <string>('d', "domain", "Domain to query for Group Policy Goodies.");
            ValueArgument <string> passwordArg = new ValueArgument <string>('p', "password", "Password to use for LDAP operations.");
            ValueArgument <string> usernameArg =
                new ValueArgument <string>('u', "username", "Username to use for LDAP operations.");
            SwitchArgument helpArg           = new SwitchArgument('h', "help", "Displays this help.", false);
            SwitchArgument prettyArg         = new SwitchArgument('g', "pretty", "Switches output from the raw Json to a prettier format.", false);
            SwitchArgument noMessArg         = new SwitchArgument('m', "nomess", "Avoids file writes at all costs. May find less stuff.", false);
            SwitchArgument currentPolOnlyArg = new SwitchArgument('c', "currentonly", "Only checks current policies, ignoring stuff in those " +
                                                                  "Policies_NTFRS_* directories that result from replication failures.", false);
            SwitchArgument noGrepScriptsArg = new SwitchArgument('n', "nogrepscripts", "Don't grep through the files in the \"Scripts\" subdirectory", false);
            SwitchArgument quietModeArg     = new SwitchArgument('q', "quiet", "Enables quiet mode. Turns off progress counter.", false);

            parser.Arguments.Add(usernameArg);
            parser.Arguments.Add(passwordArg);
            parser.Arguments.Add(debugArg);
            parser.Arguments.Add(intlevArg);
            parser.Arguments.Add(sysvolArg);
            parser.Arguments.Add(offlineArg);
            parser.Arguments.Add(threadsArg);
            parser.Arguments.Add(helpArg);
            parser.Arguments.Add(prettyArg);
            parser.Arguments.Add(noMessArg);
            parser.Arguments.Add(currentPolOnlyArg);
            parser.Arguments.Add(noGrepScriptsArg);
            parser.Arguments.Add(domainArg);
            parser.Arguments.Add(htmlArg);
            parser.Arguments.Add(quietModeArg);

            // set a few defaults
            string sysvolDir = "";

            GlobalVar.OnlineChecks = true;
            int  maxThreads   = 10;
            bool prettyOutput = false;

            GlobalVar.NoMess = false;
            bool   noNtfrs           = false;
            bool   noGrepScripts     = false;
            string userDefinedDomain = "";
            bool   htmlOut           = false;
            string htmlOutPath       = "";

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

            try
            {
                parser.ParseCommandLine(args);
                if (helpArg.Parsed)
                {
                    foreach (Argument arg in parser.Arguments)
                    {
                        Console.Error.Write("-");
                        Console.Error.Write(arg.ShortName);
                        Console.Error.Write(" " + arg.LongName);
                        Console.Error.WriteLine(" - " + arg.Description);
                    }

                    Environment.Exit(0);
                }
                if (offlineArg.Parsed && offlineArg.Value && sysvolArg.Parsed)
                {
                    // args config for valid offline run.
                    GlobalVar.OnlineChecks = false;
                    sysvolDir = sysvolArg.Value;
                }

                if (offlineArg.Parsed && offlineArg.Value && !sysvolArg.Parsed)
                {
                    // handle someone trying to run in offline mode without giving a value for sysvol
                    Console.Error.WriteLine(
                        "\nOffline mode requires you to provide a value for -s, the path where Grouper2 can find the domain SYSVOL share, or a copy of it at least.");
                    Environment.Exit(1);
                }

                if (intlevArg.Parsed)
                {
                    // handle interest level parsing
                    Console.Error.WriteLine("\nRoger. Everything with an Interest Level lower than " +
                                            intlevArg.Value.ToString() + " is getting thrown on the floor.");
                    GlobalVar.IntLevelToShow = intlevArg.Value;
                }
                else
                {
                    GlobalVar.IntLevelToShow = 1;
                }

                if (htmlArg.Parsed)
                {
                    htmlOut     = true;
                    htmlOutPath = htmlArg.Value;
                }
                if (debugArg.Parsed)
                {
                    Console.Error.WriteLine("\nVerbose debug mode enabled. Hope you like yellow.");
                    GlobalVar.DebugMode = true;
                }

                if (threadsArg.Parsed)
                {
                    Console.Error.WriteLine("\nMaximum threads set to: " + threadsArg.Value);
                    maxThreads = threadsArg.Value;
                }

                if (sysvolArg.Parsed)
                {
                    Console.Error.WriteLine("\nYou specified that I should assume SYSVOL is here: " + sysvolArg.Value);
                    sysvolDir = sysvolArg.Value;
                }

                if (prettyArg.Parsed)
                {
                    Console.Error.WriteLine("\nSwitching output to pretty mode. Nice.");
                    prettyOutput = true;
                }

                if (noMessArg.Parsed)
                {
                    Console.Error.WriteLine("\nNo Mess mode enabled. Good for OPSEC, maybe bad for finding all the vulns? All \"Directory Is Writable\" checks will return false.");

                    GlobalVar.NoMess = true;
                }
                if (quietModeArg.Parsed)
                {
                    GlobalVar.QuietMode = true;
                }
                if (currentPolOnlyArg.Parsed)
                {
                    Console.Error.WriteLine("\nOnly looking at current policies and scripts, not checking any of those weird old NTFRS dirs.");
                    noNtfrs = true;
                }

                if (domainArg.Parsed)
                {
                    Console.Error.Write("\nYou told me to talk to domain " + domainArg.Value + " so I'm gonna do that.");
                    if (!(usernameArg.Parsed) || !(passwordArg.Parsed))
                    {
                        Console.Error.Write("\nIf you specify a domain you need to specify a username and password too using -u and -p.");
                    }

                    userDefinedDomain = domainArg.Value;
                    string[]      splitDomain = userDefinedDomain.Split('.');
                    StringBuilder sb          = new StringBuilder();
                    int           pi          = splitDomain.Length;
                    int           ind         = 1;
                    foreach (string piece in splitDomain)
                    {
                        sb.Append("DC=" + piece);
                        if (pi != ind)
                        {
                            sb.Append(",");
                        }
                        ind++;
                    }

                    GlobalVar.UserDefinedDomain   = userDefinedDomain;
                    GlobalVar.UserDefinedDomainDn = sb.ToString();
                    GlobalVar.UserDefinedPassword = passwordArg.Value;
                    GlobalVar.UserDefinedUsername = usernameArg.Value;
                }

                if (noGrepScriptsArg.Parsed)
                {
                    Console.Error.WriteLine("\nNot gonna look through scripts in SYSVOL for goodies.");
                    noGrepScripts = true;
                }
            }
            catch (CommandLineException e)
            {
                Console.WriteLine(e.Message);
            }

            if (GlobalVar.UserDefinedDomain != null)
            {
                Console.Error.WriteLine("\nRunning as user: "******"\\" + GlobalVar.UserDefinedUsername);
            }
            else
            {
                Console.Error.WriteLine("\nRunning as user: "******"\\" + Environment.UserName);
            }
            Console.Error.WriteLine("\nAll online checks will be performed in the context of this user.");


            if (!prettyOutput)
            {
                Output.PrintBanner();
            }

            // Ask the DC for GPO details
            string currentDomainString = "";

            if (GlobalVar.OnlineChecks)
            {
                if (userDefinedDomain != "")
                {
                    currentDomainString = userDefinedDomain;
                }
                else
                {
                    Console.Error.WriteLine("\nTrying to figure out what AD domain we're working with.");
                    try
                    {
                        currentDomainString = Domain.GetCurrentDomain().ToString();
                    }
                    catch (ActiveDirectoryOperationException e)
                    {
                        Console.Error.WriteLine("\nCouldn't talk to the domain properly. If you're trying to run offline you should use the -o switch. Failing that, try rerunning with -d to specify a domain or -v to get more information about the error.");
                        Utility.Output.DebugWrite(e.ToString());

                        Environment.Exit(1);
                    }
                }

                Console.WriteLine("\nCurrent AD Domain is: " + currentDomainString);

                // if we're online, get a bunch of metadata about the GPOs via LDAP
                JObject domainGpos = new JObject();

                if (GlobalVar.OnlineChecks)
                {
                    domainGpos = GetDomainGpoData.DomainGpoData;
                }

                Console.WriteLine("");

                if (sysvolDir == "")
                {
                    sysvolDir = @"\\" + currentDomainString + @"\sysvol\" + currentDomainString + @"\";
                    Console.Error.WriteLine("Targeting SYSVOL at: " + sysvolDir);
                }
            }
            else if ((GlobalVar.OnlineChecks == false) && sysvolDir.Length > 1)
            {
                Console.Error.WriteLine("\nTargeting SYSVOL at: " + sysvolDir);
            }
            else
            {
                Console.Error.WriteLine("\nSomething went wrong with parsing the path to sysvol and I gave up.");
                Environment.Exit(1);
            }

            // get all the dirs with Policies and scripts in an array.
            string[] sysvolDirs =
                Directory.GetDirectories(sysvolDir);

            Console.Error.WriteLine(
                "\nI found all these directories in SYSVOL...");
            Console.Error.WriteLine("#########################################");
            foreach (string line in sysvolDirs)
            {
                Console.Error.WriteLine(line);
            }
            Console.Error.WriteLine("#########################################");

            List <string> sysvolPolDirs    = new List <string>();
            List <string> sysvolScriptDirs = new List <string>();

            if (noNtfrs)
            {
                Console.Error.WriteLine("... but I'm not going to look in any of them except .\\Policies and .\\Scripts because you told me not to.");
                sysvolPolDirs.Add(sysvolDir + "Policies\\");
                sysvolScriptDirs.Add(sysvolDir + "Scripts\\");
            }
            else
            {
                Console.Error.WriteLine("... and I'm going to find all the goodies I can in all of them.");
                foreach (string dir in sysvolDirs)
                {
                    if (dir.ToLower().Contains("scripts"))
                    {
                        sysvolScriptDirs.Add(dir);
                    }

                    if (dir.ToLower().Contains("policies"))
                    {
                        sysvolPolDirs.Add(dir);
                    }
                }
            }

            // get all the policy dirs
            List <string> gpoPaths = new List <string>();

            foreach (string policyPath in sysvolPolDirs)
            {
                try
                {
                    gpoPaths = Directory.GetDirectories(policyPath).ToList();
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("I had a problem with " + policyPath +
                                            ". I guess you could try to fix it?");
                    Output.DebugWrite(e.ToString());
                }
            }

            JObject gpoPackageData = new JObject();

            // Grab Packages from LDAP
            if (GlobalVar.OnlineChecks)
            {
                gpoPackageData = LDAPstuff.GetGpoPackages(Environment.UserDomainName.ToString());
            }



            // create a JObject to put all our output goodies in.
            JObject grouper2Output = new JObject();
            // so for each uid directory (including ones with that dumb broken domain replication condition)
            // we're going to gather up all our goodies and put them into that dict we just created.
            // Create a TaskScheduler
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(maxThreads);
            List <Task> gpoTasks = new List <Task>();

            // create a TaskFactory
            TaskFactory             gpoFactory = new TaskFactory(lcts);
            CancellationTokenSource gpocts     = new CancellationTokenSource();

            Console.Error.WriteLine("\n" + gpoPaths.Count.ToString() + " GPOs to process.");
            Console.Error.WriteLine("\nStarting processing GPOs with " + maxThreads.ToString() + " threads.");

            JObject taskErrors = new JObject();

            // Create a task for each GPO
            foreach (string gpoPath in gpoPaths)
            {
                // skip PolicyDefinitions directory
                if (gpoPath.Contains("PolicyDefinitions"))
                {
                    continue;
                }
                Task t = gpoFactory.StartNew(() =>
                {
                    try
                    {
                        JObject matchedPackages = new JObject();
                        if (GlobalVar.OnlineChecks)
                        {
                            // figure out the gpo UID from the path so we can see which packages need to be processed here.
                            string[] gpoPathArr      = gpoPath.Split('{');
                            string gpoPathBackString = gpoPathArr[1];
                            string[] gpoPathBackArr  = gpoPathBackString.Split('}');
                            string gpoUid            = gpoPathBackArr[0].ToString().ToLower();

                            // see if we have any appropriate matching packages and construct a little bundle
                            foreach (KeyValuePair <string, JToken> gpoPackage in gpoPackageData)
                            {
                                string packageParentGpoUid = gpoPackage.Value["ParentGPO"].ToString().ToLower()
                                                             .Trim('{', '}');
                                if (packageParentGpoUid == gpoUid)
                                {
                                    JProperty assessedPackage = PackageAssess.AssessPackage(gpoPackage);
                                    if (assessedPackage != null)
                                    {
                                        matchedPackages.Add(assessedPackage);
                                    }
                                }
                            }
                        }


                        JObject gpoFindings = ProcessGpo(gpoPath, matchedPackages);

                        if (gpoFindings != null)
                        {
                            if (gpoFindings.HasValues)
                            {
                                lock (grouper2Output)
                                {
                                    if (!(gpoPath.Contains("NTFRS")))
                                    {
                                        grouper2Output.Add(("Current Policy - " + gpoPath), gpoFindings);
                                    }
                                    else
                                    {
                                        grouper2Output.Add(gpoPath, gpoFindings);
                                    }
                                }
                            }
                        }
                    }

                    catch (Exception e)
                    {
                        taskErrors.Add(gpoPath, e.ToString());
                    }
                }, gpocts.Token);
                gpoTasks.Add(t);
            }

            // put 'em all in a happy little array
            Task[] gpoTaskArray = gpoTasks.ToArray();

            // create a little counter to provide status updates
            int totalGpoTasksCount  = gpoTaskArray.Length;
            int incompleteTaskCount = gpoTaskArray.Length;
            int remainingTaskCount  = gpoTaskArray.Length;

            while (remainingTaskCount > 0)
            {
                Task[] incompleteTasks =
                    Array.FindAll(gpoTaskArray, element => element.Status != TaskStatus.RanToCompletion);
                incompleteTaskCount = incompleteTasks.Length;
                Task[] faultedTasks = Array.FindAll(gpoTaskArray,
                                                    element => element.Status == TaskStatus.Faulted);
                int    faultedTaskCount  = faultedTasks.Length;
                int    completeTaskCount = totalGpoTasksCount - incompleteTaskCount - faultedTaskCount;
                int    percentage        = (int)Math.Round((double)(100 * completeTaskCount) / totalGpoTasksCount);
                string percentageString  = percentage.ToString();
                if (GlobalVar.QuietMode != true)
                {
                    Console.Error.Write("");

                    Console.Error.Write("\r" + completeTaskCount.ToString() + "/" + totalGpoTasksCount.ToString() +
                                        " GPOs processed. " + percentageString + "% complete. ");
                    if (faultedTaskCount > 0)
                    {
                        Console.Error.Write(faultedTaskCount.ToString() + " GPOs failed to process.");
                    }
                }

                remainingTaskCount = incompleteTaskCount - faultedTaskCount;
            }

            // make double sure tasks all finished
            Task.WaitAll(gpoTasks.ToArray());
            gpocts.Dispose();

            // do the script grepping
            if (!(noGrepScripts))
            {
                Console.Error.Write("\n\nProcessing SYSVOL script dirs.\n\n");
                JObject processedScriptDirs = ProcessScripts(sysvolScriptDirs);
                if ((processedScriptDirs != null) && (processedScriptDirs.HasValues))
                {
                    grouper2Output.Add("Scripts", processedScriptDirs);
                }
            }

            Console.Error.WriteLine("Errors in processing GPOs:");
            Console.Error.WriteLine(taskErrors.ToString());

            // Final output is finally happening finally here:

            if (prettyOutput || htmlOut)
            {
                // gotta add a line feed to make sure we're clear to write the nice output.
                Console.Error.WriteLine("\n");

                if (htmlOut)
                {
                    try
                    {
                        // gotta add a line feed to make sure we're clear to write the nice output.

                        Document htmlDoc = new Document();

                        htmlDoc.Children.Add(Output.GetG2BannerDocument());

                        foreach (KeyValuePair <string, JToken> gpo in grouper2Output)
                        {
                            htmlDoc.Children.Add(Output.GetAssessedGpoOutput(gpo));
                        }
                        ConsoleRenderer.RenderDocument(htmlDoc,
                                                       new HtmlRenderTarget(File.Create(htmlOutPath), new UTF8Encoding(false)));
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.Error.WriteLine("Tried to write html output file but I'm not allowed.");
                    }
                }

                if (prettyOutput)
                {
                    Document prettyDoc = new Document();

                    prettyDoc.Children.Add(Output.GetG2BannerDocument());

                    foreach (KeyValuePair <string, JToken> gpo in grouper2Output)
                    {
                        prettyDoc.Children.Add(Output.GetAssessedGpoOutput(gpo));
                    }
                    ConsoleRenderer.RenderDocument(prettyDoc);
                }
            }
            else
            {
                Console.WriteLine(grouper2Output);
                Console.Error.WriteLine("If you find yourself thinking 'wtf this is very ugly and hard to read', consider trying the -g argument.");
            }


            // get the time it took to do the thing and give to user
            DateTime grouper2EndTime       = DateTime.Now;
            TimeSpan grouper2RunTime       = grouper2EndTime.Subtract(grouper2StartTime);
            string   grouper2RunTimeString =
                $"{grouper2RunTime.Hours}:{grouper2RunTime.Minutes}:{grouper2RunTime.Seconds}:{grouper2RunTime.Milliseconds}";

            Console.WriteLine("Grouper2 took " + grouper2RunTimeString + " to run.");

            if (GlobalVar.CleanupList != null)
            {
                List <string> cleanupList = Util.DedupeList(GlobalVar.CleanupList);
                if (cleanupList.Count >= 1)
                {
                    Console.WriteLine("\n\nGrouper2 tried to create these files. It probably failed, but just in case it didn't, you might want to check and clean them up.\n");
                    foreach (string path in cleanupList)
                    {
                        Console.WriteLine(path);
                    }
                }
            }
            // FINISHED!
            bool isDebuggerAttached = System.Diagnostics.Debugger.IsAttached;

            if (isDebuggerAttached)
            {
                Console.Error.WriteLine("Press any key to Exit");
                Console.ReadKey();
            }
            Environment.Exit(0);
        }
コード例 #4
0
ファイル: AssessHandlers.cs プロジェクト: liamosaur/Grouper2
        public static JObject AssessPrivRights(JToken privRights)
        {
            JObject jsonData      = JankyDb.Instance;
            JArray  intPrivRights = (JArray)jsonData["privRights"]["item"];

            // create an object to put the results in
            Dictionary <string, Dictionary <string, string> > matchedPrivRights = new Dictionary <string, Dictionary <string, string> >();

            //set an intentionally non-matchy domainSid value unless we doing online checks.
            string domainSid = "X";

            if (GlobalVar.OnlineChecks)
            {
                domainSid = LDAPstuff.GetDomainSid();
            }

            foreach (JProperty privRight in privRights.Children <JProperty>())
            {
                foreach (JToken intPrivRight in intPrivRights)
                {
                    // if the priv is interesting
                    if ((string)intPrivRight["privRight"] == privRight.Name)
                    {
                        //create a dict to put the trustees into
                        Dictionary <string, string> trusteesDict = new Dictionary <string, string>();
                        //then for each trustee it's granted to
                        foreach (string trustee in privRight.Value)
                        {
                            string displayName = "unknown";
                            // clean up the trustee SID
                            string trusteeClean = trustee.Trim('*');
                            JToken checkedSid   = Utility.CheckSid(trusteeClean);

                            // display some info if they match.
                            if (checkedSid != null)
                            {
                                displayName = (string)checkedSid["displayName"];
                            }
                            // if they don't match, handle that.
                            else
                            {
                                if (GlobalVar.OnlineChecks)
                                {
                                    try
                                    {
                                        if (trusteeClean.StartsWith(domainSid))
                                        {
                                            string resolvedSid = LDAPstuff.GetUserFromSID(trusteeClean);
                                            displayName = resolvedSid;
                                        }
                                    }
                                    catch (IdentityNotMappedException e)
                                    {
                                        displayName = "Failed to resolve SID";
                                    }
                                    //LDAPStuff.ResolveSID?
                                    //TODO: look up unknown SIDS in the domain if we can.
                                }
                            }
                            trusteesDict.Add(trusteeClean, displayName);
                        }
                        // add the results to our dictionary of trustees
                        string matchedPrivRightName = privRight.Name;
                        matchedPrivRights.Add(matchedPrivRightName, trusteesDict);
                    }
                }
            }
            // cast our dict to a jobject and return it.
            JObject matchedPrivRightsJson = (JObject)JToken.FromObject(matchedPrivRights);

            return(matchedPrivRightsJson);
        }
コード例 #5
0
        public static JObject GetFileDaclJObject(string filePathString)
        {
            if (!GlobalVar.OnlineChecks)
            {
                return(new JObject());
            }
            JObject      fileDaclsJObject = new JObject();
            FileSecurity filePathSecObj;

            try
            {
                filePathSecObj = File.GetAccessControl(filePathString);
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Tried to check file permissions on invalid path: " + filePathString);
                return(null);
            }
            catch (UnauthorizedAccessException e)
            {
                if (GlobalVar.DebugMode)
                {
                    DebugWrite(e.ToString());
                }
                return(null);
            }

            AuthorizationRuleCollection fileAccessRules =
                filePathSecObj.GetAccessRules(true, true, typeof(SecurityIdentifier));

            foreach (FileSystemAccessRule fileAccessRule in fileAccessRules)
            {
                // get inheritance and access control type values
                string isInheritedString = "False";
                if (fileAccessRule.IsInherited)
                {
                    isInheritedString = "True";
                }
                string accessControlTypeString = "Allow";
                if (fileAccessRule.AccessControlType == AccessControlType.Deny)
                {
                    accessControlTypeString = "Deny";
                }

                // get the user's SID
                string identityReferenceString = fileAccessRule.IdentityReference.ToString();
                string displayNameString       = LDAPstuff.GetUserFromSid(identityReferenceString);
                // get the rights
                string fileSystemRightsString = fileAccessRule.FileSystemRights.ToString();
                // strip spaces
                fileSystemRightsString = fileSystemRightsString.Replace(" ", "");
                // turn them into an array
                string[] fileSystemRightsArray = fileSystemRightsString.Split(',');
                // then into a JArray
                JArray fileSystemRightsJArray = new JArray();
                foreach (string x in fileSystemRightsArray)
                {
                    fileSystemRightsJArray.Add(x);
                }

                JObject fileDaclJObject = new JObject
                {
                    { accessControlTypeString, displayNameString },
                    { "Inherited?", isInheritedString },
                    { "Rights", fileSystemRightsJArray }
                };
                try
                {
                    fileDaclsJObject.Merge(fileDaclJObject, new JsonMergeSettings
                    {
                        // union array values together to avoid duplicates
                        MergeArrayHandling = MergeArrayHandling.Union
                    });
                    //fileDaclsJObject.Add((identityReferenceString + " - " + accessControlTypeString), fileDaclJObject);
                }
                catch (ArgumentException e)
                {
                    if (GlobalVar.DebugMode)
                    {
                        DebugWrite(e.ToString());
                        DebugWrite("\n" + "Trying to Add:");
                        DebugWrite(fileDaclJObject.ToString());
                        DebugWrite("\n" + "To:");
                        DebugWrite(fileDaclsJObject.ToString());
                    }
                }
            }

            return(fileDaclsJObject);
        }
コード例 #6
0
        private static void Main(string[] args)
        {
            Utility.PrintBanner();
            string sysvolPolDir = "";

            JObject domainGpos = new JObject();

            // Ask the DC for GPO details
            if (args.Length == 0)
            {
                Console.WriteLine("Trying to figure out what AD domain we're working with.");
                string currentDomainString = Domain.GetCurrentDomain().ToString();
                Console.WriteLine("Current AD Domain is: " + currentDomainString);
                sysvolPolDir = @"\\" + currentDomainString + @"\sysvol\" + currentDomainString + @"\Policies\";
                Utility.DebugWrite("SysvolPolDir is " + sysvolPolDir);
                GlobalVar.OnlineChecks = true;
            }

            // or if the user gives a path argument, just look for policies in there
            if (args.Length == 1)
            {
                Console.WriteLine("OK, I trust you know where you're aiming me.");
                sysvolPolDir = args[0];
            }

            Console.WriteLine("We gonna look at the policies in: " + sysvolPolDir);
            if (GlobalVar.OnlineChecks)
            {
                domainGpos = LDAPstuff.GetDomainGpos();
            }

            string[] gpoPaths = Directory.GetDirectories(sysvolPolDir);

            // create a dict to put all our output goodies in.
            Dictionary <string, JObject> grouper2OutputDict = new Dictionary <string, JObject>();

            foreach (var gpoPath in gpoPaths)
            {
                // create a dict to put the stuff we find for this GPO into.
                Dictionary <string, JObject> gpoResultDict = new Dictionary <string, JObject>();
                //

                // Get the UID of the GPO from the file path.
                string[] splitPath = gpoPath.Split(Path.DirectorySeparatorChar);
                string   gpoUid    = splitPath[splitPath.Length - 1];

                // Make a JObject for GPO metadata
                JObject gpoPropsJson = new JObject();
                // If we're online and talking to the domain, just use that data
                if (GlobalVar.OnlineChecks)
                {
                    JToken domainGpo = domainGpos[gpoUid];
                    gpoPropsJson = (JObject)JToken.FromObject(domainGpo);
                }
                // otherwise do what we can with what we have
                else
                {
                    Dictionary <string, string> gpoPropsDict = new Dictionary <string, string>();
                    gpoPropsDict.Add("GPO UID", gpoUid);
                    gpoPropsDict.Add("GPO Path", gpoPath);
                    gpoPropsJson = (JObject)JToken.FromObject(gpoPropsDict);
                }

                // TODO (and put in GPOProps)
                // get the policy owner
                // get whether it's linked and where
                // get whether it's enabled

                // Get the paths for the machine policy and user policy dirs
                string machinePolPath = Path.Combine(gpoPath, "Machine");
                string userPolPath    = Path.Combine(gpoPath, "User");

                // Process Inf and Xml Policy data for machine and user
                JObject machinePolInfResults = ProcessInf(machinePolPath);
                JObject userPolInfResults    = ProcessInf(userPolPath);
                JObject machinePolGppResults = ProcessGpXml(machinePolPath);
                JObject userPolGppResults    = ProcessGpXml(userPolPath);

                // Add all this crap into a dict
                gpoResultDict.Add("GPOProps", gpoPropsJson);
                //gpoResultDict.Add("Machine Policy from GPP XML files", machinePolGppResults);
                //gpoResultDict.Add("User Policy from GPP XML files", userPolGppResults);
                gpoResultDict.Add("Machine Policy from Inf files", machinePolInfResults);
                gpoResultDict.Add("User Policy from Inf files", userPolInfResults);

                // turn dict of data for this gpo into jobj
                JObject gpoResultJson = (JObject)JToken.FromObject(gpoResultDict);

                // put into final jobj
                grouper2OutputDict.Add(gpoPath, gpoResultJson);

                //  TODO
                //  Parse other inf sections:
                //  System Access
                //  Kerberos Policy
                //  Event Audit
                //  Registry Values
                //  Registry Keys
                //  Group Membership
                //  Service General Setting
                //  Parse XML files
                //  Parse ini files
                //  Grep scripts for creds.
                //  File permissions for referenced files.
            }

            // Final output is finally happening finally here:
            Utility.DebugWrite("Final Output:");
            JObject grouper2OutputJson = (JObject)JToken.FromObject(grouper2OutputDict);

            Console.WriteLine("");
            Console.WriteLine(grouper2OutputJson);
            Console.WriteLine("");
            Console.WriteLine("This");
            Console.WriteLine(Utility.CanIWrite("C:\\temp\\thing.txt").ToString());
            // wait for 'anykey'
            Console.ReadKey();
        }
コード例 #7
0
        static void Main(string[] args)
        {
            Utility.PrintBanner();
            JObject JSonData     = JankyDB.Instance;
            JObject JSonData2    = JankyDB.Instance;
            string  SysvolPolDir = "";

            JObject DomainGPOs = new JObject();

            // Ask the DC for GPO details
            if (args.Length == 0)
            {
                Console.WriteLine("Trying to figure out what AD domain we're workin with.");
                Domain CurrentDomain       = Domain.GetCurrentDomain();
                string CurrentDomainString = CurrentDomain.ToString();
                Console.WriteLine("Current AD Domain is: " + CurrentDomainString);
                SysvolPolDir = @"\\" + CurrentDomainString + @"\sysvol\" + CurrentDomainString + @"\Policies\";
                Utility.DebugWrite("SysvolPolDir is " + SysvolPolDir);
                GlobalVar.OnlineChecks = true;
            }
            if (args.Length == 1)
            {
                Console.WriteLine("OK, I trust you know where you're aiming me.");
                SysvolPolDir = args[0];
            }

            Console.WriteLine("We gonna look at the policies in: " + SysvolPolDir);
            if (GlobalVar.OnlineChecks)
            {
                DomainGPOs = LDAPstuff.GetDomainGPOs();
            }

            string[] GPOPaths = Directory.GetDirectories(SysvolPolDir);

            // create a dict to put all our output goodies in.
            Dictionary <string, JObject> Grouper2OutputDict = new Dictionary <string, JObject>();

            foreach (string GPOPath in GPOPaths)
            {
                // create a dict to put the stuff we find for this GPO into.
                Dictionary <string, JObject> GPOResultDict = new Dictionary <string, JObject>();
                Dictionary <string, string>  GPOPropsDict  = new Dictionary <string, string>();

                // Get the UID of the GPO from the file path.
                char     DirSeparator = Path.DirectorySeparatorChar;
                char[]   SplitChars   = new char[] { DirSeparator };
                string[] SplitPath    = GPOPath.Split(SplitChars);
                string   GPOUID       = SplitPath[(SplitPath.Length - 1)];

                // Set some properties of the GPO we're looking at in our output file.
                GPOPropsDict.Add("GPO UID", GPOUID);
                GPOPropsDict.Add("GPO Path", GPOPath);
                if (GlobalVar.OnlineChecks)
                {
                    JToken DomainGPO = DomainGPOs[GPOUID];
                    GPOPropsDict.Add("Display Name", DomainGPO["DisplayName"].ToString());
                    GPOPropsDict.Add("Distinguished Name", DomainGPO["DistinguishedName"].ToString());
                    GPOPropsDict.Add("GPO SDDL", DomainGPO["SDDL"].ToString());
                }

                // TODO (and put in GPOProps)
                // look up the friendly name of the policy
                // get the policy ACLs
                // get the policy owner
                // get whether it's linked and where
                // get whether it's enabled

                // start processing files
                string[] MachinePolPathArray = { GPOPath, "Machine" };
                string[] UserPolPathArray    = { GPOPath, "User" };
                string   MachinePolPath      = Path.Combine(MachinePolPathArray);
                string   UserPolPath         = Path.Combine(UserPolPathArray);

                JObject MachinePolInfResults = ProcessInf(MachinePolPath);
                JObject UserPolInfResults    = ProcessInf(UserPolPath);
                JObject MachinePolGPPResults = ProcessGPXml(MachinePolPath);
                JObject UserPolGPPResults    = ProcessGPXml(UserPolPath);

                JObject GPOPropsJson = (JObject)JToken.FromObject(GPOPropsDict);

                GPOResultDict.Add("GPOProps", GPOPropsJson);
                GPOResultDict.Add("Machine Policy from GPP XML files", MachinePolGPPResults);
                GPOResultDict.Add("User Policy from GPP XML files", UserPolGPPResults);
                GPOResultDict.Add("Machine Policy from Inf files", MachinePolInfResults);
                GPOResultDict.Add("User Policy from Inf files", MachinePolInfResults);

                JObject GPOResultJson = (JObject)JToken.FromObject(GPOResultDict);

                Grouper2OutputDict.Add(GPOPath, GPOResultJson);

                //  TODO
                //  Parse other inf sections:
                //  System Access
                //  Kerberos Policy
                //  Event Audit
                //  Registry Values
                //  Registry Keys
                //  Group Membership
                //  Service General Setting
                //  Parse XML files
                //  Parse ini files
                //  Grep scripts for creds.
                // File permissions for referenced files.
            }

            // Final output is finally happening here:
            Utility.DebugWrite("Final Output:");
            JObject Grouper2OutputJson = (JObject)JToken.FromObject(Grouper2OutputDict);

            Console.WriteLine(Grouper2OutputJson.ToString());
            Console.ReadKey();
        }
コード例 #8
0
        private static void Main(string[] args)
        {
            Utility.PrintBanner();

            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();
            SwitchArgument         debugArg            = new SwitchArgument('d', "debug", "Enables debug mode. Will also show you the names of any categories of policies that Grouper saw but didn't have any means of processing. I eagerly await your pull request.", false);
            SwitchArgument         offlineArg          = new SwitchArgument('o', "offline", "Disables checks that require LDAP comms with a DC or SMB comms with file shares found in policy settings. Requires that you define a value for --sysvol.", false);
            ValueArgument <string> sysvolArg           = new ValueArgument <string>('s', "sysvol", "Set the path to a domain SYSVOL directory.");
            ValueArgument <int>    intlevArg           = new ValueArgument <int>('i', "interestlevel", "The minimum interest level to display. i.e. findings with an interest level lower than x will not be seen in output. Defaults to 1, i.e. show everything except some extremely dull defaults. If you want to see those too, do -i 0.");

            //ValueArgument<string> domainArg = new ValueArgument<string>('d', "domain", "The domain to connect to. If not specified, connects to current user context domain.");
            //ValueArgument<string> usernameArg = new ValueArgument<string>('u', "username", "Username to authenticate as. SMB permissions checks will be run from this user's perspective.");
            //ValueArgument<string> passwordArg = new ValueArgument<string>('p', "password", "Password to use for authentication.");
            //parser.Arguments.Add(domainArg);
            //parser.Arguments.Add(usernameArg);
            //parser.Arguments.Add(passwordArg);
            parser.Arguments.Add(debugArg);
            parser.Arguments.Add(intlevArg);
            parser.Arguments.Add(sysvolArg);
            parser.Arguments.Add(offlineArg);

            // set a couple of defaults
            string sysvolPolDir = "";

            GlobalVar.OnlineChecks = true;

            try
            {
                parser.ParseCommandLine(args);
                //parser.ShowParsedArguments();
                if (debugArg.Parsed && debugArg.Value)
                {
                    GlobalVar.DebugMode = true;
                }
                if (offlineArg.Parsed && offlineArg.Value && sysvolArg.Parsed)
                {
                    // args config for valid offline run.
                    GlobalVar.OnlineChecks = false;
                    sysvolPolDir           = sysvolArg.Value;
                }
                if (offlineArg.Parsed && offlineArg.Value && !sysvolArg.Parsed)
                {
                    // handle someone trying to run in offline mode without giving a value for sysvol
                    Console.WriteLine("Offline mode requires you to provide a value for -s, the path where Grouper2 can find the domain SYSVOL share, or a copy of it at least.");
                    Environment.Exit(1);
                }
                if (intlevArg.Parsed)
                {
                    // handle interest level parsing
                    Console.WriteLine("Roger. Everything with an Interest Level lower than " + intlevArg.Value.ToString() + " is getting thrown on the floor.");
                    GlobalVar.IntLevelToShow = intlevArg.Value;
                }
                else
                {
                    GlobalVar.IntLevelToShow = 1;
                }

                if (sysvolArg.Parsed)
                {
                    sysvolPolDir = sysvolArg.Value;
                }
                //if (domainArg.Parsed || usernameArg.Parsed || passwordArg.Parsed)
                //{
                //    Console.WriteLine("I haven't set up anything to handle the domain/password stuff yet, so it won't work");
                //    Environment.Exit(1);
                //}
            }
            catch (CommandLineException e)
            {
                Console.WriteLine(e.Message);
            }

            JObject domainGpos = new JObject();

            // Ask the DC for GPO details
            if (GlobalVar.OnlineChecks)
            {
                Console.WriteLine("Trying to figure out what AD domain we're working with.");
                string currentDomainString = Domain.GetCurrentDomain().ToString();
                Console.WriteLine("Current AD Domain is: " + currentDomainString);
                if (sysvolPolDir == "")
                {
                    sysvolPolDir = @"\\" + currentDomainString + @"\sysvol\" + currentDomainString + @"\Policies\";
                }
            }

            Console.WriteLine("Targeting SYSVOL at: " + sysvolPolDir);

            // if we're online, get a bunch of metadata about the GPOs via LDAP
            if (GlobalVar.OnlineChecks)
            {
                domainGpos = LDAPstuff.GetDomainGpos();
            }

            string[] gpoPaths = new string[0];
            try
            {
                gpoPaths = Directory.GetDirectories(sysvolPolDir);
            }
            catch
            {
                Console.WriteLine("Sysvol path is broken. You should fix it.");
                Environment.Exit(1);
            }

            // create a JObject to put all our output goodies in.
            JObject grouper2Output = new JObject();

            // so for each uid directory (including ones with that dumb broken domain replication condition)
            // we're going to gather up all our goodies and put them into that dict we just created.
            foreach (var gpoPath in gpoPaths)
            {
                // create a dict to put the stuff we find for this GPO into.
                JObject gpoResult = new JObject();
                // Get the UID of the GPO from the file path.
                string[] splitPath = gpoPath.Split(Path.DirectorySeparatorChar);
                string   gpoUid    = splitPath[splitPath.Length - 1];

                // Make a JObject for GPO metadata
                JObject gpoProps = new JObject();
                // If we're online and talking to the domain, just use that data
                if (GlobalVar.OnlineChecks)
                {
                    JToken domainGpo = domainGpos[gpoUid];
                    gpoProps = (JObject)JToken.FromObject(domainGpo);
                }
                // otherwise do what we can with what we have
                else
                {
                    gpoProps = new JObject()
                    {
                        { "gpoUID", gpoUid },
                        { "gpoPath", gpoPath }
                    };
                }

                // TODO (and put in GPOProps)
                // get the policy owner
                // get whether it's linked and where
                // get whether it's enabled

                // Add all this crap into a dict, if we found anything of interest.
                gpoResult.Add("GPOProps", gpoProps);
                // turn dict of data for this gpo into jobj
                JObject gpoResultJson = (JObject)JToken.FromObject(gpoResult);

                // if I were smarter I would have done this shit with the machine and user dirs inside the Process methods instead of calling each one twice out here.
                // @liamosaur you reckon you can see how to clean it up after the fact?
                // Get the paths for the machine policy and user policy dirs
                string machinePolPath = Path.Combine(gpoPath, "Machine");
                string userPolPath    = Path.Combine(gpoPath, "User");

                // Process Inf and Xml Policy data for machine and user
                JArray machinePolInfResults    = ProcessInf(machinePolPath);
                JArray userPolInfResults       = ProcessInf(userPolPath);
                JArray machinePolGppResults    = ProcessGpXml(machinePolPath);
                JArray userPolGppResults       = ProcessGpXml(userPolPath);
                JArray machinePolScriptResults = ProcessScriptsIni(machinePolPath);
                JArray userPolScriptResults    = ProcessScriptsIni(userPolPath);

                // add all our findings to a JArray in what seems a very inefficient manner.
                JArray userFindings    = new JArray();
                JArray machineFindings = new JArray();
                if (machinePolGppResults != null && machinePolGppResults.HasValues)
                {
                    foreach (JObject finding in machinePolGppResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolGppResults != null && userPolGppResults.HasValues)
                {
                    foreach (JObject finding in userPolGppResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                if (machinePolGppResults != null && machinePolInfResults.HasValues)
                {
                    foreach (JObject finding in machinePolInfResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolInfResults != null && userPolInfResults.HasValues)
                {
                    foreach (JObject finding in userPolInfResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                if (machinePolScriptResults != null && machinePolScriptResults.HasValues)
                {
                    foreach (JObject finding in machinePolScriptResults)
                    {
                        machineFindings.Add(finding);
                    }
                }
                if (userPolScriptResults != null && userPolScriptResults.HasValues)
                {
                    foreach (JObject finding in userPolScriptResults)
                    {
                        userFindings.Add(finding);
                    }
                }
                // if there are any Findings, add it to the final output.
                if (userFindings.HasValues)
                {
                    JProperty userFindingsJProp = new JProperty("Findings in User Policy", userFindings);
                    gpoResultJson.Add(userFindingsJProp);
                }

                if (machineFindings.HasValues)
                {
                    JProperty machineFindingsJProp = new JProperty("Findings in Machine Policy", machineFindings);
                    gpoResultJson.Add(machineFindingsJProp);
                }

                // put into final output
                if (userFindings.HasValues || machineFindings.HasValues)
                {
                    grouper2Output.Add(gpoPath, gpoResultJson);
                }
            }

            // Final output is finally happening finally here:
            Console.WriteLine("RESULT!");
            Console.WriteLine("");
            Console.WriteLine(grouper2Output);
            Console.WriteLine("");
            // wait for 'anykey'
            Console.ReadKey();
        }