/// <summary>
        /// On linux we check the central trusted root store (a folder), which has symlinks to actual cert locations scattered across the db
        /// We list all the certificates and then create a new X509Certificate2 object for each by filename.
        /// </summary>
        public void ExecuteLinux()
        {
            try
            {
                if (ExternalCommandRunner.RunExternalCommand("ls", "/etc/ssl/certs -A", out string result, out string _) == 0)
                {
                    foreach (var _line in result.Split('\n'))
                    {
                        Log.Debug("{0}", _line);
                        try
                        {
                            using X509Certificate2 certificate = new X509Certificate2("/etc/ssl/certs/" + _line);

                            var obj = new CertificateObject(
                                StoreLocation: StoreLocation.LocalMachine.ToString(),
                                StoreName: StoreName.Root.ToString(),
                                Certificate: new SerializableCertificate(certificate))
                            {
                                Pkcs7 = Convert.ToBase64String(certificate.Export(X509ContentType.Cert))
                            };
                            Results.Enqueue(obj);
                        }
                        catch (Exception e)
                        {
                            Log.Debug("{0} {1} Issue creating certificate based on /etc/ssl/certs/{2}", e.GetType().ToString(), e.Message, _line);
                            Log.Debug("{0}", e.StackTrace);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Failed to dump certificates from 'ls /etc/ssl/certs -A'.");
            }
        }
Пример #2
0
        /// <summary>
        /// On linux we check the central trusted root store (a folder), which has symlinks to actual cert locations scattered across the db
        /// We list all the certificates and then create a new X509Certificate2 object for each by filename.
        /// </summary>
        public void ExecuteLinux()
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("ls", new string[] { "/etc/ssl/certs", "-A" });

                foreach (var _line in result.Split('\n'))
                {
                    Log.Debug("{0}", _line);
                    try
                    {
                        using X509Certificate2 certificate = new X509Certificate2("/etc/ssl/certs/" + _line);

                        var obj = new CertificateObject(
                            StoreLocation: StoreLocation.LocalMachine.ToString(),
                            StoreName: StoreName.Root.ToString(),
                            Certificate: new SerializableCertificate(certificate),
                            Pkcs7: certificate.Export(X509ContentType.Cert).ToString());

                        DatabaseManager.Write(obj, RunId);
                    }
                    catch (Exception e)
                    {
                        Log.Debug("{0} {1} Issue creating certificate based on /etc/ssl/certs/{2}", e.GetType().ToString(), e.Message, _line);
                        Log.Debug("{0}", e.StackTrace);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Failed to dump certificates from 'ls /etc/ssl/certs -A'.");
            }
        }
        public void TestServiceCollectorWindows()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                var FirstRunId  = "TestServiceCollector-1";
                var SecondRunId = "TestServiceCollector-2";

                var fwc = new ServiceCollector(FirstRunId);
                fwc.Execute();

                // Create a service - This won't throw an exception, but it won't work if you are not an Admin.
                var serviceName = "AsaDemoService";
                var exeName     = "AsaDemoService.exe";
                var cmd         = string.Format("create {0} binPath=\"{1}\"", serviceName, exeName);
                ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);

                fwc = new ServiceCollector(SecondRunId);
                fwc.Execute();

                // Clean up
                cmd = string.Format("delete {0}", serviceName);
                ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);

                BaseCompare bc = new BaseCompare();
                if (!bc.TryCompare(FirstRunId, SecondRunId))
                {
                    Assert.Fail();
                }

                var results = bc.Results;

                Assert.IsTrue(results.ContainsKey("SERVICE_CREATED"));
                Assert.IsTrue(results["SERVICE_CREATED"].Where(x => x.Identity.Contains("AsaDemoService")).Count() > 0);
            }
        }
        public void TestUserCollectorWindows()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.IsTrue(AsaHelpers.IsAdmin());
                var FirstRunId  = "TestUserCollector-1";
                var SecondRunId = "TestUserCollector-2";

                var fwc = new UserAccountCollector(FirstRunId);
                fwc.Execute();

                var user     = System.Guid.NewGuid().ToString().Substring(0, 10);
                var password = System.Guid.NewGuid().ToString().Substring(0, 10);
                var cmd      = string.Format("user /add {0} {1}", user, password);
                ExternalCommandRunner.RunExternalCommand("net", cmd);

                var serviceName = System.Guid.NewGuid();

                fwc = new UserAccountCollector(SecondRunId);
                fwc.Execute();

                cmd = string.Format("user /delete {0}", user);
                ExternalCommandRunner.RunExternalCommand("net", cmd);

                BaseCompare bc = new BaseCompare();
                if (!bc.TryCompare(FirstRunId, SecondRunId))
                {
                    Assert.Fail();
                }

                var results = bc.Results;
                Assert.IsTrue(results.ContainsKey("USER_CREATED"));
                Assert.IsTrue(results["USER_CREATED"].Where(x => x.Identity.Contains(user)).Count() > 0);
            }
        }
Пример #5
0
        public void TestFirewallCollectorLinux()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Setup();
                var FirstRunId  = "TestFirewallCollector-1";
                var SecondRunId = "TestFirewallCollector-2";

                var fwc = new FirewallCollector(FirstRunId);
                fwc.Execute();

                var result = ExternalCommandRunner.RunExternalCommand("iptables", "-A INPUT -p tcp --dport 19999 -j DROP");

                fwc = new FirewallCollector(SecondRunId);
                fwc.Execute();

                result = ExternalCommandRunner.RunExternalCommand("iptables", "-D INPUT -p tcp --dport 19999 -j DROP");

                BaseCompare bc = new BaseCompare();
                if (!bc.TryCompare(FirstRunId, SecondRunId))
                {
                    Assert.Fail();
                }

                var results = bc.Results;

                Assert.IsTrue(results.ContainsKey("FIREWALL_CREATED"));
                Assert.IsTrue(results["FIREWALL_CREATED"].Where(x => x.Identity.Contains("9999")).Count() > 0);

                TearDown();
            }
        }
Пример #6
0
        /// <summary>
        /// Executes the OpenPortCollector on OS X. Calls out to the `lsof`
        /// command and parses the output, sending the output to the database.
        /// </summary>
        private void ExecuteOsX()
        {
            try
            {
                string result = ExternalCommandRunner.RunExternalCommand("lsof", "-Pn -i4 -i6");

                foreach (var _line in result.Split('\n'))
                {
                    var line = _line.ToUpperInvariant();
                    if (!line.Contains("LISTEN"))
                    {
                        continue; // Skip any lines which aren't open listeners
                    }
                    var parts = Regex.Split(line, @"\s+");
                    if (parts.Length <= 9)
                    {
                        continue; // Not long enough
                    }

                    var addressMatches = Regex.Match(parts[8], @"^(.*):(\d+)$");
                    if (addressMatches.Success)
                    {
                        var address = addressMatches.Groups[1].ToString();
                        var port    = addressMatches.Groups[2].ToString();
                        if (int.TryParse(port, out int portInt))
                        {
                            var transport = parts[7].ToUpperInvariant().Equals("TCP") ? TRANSPORT.TCP : parts[7].ToUpperInvariant().Equals("TCP") ? TRANSPORT.UDP : TRANSPORT.UNKNOWN;
                            var family    = ADDRESS_FAMILY.Unknown;

                            switch (parts[4])
                            {
                            case "IPv4":
                                family = ADDRESS_FAMILY.InterNetwork;
                                break;

                            case "IPv6":
                                family = ADDRESS_FAMILY.InterNetworkV6;
                                break;

                            default:
                                family = ADDRESS_FAMILY.Unknown;
                                break;
                            }

                            var obj = new OpenPortObject(portInt, transport, family)
                            {
                                Address     = address,
                                ProcessName = parts[0]
                            };

                            Results.Push(obj);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, Strings.Get("Err_Lsof"));
            }
        }
Пример #7
0
        public void TestUserCollectorWindows()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.IsTrue(AsaHelpers.IsAdmin());
                var user     = System.Guid.NewGuid().ToString().Substring(0, 10);
                var password = "******" + CryptoHelpers.GetRandomString(13);

                var cmd = string.Format("user /add {0} {1}", user, password);
                ExternalCommandRunner.RunExternalCommand("net", cmd);

                var uac = new UserAccountCollector();
                uac.TryExecute();

                Assert.IsTrue(uac.Results.Any(x => x is UserAccountObject y && y.Name.Equals(user)));

                ConcurrentStack <CollectObject> results = new ConcurrentStack <CollectObject>();
                uac = new UserAccountCollector(changeHandler: x => results.Push(x));
                uac.TryExecute();

                Assert.IsTrue(results.Any(x => x is UserAccountObject y && y.Name.Equals(user)));

                cmd = string.Format("user /delete {0}", user);
                ExternalCommandRunner.RunExternalCommand("net", cmd);
            }
        }
Пример #8
0
        public void TestServiceCollectorWindows()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                // Create a service - This won't throw an exception, but it won't work if you are not an Admin.
                var serviceName = "AsaDemoService";
                var exeName     = "AsaDemoService.exe";
                var cmd         = string.Format("create {0} binPath=\"{1}\"", serviceName, exeName);
                ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);

                var sc = new ServiceCollector(new CollectCommandOptions());
                sc.TryExecute();

                Assert.IsTrue(sc.Results.Any(x => x is ServiceObject RO && RO.Name.Equals(serviceName)));

                ConcurrentStack <CollectObject> results = new ConcurrentStack <CollectObject>();
                sc = new ServiceCollector(changeHandler: x => results.Push(x));
                sc.TryExecute();

                Assert.IsTrue(results.Any(x => x is ServiceObject RO && RO.Name.Equals(serviceName)));

                // Clean up
                cmd = string.Format("delete {0}", serviceName);
                ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);
            }
        }
Пример #9
0
        public void TestFirewallCollectorOSX()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                Setup();
                var FirstRunId  = "TestFirewallCollector-1";
                var SecondRunId = "TestFirewallCollector-2";

                var fwc = new FirewallCollector(FirstRunId);
                fwc.Execute();

                _ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--add", "/bin/bash");

                fwc = new FirewallCollector(SecondRunId);
                fwc.Execute();

                _ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--remove", "/bin/bash");

                BaseCompare bc = new BaseCompare();
                if (!bc.TryCompare(FirstRunId, SecondRunId))
                {
                    Assert.Fail();
                }

                var results = bc.Results;

                Assert.IsTrue(results.ContainsKey("FIREWALL_CREATED"));
                Assert.IsTrue(results["FIREWALL_CREATED"].Where(x => x.Identity.Contains("/bin/bash")).Count() > 0);

                TearDown();
            }
        }
        /// <summary>
        /// Collect event logs on macOS using the 'log' utility
        /// </summary>
        public void ExecuteMacOs()
        {
            _ = DatabaseManager.Transaction;

            var outputPath = Path.Combine(Directory.GetCurrentDirectory(), "events");
            var file       = (GatherVerboseLogs)? ExternalCommandRunner.RunExternalCommand("log", "show") : ExternalCommandRunner.RunExternalCommand("log", "show --predicate \"messageType == 16 || messageType == 17\"");

            // New log entries start with a timestamp like so:
            // 2019-09-25 20:38:53.784594-0700 0xdbf47    Error       0x0                  0      0    kernel: (Sandbox) Sandbox: mdworker(15726) deny(1) mach-lookup com.apple.security.syspolicy
            Regex LogHeader = new Regex("^([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]).*?0x[0-9a-f]*[\\s]*([A-Za-z]*)[\\s]*0x[0-9a-f][\\s]*[0-9]*[\\s]*([0-9]*)[\\s]*(.*?):(.*)");


            List <string> data         = null;
            string        previousLine = null;

            foreach (var line in file.Split('\n'))
            {
                if (LogHeader.IsMatch(line))
                {
                    if (previousLine != null)
                    {
                        var obj = new EventLogObject()
                        {
                            Data      = (data.Count > 0) ? data : null,
                            Event     = previousLine,
                            Level     = LogHeader.Matches(previousLine).Single().Groups[2].Value,
                            Summary   = string.Format("{0}:{1}", LogHeader.Matches(previousLine).Single().Groups[4].Captures[0].Value, LogHeader.Matches(previousLine).Single().Groups[5].Captures[0].Value),
                            Timestamp = LogHeader.Matches(previousLine).Single().Groups[1].Captures[0].Value,
                            Source    = LogHeader.Matches(previousLine).Single().Groups[4].Captures[0].Value
                        };
                        DatabaseManager.Write(obj, runId);
                    }
                    previousLine = line;
                    data         = new List <string>();
                }
                else
                {
                    if (previousLine != null)
                    {
                        data.Add(line);
                    }
                }
            }
            if (previousLine != null)
            {
                var obj = new EventLogObject()
                {
                    Data      = (data.Count > 0) ? data:null,
                    Event     = previousLine,
                    Level     = LogHeader.Matches(previousLine).Single().Groups[2].Value,
                    Summary   = string.Format("{0}:{1}", LogHeader.Matches(previousLine).Single().Groups[4].Captures[0].Value, LogHeader.Matches(previousLine).Single().Groups[5].Captures[0].Value),
                    Timestamp = LogHeader.Matches(previousLine).Single().Groups[1].Captures[0].Value,
                    Source    = LogHeader.Matches(previousLine).Single().Groups[4].Captures[0].Value
                };
                DatabaseManager.Write(obj, runId);
            }
            DatabaseManager.Commit();
        }
        public override void Stop()
        {
            // restore the old auditpolicy
            ExternalCommandRunner.RunExternalCommand("auditpol", String.Format("/restore /file:{0}", tmpFileName));

            //delete temporary file
            ExternalCommandRunner.RunExternalCommand("del", tmpFileName);

            log.EnableRaisingEvents = false;
        }
Пример #12
0
        public void TestFirewallCollectorOSX()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                _ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--add /bin/bash");

                var fwc = new FirewallCollector();
                fwc.TryExecute();
                _ = ExternalCommandRunner.RunExternalCommand("/usr/libexec/ApplicationFirewall/socketfilterfw", "--remove /bin/bash");
                Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.ApplicationName == "/bin/bash"));
            }
        }
Пример #13
0
        /// <summary>
        /// Executes the OpenPortCollector on OS X. Calls out to the `lsof`
        /// command and parses the output, sending the output to the database.
        /// The 'ss' command used on Linux isn't available on OS X.
        /// </summary>
        private void ExecuteOsX()
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("sudo", "lsof -Pn -i4 -i6");

                foreach (var _line in result.Split('\n'))
                {
                    var line = _line.ToLower();
                    if (!line.Contains("listen"))
                    {
                        continue; // Skip any lines which aren't open listeners
                    }
                    var parts = Regex.Split(line, @"\s+");
                    if (parts.Length <= 9)
                    {
                        continue;       // Not long enough
                    }
                    string address = null;
                    string port    = null;

                    var addressMatches = Regex.Match(parts[8], @"^(.*):(\d+)$");
                    if (addressMatches.Success)
                    {
                        address = addressMatches.Groups[1].ToString();
                        port    = addressMatches.Groups[2].ToString();

                        var obj = new OpenPortObject()
                        {
                            // Assuming family means IPv6 vs IPv4
                            family      = parts[4],
                            address     = address,
                            port        = port,
                            type        = parts[7],
                            processName = parts[0]
                        };
                        try
                        {
                            DatabaseManager.Write(obj, this.runId);
                        }
                        catch (Exception e)
                        {
                            Logger.DebugException(e);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(Strings.Get("Err_Lsof"));
                Logger.DebugException(e);
            }
        }
Пример #14
0
        public override void StartRun()
        {
            // backup the current auditpolicy
            ExternalCommandRunner.RunExternalCommand("auditpol", $"/backup /file:{tmpFileName}");

            // start listening to the event log
            log.EntryWritten       += new EntryWrittenEventHandler(MyOnEntryWritten);
            log.EnableRaisingEvents = true;

            // Enable auditing for registry events GUID for Registry subcategory of audit policy https://msdn.microsoft.com/en-us/library/dd973928.aspx
            ExternalCommandRunner.RunExternalCommand("auditpol", "/set /subcategory:{0CCE921E-69AE-11D9-BED3-505054503030} /success:enable /failure:enable");
        }
Пример #15
0
        public void TestFirewallCollectorLinux()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                var result = ExternalCommandRunner.RunExternalCommand("iptables", "-A INPUT -p tcp --dport 19999 -j DROP");

                var fwc = new FirewallCollector();
                fwc.TryExecute();

                Assert.IsTrue(fwc.Results.Any(x => x is FirewallObject FWO && FWO.LocalPorts.Contains("19999")));

                result = ExternalCommandRunner.RunExternalCommand("iptables", "-D INPUT -p tcp --dport 19999 -j DROP");
            }
        }
        /// <summary>
        /// Executes the OpenPortCollector on Linux. Calls out to the `ss`
        /// command and parses the output, sending the output to the database.
        /// </summary>
        internal void ExecuteLinux(CancellationToken cancellationToken)
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("ss", "-ln");

                foreach (var _line in result.Split('\n'))
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var line = _line;
                    line = line.ToUpperInvariant();
                    if (!line.Contains("LISTEN"))
                    {
                        continue;
                    }
                    var parts = Regex.Split(line, @"\s+");
                    if (parts.Length < 5)
                    {
                        continue;       // Not long enough, must be an error
                    }

                    var addressMatches = Regex.Match(parts[4], @"^(.*):(\d+)$");
                    if (addressMatches.Success)
                    {
                        var address = addressMatches.Groups[1].ToString();
                        var port    = addressMatches.Groups[2].ToString();
                        if (int.TryParse(port, out int portInt))
                        {
                            var transport = parts[0].ToUpperInvariant().Equals("TCP") ? TRANSPORT.TCP : TRANSPORT.UDP;
                            var family    = address.Contains('.') ? ADDRESS_FAMILY.InterNetwork : address.Contains(':') ? ADDRESS_FAMILY.InterNetworkV6 : ADDRESS_FAMILY.Unknown;
                            var obj       = new OpenPortObject(portInt, transport, family)
                            {
                                Address = address
                            };
                            HandleChange(obj);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warning(Strings.Get("Err_Iproute2"));
                Log.Debug(e, "");
            }
        }
Пример #17
0
        private long SizeOnDisk(FileInfo path)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                try
                {
                    uint clusterSize = 0;
                    var  root        = path.Directory.Root.FullName;
                    if (!ClusterSizes.ContainsKey(root))
                    {
                        ClusterSizes[root] = 0;
                        NativeMethods.GetDiskFreeSpace(root, out uint lpSectorsPerCluster, out uint lpBytesPerSector, out _, out _);
                        ClusterSizes[root] = lpSectorsPerCluster * lpBytesPerSector;
                    }
                    clusterSize = ClusterSizes[root];

                    if (clusterSize > 0)
                    {
                        uint lowSize = NativeMethods.GetCompressedFileSizeW(path.FullName, out uint highSize);
                        long size    = (long)highSize << 32 | lowSize;
                        return(((size + clusterSize - 1) / clusterSize) * clusterSize);
                    }
                }
                catch (Exception e)
                {
                    Log.Debug("Failed to GetDiskFreeSpace for {0} ({1}:{2})", path.FullName, e.GetType(), e.Message);
                }
                return(-1);
            }
            else
            {
                if (sizesOnDisk.ContainsKey(path.FullName))
                {
                    return(sizesOnDisk[path.FullName]);
                }
                var exitCode = ExternalCommandRunner.RunExternalCommand("du", path.FullName, out string StdOut, out string StdErr);
                if (exitCode == 0 && long.TryParse(StdOut.Split('\t')[0], out long result))
                {
                    return(result);
                }
                else
                {
                    return(-1);
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Executes the OpenPortCollector on OS X. Calls out to the `lsof`
        /// command and parses the output, sending the output to the database.
        /// The 'ss' command used on Linux isn't available on OS X.
        /// </summary>
        private void ExecuteOsX()
        {
            try
            {
                string result = ExternalCommandRunner.RunExternalCommand("lsof", "-Pn -i4 -i6");

                foreach (var _line in result.Split('\n'))
                {
                    var line = _line.ToUpperInvariant();
                    if (!line.Contains("LISTEN"))
                    {
                        continue; // Skip any lines which aren't open listeners
                    }
                    var parts = Regex.Split(line, @"\s+");
                    if (parts.Length <= 9)
                    {
                        continue; // Not long enough
                    }

                    var addressMatches = Regex.Match(parts[8], @"^(.*):(\d+)$");
                    if (addressMatches.Success)
                    {
                        var address = addressMatches.Groups[1].ToString();
                        var port    = addressMatches.Groups[2].ToString();
                        if (int.TryParse(port, out int portInt))
                        {
                            var obj = new OpenPortObject(portInt)
                            {
                                // Assuming family means IPv6 vs IPv4
                                Family      = parts[4],
                                Address     = address,
                                Type        = parts[7],
                                ProcessName = parts[0]
                            };

                            DatabaseManager.Write(obj, RunId);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, Strings.Get("Err_Lsof"));
            }
        }
Пример #19
0
        /// <summary>
        /// Executes the OpenPortCollector on Linux. Calls out to the `ss`
        /// command and parses the output, sending the output to the database.
        /// </summary>
        private void ExecuteLinux()
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("ss", "-ln");

                foreach (var _line in result.Split('\n'))
                {
                    var line = _line;
                    line = line.ToUpperInvariant();
                    if (!line.Contains("LISTEN"))
                    {
                        continue;
                    }
                    var parts = Regex.Split(line, @"\s+");
                    if (parts.Length < 5)
                    {
                        continue;       // Not long enough, must be an error
                    }
                    string address = null;
                    string port    = null;

                    var addressMatches = Regex.Match(parts[4], @"^(.*):(\d+)$");
                    if (addressMatches.Success)
                    {
                        address = addressMatches.Groups[1].ToString();
                        port    = addressMatches.Groups[2].ToString();

                        var obj = new OpenPortObject()
                        {
                            Family  = parts[0],//@TODO: Determine IPV4 vs IPv6 via looking at the address
                            Address = address,
                            Port    = port,
                            Type    = parts[0]
                        };
                        DatabaseManager.Write(obj, this.RunId);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Warning(Strings.Get("Err_Iproute2"));
                Log.Debug(e, "");
            }
        }
        /// <summary>
        ///     Uses launchctl
        /// </summary>
        internal void ExecuteMacOs(CancellationToken cancellationToken)
        {
            // Get the user processes run "launchtl dumpstate" for the super detailed view However, dumpstate
            // is difficult to parse
            Dictionary <string, ServiceObject> outDict = new Dictionary <string, ServiceObject>();

            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("launchctl", "list");
                foreach (var _line in result.Split('\n'))
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    // Lines are formatted like this:
                    // PID   Exit  Name
                    //1015    0   com.apple.appstoreagent
                    var _fields = _line.Split('\t');
                    if (_fields.Length < 3 || _fields[0].Contains("PID"))
                    {
                        continue;
                    }
                    var obj = new ServiceObject(_fields[2])
                    {
                        DisplayName = _fields[2],
                        // If we have a current PID then it is running.
                        State = (_fields[0].Equals("-")) ? "Stopped" : "Running"
                    };
                    if (!outDict.ContainsKey(obj.Identity))
                    {
                        HandleChange(obj);
                        outDict.Add(obj.Identity, obj);
                    }
                }
            }
            catch (ExternalException)
            {
                Log.Error("Error executing {0}", "launchctl list");
            }
        }
        /// <summary>
        /// On macos we use the keychain and export the certificates as .pem. However, on macos
        /// Certificate2 doesn't support loading from a pem. So first we need pkcs12s instead, we
        /// convert using openssl, which requires we set a password we import the pkcs12 with all
        /// our certs, delete the temp files and then iterate over it the certs
        /// </summary>
        internal void ExecuteMacOs(CancellationToken cancellationToken)
        {
            try
            {
                if (ExternalCommandRunner.RunExternalCommand("security", "find-certificate -ap /System/Library/Keychains/SystemRootCertificates.keychain", out string result, out string _) == 0)
                {
                    string tmpPath = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pem");
                    string pkPath  = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pk12");

                    File.WriteAllText(tmpPath, result);
                    if (ExternalCommandRunner.RunExternalCommand("openssl", $"pkcs12 -export -nokeys -out {pkPath} -passout pass:pass -in {tmpPath}", out string _, out string _) == 0)
                    {
                        X509Certificate2Collection xcert = new X509Certificate2Collection();
                        xcert.Import(pkPath, "pass", X509KeyStorageFlags.DefaultKeySet); //lgtm [cs/hardcoded-credentials]

                        File.Delete(tmpPath);
                        File.Delete(pkPath);

                        var X509Certificate2Enumerator = xcert.GetEnumerator();

                        while (X509Certificate2Enumerator.MoveNext())
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            var certificate = X509Certificate2Enumerator.Current;

                            var obj = new CertificateObject(
                                StoreLocation: StoreLocation.LocalMachine.ToString(),
                                StoreName: StoreName.Root.ToString(),
                                Certificate: new SerializableCertificate(certificate));
                            HandleChange(obj);
                        }
                    }
                    else
                    {
                        Log.Debug("Failed to export certificate with OpenSSL."); //DevSkim: ignore DS440000
                    }
                }
Пример #22
0
        public static void Main(string[] args)
        {
            Logger.Setup(true, true);

            try
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    if (!Elevation.IsAdministrator())
                    {
                        Log.Fatal("Must run as administrator.");
                        Log.CloseAndFlush();
                        Environment.Exit(-1);
                    }
                    var user     = System.Guid.NewGuid().ToString().Substring(0, 10);
                    var password = System.Guid.NewGuid().ToString().Substring(0, 10);
                    var cmd      = string.Format("user /add {0} {1}", user, password);
                    ExternalCommandRunner.RunExternalCommand("net", cmd);

                    Log.Information("Created user {0} with password {1}", user, password);

                    var serviceName = System.Guid.NewGuid();
                    var exeName     = "AsaDemoService.exe";

                    cmd = string.Format("create {0} binPath=\"{1}\"", serviceName, exeName);
                    ExternalCommandRunner.RunExternalCommand("sc.exe", cmd);

                    Log.Information("Created service {0} for not-present exe {1}", serviceName, exeName);
                }
                else
                {
                    Log.Fatal("Only supported on Windows.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
        /// <summary>
        /// On macos we use the keychain and export the certificates as .pem.
        /// However, on macos Certificate2 doesn't support loading from a pem.
        /// So first we need pkcs12s instead, we convert using openssl, which requires we set a password
        /// we import the pkcs12 with all our certs, delete the temp files and then iterate over it the certs
        /// </summary>
        public void ExecuteMacOs()
        {
            try
            {
                if (ExternalCommandRunner.RunExternalCommand("security", "find-certificate -ap /System/Library/Keychains/SystemRootCertificates.keychain", out string result, out string _) == 0)
                {
                    string tmpPath = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pem");
                    string pkPath  = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pk12");

                    File.WriteAllText(tmpPath, result);
                    if (ExternalCommandRunner.RunExternalCommand("openssl", $"pkcs12 -export -nokeys -out {pkPath} -passout pass:pass -in {tmpPath}", out string _, out string _) == 0)
                    {
                        X509Certificate2Collection xcert = new X509Certificate2Collection();
                        xcert.Import(pkPath, "pass", X509KeyStorageFlags.DefaultKeySet); //lgtm [cs/hardcoded-credentials]

                        File.Delete(tmpPath);
                        File.Delete(pkPath);

                        var X509Certificate2Enumerator = xcert.GetEnumerator();

                        while (X509Certificate2Enumerator.MoveNext())
                        {
                            var certificate = X509Certificate2Enumerator.Current;

                            var obj = new CertificateObject(
                                StoreLocation: StoreLocation.LocalMachine.ToString(),
                                StoreName: StoreName.Root.ToString(),
                                Certificate: new SerializableCertificate(certificate))
                            {
                                Pkcs7 = Convert.ToBase64String(certificate.Export(X509ContentType.Cert))
                            };
                            DatabaseManager.Write(obj, RunId);
                        }
                    }
                    else
                    {
                        Log.Debug("Failed to export certificate with OpenSSL.");
                    }
                }
Пример #24
0
        /// <summary>
        /// Executes the OpenPortCollector on Linux. Calls out to the `ss`
        /// command and parses the output, sending the output to the database.
        /// </summary>
        private void ExecuteLinux()
        {
            Log.Debug("ExecuteLinux()");

            var result = ExternalCommandRunner.RunExternalCommand("ss", "-ln");

            foreach (var _line in result.Split('\n'))
            {
                var line = _line;
                line = line.ToLower();
                if (!line.Contains("listen"))
                {
                    continue;
                }
                var parts = Regex.Split(line, @"\s+");
                if (parts.Length < 5)
                {
                    continue;       // Not long enough, must be an error
                }
                string address = null;
                string port    = null;

                var addressMatches = Regex.Match(parts[4], @"^(.*):(\d+)$");
                if (addressMatches.Success)
                {
                    address = addressMatches.Groups[1].ToString();
                    port    = addressMatches.Groups[2].ToString();

                    var obj = new OpenPortObject()
                    {
                        family  = parts[0],//@TODO: Determine IPV4 vs IPv6 via looking at the address
                        address = address,
                        port    = port,
                        type    = parts[0]
                    };
                    DatabaseManager.Write(obj, this.runId);
                }
            }
        }
Пример #25
0
        /// <summary>
        /// On macos we use the keychain and export the certificates as .pem.
        /// However, on macos Certificate2 doesn't support loading from a pem.
        /// So first we need pkcs12s instead, we convert using openssl, which requires we set a password
        /// we import the pkcs12 with all our certs, delete the temp files and then iterate over it the certs
        /// </summary>
        public void ExecuteMacOs()
        {
            try
            {
                var    result  = ExternalCommandRunner.RunExternalCommand("security", new string[] { "find-certificate", "-ap", "/System/Library/Keychains/SystemRootCertificates.keychain" });
                string tmpPath = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pem");
                string pkPath  = Path.Combine(Directory.GetCurrentDirectory(), "tmpcert.pk12");

                File.WriteAllText(tmpPath, result);
                _ = ExternalCommandRunner.RunExternalCommand("openssl", new string[] { "pkcs12", "-export", "-nokeys", "-out", pkPath, "-passout pass:pass", "-in", tmpPath });

                X509Certificate2Collection xcert = new X509Certificate2Collection();
                xcert.Import(pkPath, "pass", X509KeyStorageFlags.DefaultKeySet);

                File.Delete(tmpPath);
                File.Delete(pkPath);

                var X509Certificate2Enumerator = xcert.GetEnumerator();

                while (X509Certificate2Enumerator.MoveNext())
                {
                    var obj = new CertificateObject()
                    {
                        StoreLocation         = StoreLocation.LocalMachine.ToString(),
                        StoreName             = StoreName.Root.ToString(),
                        CertificateHashString = X509Certificate2Enumerator.Current.GetCertHashString(),
                        Subject = X509Certificate2Enumerator.Current.Subject,
                        Pkcs12  = X509Certificate2Enumerator.Current.GetRawCertDataString()
                    };
                    DatabaseManager.Write(obj, this.runId);
                }
            }
            catch (Exception e)
            {
                Log.Error("Failed to dump certificates from 'security' or 'openssl'.");
                Logger.DebugException(e);
            }
        }
Пример #26
0
 private static long SizeOnDisk(string path)
 {
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         FileInfo info        = new FileInfo(path);
         uint     clusterSize = ClusterSizes[info.Directory.Root.FullName];
         uint     lowSize     = GetCompressedFileSizeW(path, out uint highSize);
         long     size        = (long)highSize << 32 | lowSize;
         return(((size + clusterSize - 1) / clusterSize) * clusterSize);
     }
     else
     {
         var exitCode = ExternalCommandRunner.RunExternalCommand("du", path, out string StdOut, out string StdErr);
         if (exitCode == 0 && long.TryParse(StdOut.Split('\t')[0], out long result))
         {
             return(result);
         }
         else
         {
             return(0);
         }
     }
 }
        /// <summary>
        /// On linux we check the central trusted root store (a folder), which has symlinks to
        /// actual cert locations scattered across the db We list all the certificates and then
        /// create a new X509Certificate2 object for each by filename.
        /// </summary>
        internal void ExecuteLinux(CancellationToken cancellationToken)
        {
            try
            {
                if (ExternalCommandRunner.RunExternalCommand("ls", "/etc/ssl/certs -A", out string result, out string _) == 0)
                {
                    foreach (var _line in result.Split('\n'))
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return;
                        }
                        Log.Debug("{0}", _line);
                        try
                        {
                            using X509Certificate2 certificate = new X509Certificate2("/etc/ssl/certs/" + _line);

                            var obj = new CertificateObject(
                                StoreLocation: StoreLocation.LocalMachine.ToString(),
                                StoreName: StoreName.Root.ToString(),
                                Certificate: new SerializableCertificate(certificate));
                            HandleChange(obj);
                        }
                        catch (Exception e)
                        {
                            Log.Debug("{0} {1} Issue creating certificate based on /etc/ssl/certs/{2}", e.GetType().ToString(), e.Message, _line);
                            Log.Debug("{0}", e.StackTrace);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Failed to dump certificates from 'ls /etc/ssl/certs -A'.");
            }
        }
Пример #28
0
        /// <summary>
        /// On linux we check the central trusted root store (a folder), which has symlinks to actual cert locations scattered across the db
        /// We list all the certificates and then create a new X509Certificate2 object for each by filename.
        /// </summary>
        public void ExecuteLinux()
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("ls", new string[] { "/etc/ssl/certs", "-A" });

                foreach (var _line in result.Split('\n'))
                {
                    Log.Debug("{0}", _line);
                    try
                    {
                        X509Certificate2 certificate = new X509Certificate2("/etc/ssl/certs/" + _line);

                        var obj = new CertificateObject()
                        {
                            StoreLocation         = StoreLocation.LocalMachine.ToString(),
                            StoreName             = StoreName.Root.ToString(),
                            CertificateHashString = certificate.GetCertHashString(),
                            Subject = certificate.Subject,
                            Pkcs12  = certificate.HasPrivateKey ? "redacted" : certificate.Export(X509ContentType.Pkcs12).ToString()
                        };
                        DatabaseManager.Write(obj, this.runId);
                    }
                    catch (Exception e)
                    {
                        Log.Debug("{0} {1} Issue creating certificate based on /etc/ssl/certs/{2}", e.GetType().ToString(), e.Message, _line);
                        Log.Debug("{0}", e.StackTrace);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error("Failed to dump certificates from 'ls /etc/ssl/certs -A'.");
                Logger.DebugException(e);
            }
        }
        /// <summary>
        ///     Uses systemctl (relies on systemd) and also checks /etc/init.d
        /// </summary>
        internal void ExecuteLinux(CancellationToken cancellationToken)
        {
            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("systemctl", "list-units --type service");

                //Split lines and remove header
                var lines = result.Split('\n').Skip(1);

                foreach (var _line in lines)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var _fields = _line.Split('\t');

                    if (_fields.Length == 5)
                    {
                        var obj = new ServiceObject(_fields[0])
                        {
                            DisplayName = _fields[4],
                            State       = _fields[3],
                        };

                        HandleChange(obj);
                    }
                }
            }
            catch (ExternalException)
            {
                Log.Error("Error executing {0}", "systemctl list-units --type service");
            }

            try
            {
                var result = ExternalCommandRunner.RunExternalCommand("ls", "/etc/init.d/ -l");

                var    lines   = result.Split('\n').Skip(1);
                String pattern = @".*\s(.*)";

                foreach (var _line in lines)
                {
                    Match           match       = Regex.Match(_line, pattern);
                    GroupCollection groups      = match.Groups;
                    var             serviceName = groups[1].ToString();

                    var obj = new ServiceObject(serviceName)
                    {
                        DisplayName = serviceName,
                    };

                    HandleChange(obj);
                }
            }
            catch (ExternalException)
            {
                Log.Error("Error executing {0}", "ls /etc/init.d/ -l");
            }
            // CentOS chkconfig --list

            // BSD service -l this provides very minor amount of info
        }
        /// <summary>
        /// Executes the ServiceCollector (main entrypoint).
        /// </summary>
        public override void Execute()
        {
            Start();

            if (!this.CanRunOnPlatform())
            {
                Log.Information("ServiceCollector cannot run on this platform.");
                return;
            }

            Truncate(runId);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                // This gathers official "services" on Windows, but perhaps neglects other startup items
                foreach (ServiceController service in ServiceController.GetServices())
                {
                    if (this.filter != null && !this.filter(service))
                    {
                        Log.Information("Service [{0}] did not pass filter, ignoring.", service.ToString());
                        continue;
                    }

                    var obj = new ServiceObject()
                    {
                        DisplayName  = service.DisplayName,
                        ServiceName  = service.ServiceName,
                        StartType    = service.StartType.ToString(),
                        CurrentState = service.Status.ToString()
                    };

                    this.Write(obj);
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                var runner = new ExternalCommandRunner();

                // Get the user processes
                // run "launchtl dumpstate" for the super detailed view
                // However, dumpstate is difficult to parse
                var result = runner.RunExternalCommand("launchctl", "list");
                Dictionary <string, ServiceObject> outDict = new Dictionary <string, ServiceObject>();
                foreach (var _line in result.Split('\n'))
                {
                    // Lines are formatted like this:
                    // PID   Exit  Name
                    //1015    0   com.apple.appstoreagent
                    var _fields = _line.Split('\t');
                    if (_fields.Length < 3 || _fields[0].Contains("PID"))
                    {
                        continue;
                    }
                    var obj = new ServiceObject()
                    {
                        DisplayName = _fields[2],
                        ServiceName = _fields[2],
                        StartType   = "Unknown",
                        // If we have a current PID then it is running.
                        CurrentState = (_fields[0].Equals("-"))?"Stopped":"Running"
                    };
                    if (!outDict.ContainsKey(obj.GetUniqueHash()))
                    {
                        this.Write(obj);
                        outDict.Add(obj.GetUniqueHash(), obj);
                    }
                }

                // Then get the system processes
                result = runner.RunExternalCommand("sudo", "launchctl list");

                foreach (var _line in result.Split('\n'))
                {
                    // Lines are formatted like this, with single tab separation:
                    //  PID     Exit    Name
                    //  1015    0       com.apple.appstoreagent
                    var _fields = _line.Split('\t');
                    if (_fields.Length < 3 || _fields[0].Contains("PID"))
                    {
                        continue;
                    }
                    var obj = new ServiceObject()
                    {
                        DisplayName = _fields[2],
                        ServiceName = _fields[2],
                        StartType   = "Unknown",
                        // If we have a current PID then it is running.
                        CurrentState = (_fields[0].Equals("-")) ? "Stopped" : "Running"
                    };

                    if (!outDict.ContainsKey(obj.GetUniqueHash()))
                    {
                        this.Write(obj);
                        outDict.Add(obj.GetUniqueHash(), obj);
                    }
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                var runner = new ExternalCommandRunner();

                var result = runner.RunExternalCommand("systemctl", "list-units --type service");

                //Split lines and remove header
                var lines = result.Split('\n');
                lines.ToList().RemoveAt(0);

                foreach (var _line in lines)
                {
                    var _fields = _line.Split('\t');

                    if (_fields.Count() == 5)
                    {
                        var obj = new ServiceObject()
                        {
                            DisplayName  = _fields[4],
                            ServiceName  = _fields[0],
                            StartType    = "Unknown",
                            CurrentState = _fields[3],
                        };

                        Write(obj);
                    }
                }

                result = runner.RunExternalCommand("ls", "/etc/init.d/ -l");

                lines = result.Split('\n');
                String pattern = @".*\s(.*)";

                foreach (var _line in lines)
                {
                    Match           match       = Regex.Match(_line, pattern);
                    GroupCollection groups      = match.Groups;
                    var             serviceName = groups[1].ToString();

                    var obj = new ServiceObject()
                    {
                        DisplayName  = serviceName,
                        ServiceName  = serviceName,
                        StartType    = "Unknown",
                        CurrentState = "Unknown"
                    };

                    Write(obj);
                }

                // without systemd (maybe just CentOS)
                // chkconfig --list

                // BSD
                // service -l
                // this provides very minor amount of info
            }

            Stop();
        }