Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BA2026.EnableAdditionalSecurityChecks #388

Merged
merged 6 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/BinSkim.Rules/PERules/BA2025.EnableShadowStack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ namespace Microsoft.CodeAnalysis.IL.Rules
[Export(typeof(Skimmer<BinaryAnalyzerContext>)), Export(typeof(ReportingDescriptor))]
public class EnableShadowStack : WindowsBinaryAndPdbSkimmerBase
{
private const int IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20;
private const ushort IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT = 0x001;

/// <summary>
/// BA2025
/// </summary>
Expand Down Expand Up @@ -79,10 +76,11 @@ public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext conte

foreach (DebugDirectoryEntry debugDirectory in debugDirectories)
{
if (debugDirectory.Type == (DebugDirectoryEntryType)IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS)
if ((ImageDebugType)debugDirectory.Type == ImageDebugType.IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS)
{
PEMemoryBlock memory = target.PE.GetSectionData(debugDirectory.DataRelativeVirtualAddress);
if ((memory.GetReader().ReadUInt16() & IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT) == IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT)
if ((memory.GetReader().ReadUInt16() & (ushort)ImageDllCharacteristicsEx.IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT)
== (ushort)ImageDllCharacteristicsEx.IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT)
{
// '{0}' enables the Control-flow Enforcement Technology (CET) Shadow Stack mitigation.
context.Logger.Log(this,
Expand Down
113 changes: 113 additions & 0 deletions src/BinSkim.Rules/PERules/BA2026.EnableAdditionalSecurityChecks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;
using System.Composition;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

using Microsoft.CodeAnalysis.BinaryParsers;
using Microsoft.CodeAnalysis.BinaryParsers.PortableExecutable;
using Microsoft.CodeAnalysis.IL.Sdk;
using Microsoft.CodeAnalysis.Sarif;
using Microsoft.CodeAnalysis.Sarif.Driver;

namespace Microsoft.CodeAnalysis.IL.Rules
{
[Export(typeof(Skimmer<BinaryAnalyzerContext>)), Export(typeof(ReportingDescriptor))]
public class EnableAdditionalSecurityChecks : WindowsBinaryAndPdbSkimmerBase
{
/// <summary>
/// BA2026
/// </summary>
public override string Id => RuleIds.EnableAdditionalSecurityChecks;

/// <summary>
/// /sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-.
/// By default, /sdl is off. /sdl- disables the additional security checks.
/// </summary>
public override MultiformatMessageString FullDescription => new MultiformatMessageString
{
Text = RuleResources.BA2026_EnableAdditionalSecurityChecks_Description
};

protected override IEnumerable<string> MessageResourceNames => new string[] {
nameof(RuleResources.BA2026_Pass),
nameof(RuleResources.BA2026_Warning),
nameof(RuleResources.NotApplicable_InvalidMetadata)
};

public override AnalysisApplicability CanAnalyzePE(PEBinary target, Sarif.PropertiesDictionary policy, out string reasonForNotAnalyzing)
{
PE portableExecutable = target.PE;
AnalysisApplicability notApplicable = AnalysisApplicability.NotApplicableToSpecifiedTarget;

if (portableExecutable.IsILOnly)
{
reasonForNotAnalyzing = MetadataConditions.ImageIsILOnlyAssembly;
return notApplicable;
}

if (portableExecutable.IsResourceOnly)
{
reasonForNotAnalyzing = MetadataConditions.ImageIsResourceOnlyBinary;
return notApplicable;
}

if (portableExecutable.IsNativeUniversalWindowsPlatform)
{
reasonForNotAnalyzing = MetadataConditions.ImageIsNativeUniversalWindowsPlatformBinary;
return notApplicable;
}

reasonForNotAnalyzing = null;
return AnalysisApplicability.ApplicableToSpecifiedTarget;
}

public override void AnalyzePortableExecutableAndPdb(BinaryAnalyzerContext context)
{
PEBinary target = context.PEBinary();
IEnumerable<DebugDirectoryEntry> debugDirectories = target.PE.DebugDirectories;

if (debugDirectories == null)
{
return;
}

foreach (DebugDirectoryEntry debugDirectory in debugDirectories)
{
if ((ImageDebugType)debugDirectory.Type == ImageDebugType.IMAGE_DEBUG_TYPE_VC_FEATURE)
{
PEMemoryBlock memory = target.PE.GetSectionData(debugDirectory.DataRelativeVirtualAddress);
BlobReader reader = memory.GetReader();
reader.ReadUInt32(); // Pre-VC++ 11.00 flag
reader.ReadUInt32(); // C/C++ Version
reader.ReadUInt32(); // /GS setting
uint sdlSetting = reader.ReadUInt32(); // /sdl setting
reader.ReadUInt32(); // guardN setting

if (sdlSetting == 1)
{
// '{0}' enables the recommended Security Development Lifecycle (SDL) checks.
// These checks change security-relevant warnings into errors, and set additional secure code-generation features.
context.Logger.Log(this,
RuleUtilities.BuildResult(ResultKind.Pass, context, null,
nameof(RuleResources.BA2026_Pass),
context.TargetUri.GetFileName()));
return;
}
else
{
// '{0}' does not enable the recommended Security Development Lifecycle (SDL) checks.
// To Enable the recommended Security Development Lifecycle (SDL) checks pass /sdl on the cl.exe command-line.
context.Logger.Log(this,
RuleUtilities.BuildResult(FailureLevel.Warning, context, null,
nameof(RuleResources.BA2026_Warning),
context.TargetUri.GetFileName()));
return;
}
}
}
}
}
}
1 change: 1 addition & 0 deletions src/BinSkim.Rules/RuleIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ internal static class RuleIds

public const string EnableSpectreMitigations = "BA2024";
public const string EnableShadowStack = "BA2025";
public const string EnableAdditionalSecurityChecks = "BA2026";

// ELF Checks
public const string EnablePositionIndependentExecutable = "BA3001";
Expand Down
27 changes: 27 additions & 0 deletions src/BinSkim.Rules/RuleResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/BinSkim.Rules/RuleResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -538,4 +538,13 @@ Modules triggering this check were:
<data name="BA4002_ReportELFCompilerData_Description" xml:space="preserve">
<value>This rule emits CSV data to the console for every compiler/language/version combination that's observed.</value>
</data>
<data name="BA2026_EnableAdditionalSecurityChecks_Description" xml:space="preserve">
<value>/sdl enables a superset of the baseline security checks provided by /GS and overrides /GS-. By default, /sdl is off. /sdl- disables the additional security checks.</value>
</data>
<data name="BA2026_Warning" xml:space="preserve">
<value>'{0}' does not enable the recommended Security Development Lifecycle (SDL) checks. To Enable the recommended Security Development Lifecycle (SDL) checks pass /sdl on the cl.exe command-line.</value>
</data>
<data name="BA2026_Pass" xml:space="preserve">
<value>'{0}' enables the recommended Security Development Lifecycle (SDL) checks. These checks change security-relevant warnings into errors, and set additional secure code-generation features.</value>
</data>
</root>
27 changes: 27 additions & 0 deletions src/BinaryParsers/PEBinary/PortableExecutable/ImageDebugType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.CodeAnalysis.BinaryParsers.PortableExecutable
{
public enum ImageDebugType
{
IMAGE_DEBUG_TYPE_UNKNOWN = 0,
IMAGE_DEBUG_TYPE_COFF = 1,
IMAGE_DEBUG_TYPE_CODEVIEW = 2,
IMAGE_DEBUG_TYPE_FPO = 3,
IMAGE_DEBUG_TYPE_MISC = 4,
IMAGE_DEBUG_TYPE_EXCEPTION = 5,
IMAGE_DEBUG_TYPE_FIXUP = 6,
IMAGE_DEBUG_TYPE_OMAP_TO_SRC = 7,
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC = 8,
IMAGE_DEBUG_TYPE_BORLAND = 9,
IMAGE_DEBUG_TYPE_RESERVED10 = 10,
IMAGE_DEBUG_TYPE_CLSID = 11,
IMAGE_DEBUG_TYPE_VC_FEATURE = 12,
IMAGE_DEBUG_TYPE_POGO = 13,
IMAGE_DEBUG_TYPE_ILTCG = 14,
IMAGE_DEBUG_TYPE_MPX = 15,
IMAGE_DEBUG_TYPE_REPRO = 16,
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.CodeAnalysis.BinaryParsers.PortableExecutable
{
public enum ImageDllCharacteristicsEx
{
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT = 0x01,
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE = 0x02,
IMAGE_DLLCHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x04,
IMAGE_DLLCHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC = 0x08,
IMAGE_DLLCHARACTERISTICS_EX_CET_RESERVED_1 = 0x10, // Reserved for CET policy *downgrade* only
IMAGE_DLLCHARACTERISTICS_EX_CET_RESERVED_2 = 0x20, // Reserved for CET policy *downgrade* only
}
}
Loading