Exemple #1
0
        private FileAccessManifest GenerateFileAccessManifest(AbsolutePath toolDirectory, AbsolutePath outputFile)
        {
            // We make no attempt at understanding what the graph generation process is going to do
            // We just configure the manifest to not fail on unexpected accesses, so they can be collected
            // later if needed
            var fileAccessManifest = new FileAccessManifest(m_context.PathTable)
            {
                FailUnexpectedFileAccesses   = false,
                ReportFileAccesses           = true,
                MonitorNtCreateFile          = true,
                MonitorZwCreateOpenQueryFile = true,
                MonitorChildProcesses        = true,
            };

            fileAccessManifest.AddScope(
                AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.Windows)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAllButSymlinkCreation);

            fileAccessManifest.AddScope(
                AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.InternetCache)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAllButSymlinkCreation);

            fileAccessManifest.AddScope(
                AbsolutePath.Create(m_context.PathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.History)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAllButSymlinkCreation);

            fileAccessManifest.AddScope(toolDirectory, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowReadAlways);
            fileAccessManifest.AddPath(outputFile, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowWrite);

            return(fileAccessManifest);
        }
        /// <summary>
        /// The manifest is configured so all file accesses are allowed but reported, including child processes.
        /// </summary>
        /// <remarks>
        /// Some special folders (Windows, InternetCache and History) are added as known scopes. Everything else will be flagged
        /// as an 'unexpected' access. However, unexpected accesses are configured so they are not blocked.
        /// </remarks>
        private static FileAccessManifest CreateManifestToAllowAllAccesses(PathTable pathTable)
        {
            var fileAccessManifest = new FileAccessManifest(pathTable)
            {
                FailUnexpectedFileAccesses = false,
                ReportFileAccesses         = true,
                MonitorChildProcesses      = true,
            };

            fileAccessManifest.AddScope(
                AbsolutePath.Create(pathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.Windows)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAll);

            fileAccessManifest.AddScope(
                AbsolutePath.Create(pathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.InternetCache)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAll);

            fileAccessManifest.AddScope(
                AbsolutePath.Create(pathTable, SpecialFolderUtilities.GetFolderPath(Environment.SpecialFolder.History)),
                FileAccessPolicy.MaskAll,
                FileAccessPolicy.AllowAll);


            return(fileAccessManifest);
        }
Exemple #3
0
        public void BreakawayProcessCanReportAugmentedAccesses()
        {
            var fam = new FileAccessManifest(
                Context.PathTable,
                childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName })
            {
                FailUnexpectedFileAccesses   = false,
                ReportUnexpectedFileAccesses = true,
                ReportFileAccesses           = true
            };

            var srcFile = CreateSourceFile();
            var output  = CreateOutputFileArtifact();

            fam.AddScope(srcFile, FileAccessPolicy.MaskNothing, FileAccessPolicy.ReportAccess);
            fam.AddScope(output, FileAccessPolicy.MaskNothing, FileAccessPolicy.ReportAccess);

            var info = ToProcessInfo(
                ToProcess(
                    Operation.AugmentedRead(srcFile),
                    Operation.AugmentedWrite(output)),
                fileAccessManifest: fam);

            var result = RunProcess(info).GetAwaiter().GetResult();

            XAssert.AreEqual(0, result.ExitCode);

            var observedAccesses = result.FileAccesses.Select(fa => fa.ManifestPath);

            XAssert.Contains(observedAccesses, srcFile.Path, output.Path);
        }
Exemple #4
0
        /// <summary>
        /// The manifest is configured so all accesses under the provided collection of directories to block are blocked
        /// </summary>
        private FileAccessManifest CreateManifest(AbsolutePath pathToProcess, IEnumerable <AbsolutePath> directoriesToBlock)
        {
            var fileAccessManifest = new FileAccessManifest(m_pathTable)
            {
                FailUnexpectedFileAccesses = true,
                ReportFileAccesses         = true,
                MonitorChildProcesses      = true,
            };

            // We allow all file accesses at the root level, so by default everything is allowed
            fileAccessManifest.AddScope(AbsolutePath.Invalid, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll);

            // We explicitly allow reading from the tool path
            fileAccessManifest.AddPath(pathToProcess, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowRead);

            // We block access on all provided directories
            foreach (var directoryToBlock in directoriesToBlock)
            {
                fileAccessManifest.AddScope(
                    directoryToBlock,
                    FileAccessPolicy.MaskAll,
                    FileAccessPolicy.Deny & FileAccessPolicy.ReportAccess);
            }

            return(fileAccessManifest);
        }
        public void MaskedReportAugmentedAccessIsNotReported()
        {
            var fam = new FileAccessManifest(
                Context.PathTable,
                childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName })
            {
                FailUnexpectedFileAccesses   = false,
                ReportUnexpectedFileAccesses = true,
                ReportFileAccesses           = true
            };

            var basePath = TestBinRootPath.Combine(Context.PathTable, "foo");

            var output1 = CreateOutputFileArtifact(basePath);
            var output2 = CreateOutputFileArtifact(basePath);

            // We mask reporting accesses for output1 and enable it for output2
            fam.AddScope(output1.Path, ~FileAccessPolicy.ReportAccess, FileAccessPolicy.AllowAll);
            fam.AddScope(output2.Path, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess);

            var info = ToProcessInfo(
                ToProcess(
                    Operation.AugmentedWrite(output1),
                    Operation.AugmentedWrite(output2)),
                fileAccessManifest: fam);

            var result = RunProcess(info).GetAwaiter().GetResult();

            XAssert.AreEqual(0, result.ExitCode);

            // We should get a single access with output2, since output1 should be ignored
            var accessPath = result.FileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).ManifestPath;

            XAssert.AreEqual(output2.Path, accessPath);
        }
Exemple #6
0
        public void MaskedReportAugmentedAccessIsNotReported(bool reportFileAccesses)
        {
            var fam = new FileAccessManifest(
                Context.PathTable,
                childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName })
            {
                FailUnexpectedFileAccesses   = false,
                ReportUnexpectedFileAccesses = true,
                ReportFileAccesses           = reportFileAccesses
            };

            var basePath = TestBinRootPath.Combine(Context.PathTable, "foo");

            var output1 = CreateOutputFileArtifact(basePath);
            var output2 = CreateOutputFileArtifact(basePath);

            // We mask reporting accesses for output1 and enable it for output2
            fam.AddScope(output1.Path, ~FileAccessPolicy.ReportAccess, FileAccessPolicy.AllowAll);
            fam.AddScope(output2.Path, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess);

            var collector = new FileAccessCollector(Context.PathTable);

            var info = ToProcessInfo(
                ToProcess(
                    Operation.AugmentedWrite(output1),
                    Operation.AugmentedWrite(output2)),
                fileAccessManifest: fam,
                detoursListener: collector);

            var result = RunProcess(info).GetAwaiter().GetResult();

            XAssert.AreEqual(0, result.ExitCode);

            // We should get a single explicit access with output2, since output1 shouldn't be reported
            var accessPath = result.ExplicitlyReportedFileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).ManifestPath;

            XAssert.AreEqual(output2.Path, accessPath);

            // We should get both accesses as part of the (optional) FileAccess on request
            if (reportFileAccesses)
            {
                var allTrustedAcceses = result.FileAccesses.Where(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool).Select(rfa => rfa.ManifestPath);
                XAssert.Contains(allTrustedAcceses, output1.Path, output2.Path);
            }
            else
            {
                // Make sure the access related to output1 is not actually reported, and the only one the listener got is output2
                XAssert.Contains(collector.FileAccessPaths, output2.Path);
                XAssert.ContainsNot(collector.FileAccessPaths, output1.Path);
            }
        }
Exemple #7
0
        public void AugmentedAccessHasTheRightManifestPath()
        {
            var fam = new FileAccessManifest(
                Context.PathTable,
                childProcessesToBreakawayFromSandbox: new[] { TestProcessToolName })
            {
                FailUnexpectedFileAccesses   = false,
                ReportUnexpectedFileAccesses = true,
                ReportFileAccesses           = true
            };

            var basePath = TestBinRootPath.Combine(Context.PathTable, "foo");

            var output = CreateOutputFileArtifact(basePath);

            fam.AddScope(basePath, FileAccessPolicy.MaskNothing, FileAccessPolicy.AllowAll | FileAccessPolicy.ReportAccess);

            var info = ToProcessInfo(
                ToProcess(
                    Operation.AugmentedWrite(output)),
                fileAccessManifest: fam);

            var result = RunProcess(info).GetAwaiter().GetResult();

            XAssert.AreEqual(0, result.ExitCode);

            var fileAccess = result.ExplicitlyReportedFileAccesses.Single(rfa => rfa.Method == FileAccessStatusMethod.TrustedTool);

            XAssert.AreEqual(basePath, fileAccess.ManifestPath);
        }
Exemple #8
0
 private void AddBlockedPath(FileAccessManifest fam, SandboxOptions option, AbsolutePath path)
 {
     if (option.debug)
     {
         Console.Error.WriteLine($"na: {path.ToString(m_pathTable)}");
     }
     fam.AddScope(path, FileAccessPolicy.MaskAll, FileAccessPolicy.Deny);
 }
Exemple #9
0
        /// <nodoc />
        private FileAccessManifest CreateManifest(AbsolutePath pathToProcess, SandboxOptions option, string workingDir)
        {
            var fam = new FileAccessManifest(m_pathTable)
            {
                FailUnexpectedFileAccesses   = true,
                ReportFileAccesses           = false,
                ReportUnexpectedFileAccesses = false,
                MonitorChildProcesses        = true,
                MonitorNtCreateFile          = true,
                MonitorZwCreateOpenQueryFile = true,
            };

            // We make whole filesystem as read-only.
            fam.AddScope(AbsolutePath.Invalid, FileAccessPolicy.MaskAll, FileAccessPolicy.AllowRead);

            // Block working dir
            AddBlockedPath(fam, option, AbsolutePath.Create(m_pathTable, workingDir));

            // We explicitly allow reading from the tool path
            AddReadOnlyPath(fam, option, pathToProcess);

            // We allow access on all provided files/directories
            // Note: if C:\A is allowed, its subtree is allowed too.
            foreach (var path in option.readonly_files)
            {
                AddReadOnlyPath(fam, option, path);
            }

            foreach (var path in option.writable_files)
            {
                AddReadWritePath(fam, option, path);
            }

            foreach (var path in option.blocked_files)
            {
                AddBlockedPath(fam, option, path);
            }

            return(fam);
        }