public override AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { PE portableExecutable = context.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsILOnlyManagedAssembly; if (portableExecutable.IsILOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyzePE(PEBinary target, PropertiesDictionary policy, out string reasonForNotAnalyzing) { PE portableExecutable = target.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsILOnlyAssembly; if (portableExecutable.IsILOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyzePE(PEBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) { PE portableExecutable = target.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsKernelModeBinary; if (portableExecutable.IsKernelMode) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageLikelyLoadsAs32BitProcess; if (portableExecutable.PEHeaders.PEHeader.Magic != PEMagic.PE32Plus) { // If the image's magic bytes are 'PE32', it is either a 32 bit binary (rule does not apply), or it is a managed binary compiled as AnyCpu. // If it's an AnyCPU managed binary, we need to do a bit more checking--if it has 'Prefers32Bit'/'Requires32Bit' flagged, it will probably // load as a 32 bit process. If it doesn't, we're likely to load in a 64 bit process space on a 64 bit arch & want to ensure HighEntropyVA is enabled. if (!portableExecutable.IsManaged || portableExecutable.IsManaged && portableExecutable.PEHeaders.CorHeader.Flags.HasFlag(CorFlags.Requires32Bit)) { return(result); } } reasonForNotAnalyzing = MetadataConditions.ImageIsNotExe; if (!portableExecutable.PEHeaders.IsExe) { return(result); } // A dotnet core entry point dll is itself loaded within a process // that will always be configured for high entropy va, if available. reasonForNotAnalyzing = MetadataConditions.ImageIsDotNetCoreEntryPointDll; if (portableExecutable.IsDotNetCore || portableExecutable.IsDotNetStandard) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public sealed override AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { AnalysisApplicability result = base.CanAnalyze(context, out reasonForNotAnalyzing); if (result != AnalysisApplicability.ApplicableToSpecifiedTarget) { return(result); } PE portableExecutable = context.PEBinary().PE; result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsWixBinary; if (portableExecutable.IsWixBinary) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public void SearchSkimmer_DenyFileNameRegexFiltersProperly() { string scanTargetExtension = Guid.NewGuid().ToString(); SearchDefinition definition = null; AnalyzeContext context = CreateGuidMatchingSkimmer( scanTargetExtension: scanTargetExtension, ref definition, out SearchSkimmer skimmer, allowFileExtension: null, denyFileExtension: scanTargetExtension); AnalysisApplicability applicability = skimmer.CanAnalyze(context, out string reasonIfNotApplicable); applicability.Should().Be(AnalysisApplicability.NotApplicableToSpecifiedTarget); reasonIfNotApplicable.Should().Be(SpamResources.TargetDoesNotMeetFileNameCriteria); skimmer.Analyze(context); ((TestLogger)context.Logger).Results.Should().BeNull(); }
public AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { PE portableExecutable = context.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsKernelModeBinary; if (portableExecutable.IsKernelMode) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsNot64BitBinary; if (portableExecutable.PEHeaders.PEHeader.Magic != PEMagic.PE32Plus) { return(result); } // TODO need to put a check here for verifying that the // compiler that built the target supports high entropy va return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { PE portableExecutable = context.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIs64BitBinary; if (context.PE.PEHeaders.PEHeader.Magic == PEMagic.PE32Plus) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsKernelModeBinary; if (portableExecutable.IsKernelMode) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsXBoxBinary; if (portableExecutable.IsXBox) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsPreVersion7WindowsCEBinary; if (OSVersions.IsWindowsCEPriorToV7(portableExecutable)) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyzePE(PEBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) { PE portableExecutable = target.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; // Review the range of metadata conditions and return NotApplicableToSpecifiedTarget // from this method for all cases where a binary is detected that is not valid to scan. // reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } // Here's an example of parameterizing a rule from input XML. In this example, // we enforce that the linker is of a minimal version, otherwise the scan will // not occur (because the toolset producing the binary is not sufficiently // current to enable the security mitigation). // Version minimumRequiredLinkerVersion = policy.GetProperty(MinimumRequiredLinkerVersion); if (portableExecutable.LinkerVersion < minimumRequiredLinkerVersion) { reasonForNotAnalyzing = string.Format( MetadataConditions.ImageCompiledWithOutdatedTools, portableExecutable.LinkerVersion, minimumRequiredLinkerVersion); return(result); } // If we get to this location, we've determined the binary is valid to analyze. // We clear the 'reasonForNotAnalyzing' output variable and return // ApplicableToSpecifiedTarget. // reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { PE portableExecutable = context.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsKernelModeBinary; if (portableExecutable.IsKernelMode) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsILOnlyManagedAssembly; if (portableExecutable.IsILOnly) { return(result); } if (portableExecutable.LinkerVersion < MinimumSupportedLinkerVersion) { reasonForNotAnalyzing = string.Format( MetadataConditions.ImageCompiledWithOutdatedTools, portableExecutable.LinkerVersion, MinimumSupportedLinkerVersion); return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
internal static AnalysisApplicability CommonCanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { PE portableExecutable = context.PE; AnalysisApplicability result = AnalysisApplicability.NotApplicableToSpecifiedTarget; reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary; if (portableExecutable.IsResourceOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsILOnlyManagedAssembly; if (portableExecutable.IsILOnly) { return(result); } reasonForNotAnalyzing = MetadataConditions.ImageIsXBoxBinary; if (portableExecutable.IsXBox) { return(result); } // .NET native compiled binaries are not fully /GS enabled. This is // considered reasonable, as the binaries themselves consist strictly // of cross-compiled MSIL. The supporting native libraries for these // applications exists in a separate (/GS enabled) native dll. reasonForNotAnalyzing = MetadataConditions.ImageIsDotNetNativeBinary; if (portableExecutable.IsDotNetNative) { return(result); } reasonForNotAnalyzing = null; return(AnalysisApplicability.ApplicableToSpecifiedTarget); }
public override AnalysisApplicability CanAnalyze(BinaryAnalyzerContext context, out string reasonForNotAnalyzing) { AnalysisApplicability applicability = StackProtectionUtilities.CommonCanAnalyze(context, out reasonForNotAnalyzing); return(applicability); }
public override AnalysisApplicability CanAnalyzePE(PEBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing) { AnalysisApplicability applicability = StackProtectionUtilities.CommonCanAnalyze(target, out reasonForNotAnalyzing); return(applicability); }
private void VerifyApplicability( BinarySkimmer skimmer, HashSet <string> applicabilityConditions, AnalysisApplicability expectedApplicability = AnalysisApplicability.NotApplicableToSpecifiedTarget, bool useDefaultPolicy = false) { string ruleName = skimmer.GetType().Name; string testFilesDirectory = GetTestDirectoryFor(ruleName); testFilesDirectory = Path.Combine(Environment.CurrentDirectory, "FunctionalTestsData", testFilesDirectory); testFilesDirectory = Path.Combine(testFilesDirectory, "NotApplicable"); var context = new BinaryAnalyzerContext(); HashSet <string> targets = this.GetTestFilesMatchingConditions(applicabilityConditions); if (Directory.Exists(testFilesDirectory)) { foreach (string target in Directory.GetFiles(testFilesDirectory, "*", SearchOption.AllDirectories)) { if (AnalyzeCommand.ValidAnalysisFileExtensions.Contains(Path.GetExtension(target))) { targets.Add(target); } } } var logger = new TestMessageLogger(); context.Logger = logger; var sb = new StringBuilder(); foreach (string target in targets) { string extension = Path.GetExtension(target); context = this.CreateContext(logger, null, target); if (!context.IsValidAnalysisTarget) { continue; } if (useDefaultPolicy) { context.Policy = new PropertiesDictionary(); } context.Rule = skimmer; AnalysisApplicability applicability; applicability = skimmer.CanAnalyze(context, out string reasonForNotAnalyzing); if (applicability != expectedApplicability) { sb.AppendLine("CanAnalyze did not correct indicate target applicability (unexpected return was " + applicability + "): " + Path.GetFileName(target)); continue; } } if (sb.Length > 0) { this.testOutputHelper.WriteLine(sb.ToString()); } Assert.Equal(0, sb.Length); }
private void VerifyNotApplicable( IBinarySkimmer skimmer, HashSet<string> notApplicableConditions, AnalysisApplicability expectedApplicability = AnalysisApplicability.NotApplicableToSpecifiedTarget) { string ruleName = skimmer.GetType().Name; string testFilesDirectory = ruleName; testFilesDirectory = Path.Combine(Environment.CurrentDirectory, "FunctionalTestsData", testFilesDirectory); testFilesDirectory = Path.Combine(testFilesDirectory, "NotApplicable"); var context = new BinaryAnalyzerContext(); HashSet<string> targets = GetTestFilesMatchingConditions(notApplicableConditions); if (Directory.Exists(testFilesDirectory)) { foreach (string target in Directory.GetFiles(testFilesDirectory, "*", SearchOption.AllDirectories)) { if (AnalyzeCommand.ValidAnalysisFileExtensions.Contains(Path.GetExtension(target))) { targets.Add(target); } } } var logger = new TestMessageLogger(); context.Logger = logger; var sb = new StringBuilder(); foreach (string target in targets) { string extension = Path.GetExtension(target); if (!AnalyzeCommand.ValidAnalysisFileExtensions.Contains(extension)) { Assert.True(false, "Test file with unexpected extension encountered: " + target); } context = CreateContext(logger, null, target); if (!context.PE.IsPEFile) { continue; } context.Rule = skimmer; string reasonForNotAnalyzing; AnalysisApplicability applicability; applicability = skimmer.CanAnalyze(context, out reasonForNotAnalyzing); if (applicability != expectedApplicability) { sb.AppendLine("CanAnalyze did not indicate target was invalid for analysis (return was " + applicability + "): " + Path.GetFileName(target)); continue; } } if (sb.Length > 0) { _testOutputHelper.WriteLine(sb.ToString()); } Assert.Equal(0, sb.Length); }
private void Analyze( IEnumerable <IBinarySkimmer> skimmers, IList <string> roslynAnalyzerFilePaths, IEnumerable <string> targets, AggregatingLogger logger, PropertyBag policy) { HashSet <string> disabledSkimmers = new HashSet <string>(); foreach (string target in targets) { var context = AnalyzeCommand.CreateContext(logger, policy, target); if (context.PE.LoadException != null) { LogExceptionLoadingTarget(context); continue; } else if (!context.PE.IsPEFile) { LogExceptionInvalidPE(context); continue; } context = CreateContext(logger, policy, target); // Analyzing {0}... logger.Log(MessageKind.AnalyzingTarget, context, DriverResources.Analyzing); foreach (IBinarySkimmer skimmer in skimmers) { if (disabledSkimmers.Contains(skimmer.Id)) { continue; } string reasonForNotAnalyzing = null; context.Rule = skimmer; AnalysisApplicability applicability = AnalysisApplicability.Unknown; try { applicability = skimmer.CanAnalyze(context, out reasonForNotAnalyzing); } catch (Exception ex) { LogUnhandledRuleExceptionAssessingTargetApplicability(disabledSkimmers, context, skimmer, ex); continue; } switch (applicability) { case AnalysisApplicability.NotApplicableToSpecifiedTarget: { // Image '{0}' was not evaluated for check '{1}' as the analysis // is not relevant based on observed binary metadata: {2}. context.Logger.Log(MessageKind.NotApplicable, context, RuleUtilities.BuildTargetNotAnalyzedMessage( context.PE.FileName, context.Rule.Name, reasonForNotAnalyzing)); break; } case AnalysisApplicability.NotApplicableToAnyTargetWithoutPolicy: { // Check '{0}' was disabled for this run as the analysis was not // configured with required policy ({1}). To resolve this, // configure and provide a policy file on the BinSkim command-line // using the --policy argument (recommended), or pass // '--policy default' to invoke built-in settings. Invoke the // BinSkim.exe 'export' command to produce an initial policy file // that can be edited if required and passed back into the tool. context.Logger.Log(MessageKind.ConfigurationError, context, RuleUtilities.BuildRuleDisabledDueToMissingPolicyMessage( context.Rule.Name, reasonForNotAnalyzing)); disabledSkimmers.Add(skimmer.Id); break; } case AnalysisApplicability.ApplicableToSpecifiedTarget: { try { skimmer.Analyze(context); } catch (Exception ex) { LogUnhandledRuleExceptionAnalyzingTarget(disabledSkimmers, context, skimmer, ex); } break; } } } // Once we've processed all portable executable skimmers for a specific // target, we'll proactively let go of the data associated with this // analysis phase. Follow-on analyses (such as the Roslyn integration) // shouldn't attempt to rehydrate this data. The context implementation // currently raises an exception if there is an attempt to rehydrate a // previously nulled PE instance. DisposePortableExecutableContextData(context); // IsManagedAssembly is computed on intitializing the binary context // object and is still valid after disposing the PE data. The Roslyn // analysis is driven solely off the binary file path in the context. if (context.IsManagedAssembly && roslynAnalyzerFilePaths?.Count > 0) { AnalyzeManagedAssembly(context.Uri.LocalPath, roslynAnalyzerFilePaths, context); } } }
private void VerifyNotApplicable( IBinarySkimmer skimmer, HashSet <string> notApplicableConditions, AnalysisApplicability expectedApplicability = AnalysisApplicability.NotApplicableToSpecifiedTarget) { string ruleName = skimmer.GetType().Name; string testFilesDirectory = ruleName; testFilesDirectory = Path.Combine(Environment.CurrentDirectory, "FunctionalTestsData", testFilesDirectory); testFilesDirectory = Path.Combine(testFilesDirectory, "NotApplicable"); var context = new BinaryAnalyzerContext(); HashSet <string> targets = GetTestFilesMatchingConditions(notApplicableConditions); if (Directory.Exists(testFilesDirectory)) { foreach (string target in Directory.GetFiles(testFilesDirectory, "*", SearchOption.AllDirectories)) { if (AnalyzeCommand.ValidAnalysisFileExtensions.Contains(Path.GetExtension(target))) { targets.Add(target); } } } var logger = new TestMessageLogger(); context.Logger = logger; var sb = new StringBuilder(); foreach (string target in targets) { string extension = Path.GetExtension(target); if (!AnalyzeCommand.ValidAnalysisFileExtensions.Contains(extension)) { Assert.True(false, "Test file with unexpected extension encountered: " + target); } context = CreateContext(logger, null, target); if (!context.PE.IsPEFile) { continue; } context.Rule = skimmer; string reasonForNotAnalyzing; AnalysisApplicability applicability; applicability = skimmer.CanAnalyze(context, out reasonForNotAnalyzing); if (applicability != expectedApplicability) { sb.AppendLine("CanAnalyze did not indicate target was invalid for analysis (return was " + applicability + "): " + Path.GetFileName(target)); continue; } } if (sb.Length > 0) { _testOutputHelper.WriteLine(sb.ToString()); } Assert.Equal(0, sb.Length); }
protected virtual TContext AnalyzeTarget( TOptions options, IEnumerable <ISkimmer <TContext> > skimmers, TContext rootContext, string target, HashSet <string> disabledSkimmers) { var context = CreateContext(options, rootContext.Logger, rootContext.Policy, target); if (context.TargetLoadException != null) { LogExceptionLoadingTarget(context); return(context); } else if (!context.IsValidAnalysisTarget) { LogExceptionInvalidTarget(context); return(context); } // Analyzing {0}... context.Rule = NoteDescriptors.AnalyzingTarget; context.Logger.Log(ResultKind.Note, context, string.Format(SdkResources.Analyzing, Path.GetFileName(context.TargetUri.LocalPath))); foreach (ISkimmer <TContext> skimmer in skimmers) { if (disabledSkimmers.Contains(skimmer.Id)) { continue; } string reasonForNotAnalyzing = null; context.Rule = skimmer; AnalysisApplicability applicability = AnalysisApplicability.Unknown; try { applicability = skimmer.CanAnalyze(context, out reasonForNotAnalyzing); } catch (Exception ex) { LogUnhandledRuleExceptionAssessingTargetApplicability(disabledSkimmers, context, skimmer, ex); continue; } switch (applicability) { case AnalysisApplicability.NotApplicableToSpecifiedTarget: { // Image '{0}' was not evaluated for check '{1}' as the analysis // is not relevant based on observed binary metadata: {2}. context.Logger.Log(ResultKind.NotApplicable, context, MessageUtilities.BuildTargetNotAnalyzedMessage( context.TargetUri.LocalPath, context.Rule.Name, reasonForNotAnalyzing)); break; } case AnalysisApplicability.NotApplicableToAnyTargetWithoutPolicy: { // Check '{0}' was disabled for this run as the analysis was not // configured with required policy ({1}). To resolve this, // configure and provide a policy file on the BinSkim command-line // using the --policy argument (recommended), or pass // '--policy default' to invoke built-in settings. Invoke the // BinSkim.exe 'export' command to produce an initial policy file // that can be edited if required and passed back into the tool. context.Logger.Log(ResultKind.ConfigurationError, context, MessageUtilities.BuildRuleDisabledDueToMissingPolicyMessage( context.Rule.Name, reasonForNotAnalyzing)); disabledSkimmers.Add(skimmer.Id); break; } case AnalysisApplicability.ApplicableToSpecifiedTarget: { try { skimmer.Analyze(context); } catch (Exception ex) { LogUnhandledRuleExceptionAnalyzingTarget(disabledSkimmers, context, skimmer, ex); } break; } } } return(context); }