Git Product home page Git Product logo

binskim's Introduction

BinSkim Binary Analyzer

This repository contains the source code for BinSkim, a Portable Executable (PE) light-weight scanner that validates compiler/linker settings and other security-relevant binary characteristics.

For Developers

  1. Fork the repository -- Need Help?
  2. Read the Rule Contributions Guide
  3. Load and compile src\BinSkim.sln to develop changes for contribution.
  4. Execute BuildAndTest.cmd at the root of the enlistment to validate before submitting a PR.

Submit Pull Requests

  1. Run BuildAndTest.cmd at the root of the enlistment to ensure that all tests pass, release build succeeds, and NuGet packages are created
  2. Submit a Pull Request to the 'develop' branch -- Need Help?

For Users

  1. Download BinSkim from NuGet
  2. Read the User Guide
  3. Find out more about the Static Analysis Results Interchange Format (SARIF) used to output Binskim results

How to extract the exe file from the nuget package

If you only want to run the Binskim tool without installing anything, then you can

  1. Download BinSkim from NuGet
  2. Rename the file extension from .nupkg to .zip (ie. via commandline: rename microsoft.codeanalysis.binskim.x.y.z.nupkg microsoft.codeanalysis.binskim.x.y.z.zip)
  3. Unzip
  4. Executable files are now available in the OS specific folder within tools\netcoreapp3.1 (ie. linux-x64, win-x64, and osx-x64).
  5. Navigate to this location to invoke the executable:
    • Windows: binskim.exe analyze c:\bld\*.dll --recurse true --output MyRun.sarif
    • Linux/Unix: ./BinSkim analyze /someDirectory/testBinary -o MyRun.sarif
    • Mac: ./BinSkim analyze /someDirectory/testBinary -o MyRun.sarif
    • Using dotnet sdk: dotnet binskim.dll analyze /directoryPath/testBinary -o MyRun.sarif

Command-Line Quick Guide

Argument (short form, long form) Meaning
--trace Execution traces, expressed as a semicolon-delimited list enclosed in double quotes, that should be emitted to the console and log file (if appropriate). Valid values: PdbLoad, ScanTime, RuleScanTime, PeakWorkingSet, TargetsScanned, ResultsSummary.
--sympath Symbol paths, expressed as a semicolon-delimited list enclosed in double quotes. (e.g. SRV*https://msdl.microsoft.com/download/symbols or Cache*d:\symbols;Srv*https://symweb) See https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/advanced-symsrv-use for syntax information.
--local-symbol-directories Local directory paths, expressed as a semicolon-delimited list enclosed in double quotes, that will be examined when attempting to locate PDBs.
-o, --output File path used to write and output analysis using SARIF
-r, --recurse [true|false] If true, recurse into subdirectories when evaluating file specifier arguments
-c, --config (Default: ‘default’) Path to policy file to be used to configure analysis. Passing value of 'default' (or omitting the argument) invokes built-in settings
-q, --quiet [true|false] If true, do not log results to the console
-s, --statistics Generate timing and other statistics for analysis session
--insert Optionally present data, expressed as a semicolon-delimited list enclosed in double quotes, that should be inserted into the log file. Valid values include Hashes, TextFiles, BinaryFiles, EnvironmentVariables, RegionSnippets, ContextRegionSnippets, ContextRegionSnippetPartialFingerprints, Guids, VersionControlDetails, and NondeterministicProperties.
-e, --environment [true|false]

If true, log machine environment details of run to output file.

WARNING: This option records potentially sensitive information (such as all environment variable values) to the log file.

-p, --plugin Paths to plugin, expressed as a semicolon-delimited list enclosed in double quotes, that will be invoked against all targets in the analysis set.
--rich-return-code [true|false] If true, output a more detailed exit code consisting of a series of flags about execution, rather than outputting '0' for success/'1' for failure (see codes below)
--level Failure levels, expressed as a semicolon-delimited list enclosed in double quotes, that is used to filter the scan results. Valid values: Error, Warning and Note.
--kind Result kinds, expressed as a semicolon-delimited list enclosed in double quotes, that is used to filter the scan results. Valid values: Fail (for literal scan results), Pass, Review, Open, NotApplicable and Informational.
--baseline A Sarif file to be used as baseline.
--help Table of argument information.
--version BinSkim version details.
value pos. 0 One or more specifiers to a file, directory, or filter pattern that resolves to one or more binaries to analyze.

Example: binskim.exe analyze c:\bld\*.dll --recurse true --output MyRun.sarif

binskim's People

Contributors

aleks-ivanov avatar connorcashmsft avatar danpere avatar davidknise avatar dependabot[bot] avatar disconnect3d avatar dmachaj avatar eddynaka avatar jameswinkler avatar kennienp avatar krwq avatar lingzhou-gh avatar lukehsiao avatar marmegh avatar michaelcfanning avatar microsoft-github-policy-service[bot] avatar msftgits avatar nguerrera avatar pabrookes avatar paddymcd-msft avatar pharring avatar rodsan avatar schlaman-ms avatar scovetta avatar shaopeng-gh avatar suvamm avatar thomsontan avatar toshipiazza avatar yanniwangannie avatar yongyan-gh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

binskim's Issues

Retry for Missing PDB on Remote Symbols Server

Multiple customers have run into transient issues loading symbols from a remote symbols server (for files which definitely have symbols published to the server)--a run will fail to find symbols once, but work later on.

Can we investigate if the underlying library contains automatic retries when it fails to load a .PDB? If it does not, it would likely be helpful to offer a command line option for retrying the lookup when the .PDB isn't found. (If the underlying library already retries, more retries is likely overkill.)

BinSkim should have better reporting for malformed args

Malformed command line tend to result in args that are improperly evaluated as file args. We should detect IO exceptions and add a useful message asking users to ensure args are properly quoted, that all switches have an expected arg value following it, etc.

We can only use some heuristics based on breaks we typically observe, due to dependency on CommandLineLibrary. Otherwise, we'd need to update the internals of that code to cover some new cases.

BinSkim cannot load PDBs for ildasm.exe even though they are present on Mcirosofts symbols servers

Hi

I am unable to implement BinSkim of my projects build output, because among the files it produces on our drop server, ildasm.exe is found. BinSkim issues an ExceptionLoadingPdb error:

binskim analyze ildasm.exe --sympath SRV*http://msdl.microsoft.com/download/symbols -v
Analyzing...
Analyzing 'ildasm.exe'...
[...]
error ERR997.ExceptionLoadingPdb : BA2006 : 'ildasm.exe' was not evaluated for check 'BuildWithSecureTools' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
[...]

One or more rules was disabled for an analysis target, as it was determined not to be applicable to it (this is a common condition). Pass --verbose on the command-line for more information.

Analysis did not complete due to one or more unrecoverable execution conditions.
Unexpected fatal runtime condition(s) observed: ExceptionLoadingPdb

I am able toto verify the binaries can be dfoudn on teh server
e:\rainfnd>\symbols\tools\x86\symchk.exe Source\Servicing\AXCreateDeployablePackageTool\AXCreateDeployablePackageBase\ildasm.exe /s SRV*http://msdl.microsoft.com/download/symbols /od
SYMCHK: ildasm.exe PASSED - PDB: ildasm.pdb DBG: <N/A>

SYMCHK: FAILED files = 0
SYMCHK: PASSED + IGNORED files = 1

What can I do to get BinSkim to find the symbols?

Thanks
Bo

Consider change to root namespace

Microsoft.CodeAnalysis collides directly with Roslyn root namespace. As it turns out, taking a dependency in this tool on Roslyn will create a name collision (with the Roslyn Location object).

PDB could not be loaded. (E_PDB_NOT_FOUND (File not found)) when we use --sympath.

pdb files are not loading when we use --sympath. if binary file and its respective pdb in the same path then pdb files getting loaded (with/without the attribute "--sympathy"). otherwise, binskim throwing below exception
error ERR997.ExceptionLoadingPdb : BA2006 : 'MyFile.dll' was not evaluated for check 'BuildWithSecureTools' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
error ERR997.ExceptionLoadingPdb : BA2014 : 'MyFile.dll' was not evaluated for check 'DoNotDisableStackProtectionForFunctions' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
error ERR997.ExceptionLoadingPdb : BA2002 : 'MyFile.dll' was not evaluated for check 'DoNotIncorporateVulnerableDependencies' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
error ERR997.ExceptionLoadingPdb : BA2007 : 'MyFile.dll' was not evaluated for check 'EnableCriticalCompilerWarnings' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
error ERR997.ExceptionLoadingPdb : BA2011 : 'MyFile.dll' was not evaluated for check 'EnableStackProtection' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))
error ERR997.ExceptionLoadingPdb : BA2013 : 'MyFile.dll' was not evaluated for check 'InitializeStackProtection' because its PDB could not be loaded. (E_PDB_NOT_FOUND (File not found))

Exit Code Differentiation

Current behavior: any error when running BinSkim, regardless of severity/etc., will give an exit code of '1'. This includes issues that often happen if you run the tool across products with rely on third party libraries, like not finding PDB files.

This makes it difficult to integrate the tool into other orchestration using the 'recurse' option--where we may expect to be missing private symbols for some libraries.

Expected behavior: Missing PDB files should be logged as an error, users integrating the tool should be able to differentiate that case from other errors via the exit code.

Sarif output should include runInfo.commandLineArguments.

According to the Sarif spec, the runInfo.commandLineArguments field is required. Current BinSkim output has this value as null.

Sarif Spec:

General { #runInfo-General }

A runInfo object describes the invocation of the static analysis tool that produced the issues specified
in the containing runLog object (§[#runLog]).

~ IsoNote
The information in the runInfo object makes it possible to precisely repeat a run of a static analysis tool,
and to verify that the issues reported in the log file were generated by an appropriate invocation of the tool.
~

commandLineArguments property { #runInfo-commandLineArguments }

A runInfo object shall contain a property named commandLineArguments whose value is a string
containing the command line arguments with which the tool was invoked.
This string shall not include the file name or path to the executable itself.

~ IsoExample
Suppose a tool is invoked with the command line

    C:\Tools\CodeScanner\CodeScanner.exe /input C:\Code\*.cc

Then the value of the commandLineArguments property should be "/input C:\Code\*.cc"."

Document policy file format

I'd like to setup binskim on our gated check-in builds.
In this builds we do not sign binaries as they are discarded.
Is it possible run binskim with policy that skips this check?
How to do it?
Command-Line Documentation say

-p, --policy Path to policy file that will be used to configure analysis. Pass value of 'default' to use built-in settings.

But how should policy file look like?

Thank you.
Palo Misik

recurse option does not work

I'm running the following (dlls I want to check are directly placed under bin directory):

BinSkim.exe analyze bin -c default -r --output BinSkim.report

And I get this error:

error ERR997.NoValidAnalysisTargets : No valid analysis targets were specified.

Analysis did not complete due to one or more unrecoverable execution conditions.
Unexpected fatal runtime condition(s) observed: NoValidAnalysisTargets

Migrate BinSkim to NET Core framework

Update signing layout to include a folder level that specifies codesign cert ID
e.g. bld\bin\LayoutForSigning<cert id>\net46\BinSkim.exe
This simplifies signing since we will be signing third-party assemblies with a different cert

Check that argument to --sympath is a directory

This command line throws E_PDB_NOT_FOUND:

binskim.exe analyze Skype.exe --sympath SkypeWithLib.pdb
    --recurse --config default --output MyRun7.sarif

The problem is that --sympath is supposed to specify a directory where symbol files can be found. The symbol file name must match the assembly name.

To avoid this unclear error message, check that the argument to --sympath is a directory, not a file.

Documentation Bugs

The readme.md file has some sections that should be shown monospaced, e.g.:

command line options here

The text also directs the user to run test.cmd, which I believe is now called BuildAndTest.cmd.

The command line example also omits the required analyze argument.

policy BA2006: nasm detected as masm

The policy BA2006 incorrectly assumes that .obj files built with NASM were built with MASM:

error: BA2006: 'x.dll' was compiled with one or more modules which were not built using minimum required tool versions (compiler version 17.0.65501.17016, linker version 11.0.65501.17016). More recent tool chains contain mitigations that make it more difficult for an attacker to exploit vulnerabilities in programs they produce. To resolve this issue, compile and/or link your binary with more recent tools. If you are servicing a product where the tool chain cannot be modified (e.g. producing a hotfix for an already shipped version) ignore this warning.
Modules built outside of policy:
aes-x86_64.obj built with MASM compiler version 8.0.26708.0 (Front end version 0.0.0.0)

These object files have been built with NASM 2.12.02 (http://www.nasm.us/)

Enable CFG - Check static libraries?

When you link your CFG-protected executable or DLL with a static library which was not compiled with /guard:cf then BinSkim will not report any issue. Flags are set, table exists. Still, if there is an indirect call in this linked library then it won't be protected. Calls to __guard_check_icall_fptr were not inserted during compilation time.

Is there any reasonable way how to extend this rule to cover also these false negatives? Maybe additional support for scanning COFF libs assuming this information could be checked there?

'exportConfig' requires an explicit filename and gives unhelpful errors

If you run BinSkim's 'exportConfig' command with a folder as the output location, you get an unhelpful exception.

For example, if you run it with the desktop folder:
.\BinSkim.exe exportConfig "C:\Users{username}\Desktop"
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users{username}\Desktop'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.StreamWriter.CreateFile(String path, Boolean append, Boolean checkHost)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize, Boolean checkHost)
at System.IO.File.InternalWriteAllText(String path, String contents, Encoding encoding, Boolean checkHost)
at Microsoft.CodeAnalysis.Sarif.Driver.ExportConfigurationCommandBase.Run(ExportConfigurationOptions exportOptions)


The workaround is to explicitly specify a full filename (e.x. "binskim.exe exportconfig C:\users{username}\Desktop\binskimconfig.json"). However, the current behavior isn't particularly user friendly.

Expected behavior: BinSkim should either chose a default filename to output to if given a folder (e.x. 'binskimconfig.json' or 'binskimconfig.xml'), or give a more helpful error message (e.x. "Error: Please specify a full file name, not a folder"), rather than throwing an exception.

Support for command line length limit extension

Users are encountering an issue with long sympaths, which ends up giving them an error. There is no support ticket currently associated with this, but the thread title is "Information about BinSkim error"

Check for QSpectre/d2guardspecload flags

Per: https://blogs.msdn.microsoft.com/vcblog/2018/01/15/spectre-mitigations-in-msvc/

New flags are being added to VC++ that add fence instructions to prevent spectre-style exploits (necessary if your application deals with data which crosses a trust boundary). It looks like they're only available in 2017.5 and 2017.6 for now, but ports are planned for 2017 RTM and 2015.3.

It'd be useful to detect their usage (we'll need to determine if symbols are/aren't necessary) and implement a check (possibly an experimental one, as these are very new?).

Suggested changes to rule messages

In the BinSkim rule descriptor output (binskim.rules.sarif.txt), I suggest:

Line 14: “Address Space Layour Randomization” (sp.)

Line 17: “increaseing the effectiveness” (sp.)

Line 17: “address space layout randomization” was capitalized on Line 14 but not here.

Line 29: “was built with a dependency on version of {1}” – did you mean “on a version of {1}”? or “on version {1} of {2}” (e.g., “on version 2.0 of Foo.exe”)?

Line 48: “in order to take advantage of” -- consider “to take advantage of” ;-) (and wherever that construction occurs)

Line 52: “built with a tool chain that satisfies…” – is “tool chain” our own jargon? How about “was built with tools that satisfy…”

Line 63: “… there is a greater likelihood that X, Y, and Z do not exist…” – consider “it is less likely that X, Y, and Z exist…”

ReleaseHistory.md is not in repo

I had made some changes in the IOperation dev branch to check the exit code at every step of BuildAndTest.cmd and upon integration from master, found nuget packaging is failing with:

File not found: '..\..\..\src\ReleaseHistory.md'.

@michaelcfanning

BinSkim -- Unclear output when PDBs not available

I ran BinSkim and Binscope against the same binary and found an important difference.

When BinScope doesn't find private symbols (and is therefore unable to perform various analyses), it fails that check with a message like:

<FILE> cannot be processed by ATLVersionCheck, because ATLVersionCheck requires private symbols which BinScope was not able to find next to the binary or on your symbol path (%_NT_SYMBOL_PATH% or /SymPath). The specific error generated by MSDIA while resolving symbols was: E_PDB_NOT_FOUND (File not found) Obtain matching private symbols for the binaries being tested and run BinScope again.

When BinSkim is run against the same binary, I see a more cryptic:

<FILE>: error BA2007: '<FILE>' contains code from an unknown language, preventing a comprehensive analysis of the compiler warning settings. The language could not be identified for the following modules: <file> ... 

<FILE>: error BA2011: '<FILE>' contains code from an unknown language, preventing a comprehensive analysis of the stack protector buffer security features. The language could not be identified for the following modules: <file> ...

Analysis finished but was not complete due to non-fatal runtime errors.
Unexpected runtime condition(s) observed: RuleNotApplicableToTarget

Are these error messages "the same" -- if so, can the user be given more information (and direction to include symbol files)? Without this, the user will be more likely to think they "passed" -- under the presumption that no output is "good".

Abbreviated switches do not work

Repro:

BinSkim.exe analyze bin -p default -r -o binskim.report

Result:

Unhandled Exception: System.InvalidOperationException: Sequence contains more than one matching element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at CommandLine.Core.TypeLookup.FindTypeDescriptorAndSibling(String name, IEnumerable`1 specifications, StringComparer comparer)
   at CommandLine.Core.Switch.<>c__DisplayClass0_0.<Partition>b__0(Token t)
   at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at CSharpx.EnumerableExtensions.Memorize[T](IEnumerable`1 source)
   at CommandLine.Core.TokenPartitioner.Partition(IEnumerable`1 tokens, Func`2 typeLookup)
   at CommandLine.Core.InstanceBuilder.<>c__DisplayClass0_0`1.<Build>b__7()
   at CommandLine.Core.InstanceChooser.MatchVerb(Func`3 tokenizer, IEnumerable`1 verbs, IEnumerable`1 arguments, StringComparer nameComparer, CultureInfo parsingCulture, IEnumerable`1 nonFatalErrors)
   at CommandLine.Core.InstanceChooser.<>c__DisplayClass0_0.<Choose>b__0()
   at CommandLine.Parser.ParseArguments(IEnumerable`1 args, Type[] types)
   at Microsoft.CodeAnalysis.IL.BinSkim.Main(String[] args)

(expanded version of them works)

Enable Binskim to generate proper PDB files on WiX toolset generated binaries

BinSkim isn’t able to properly evaluate its checks against a WiX-toolset generated executable because it does not build valid private symbols. Without these private symbols, developers cannot find out the C++ compiler version used, whether a WiX link contains vulnerable ATL libraries or if stack protection is enabled.

Update shortDescriptions

Most rules have a leading sentence that is an effective shortDescription. For several, we could trim some details around security justification in order to simply capture the prescriptive guidance.

The first sentence of BA2016, for example, is this:

Binaries should be marked as NX compatible in order to help prevent execution of untrusted data as code.

This could be reduced to the following rule abstract:

Binaries should be marked as NX compatible.

Provide opt-in mechanis for review/auditing messages

For notifications that users have disabled specific mitigations at the function/etc level (via #pragma or declspec). Ideally, these notifications would be visible in logs/output by default but not break the build/return an error code. We can use the rich error result mechanism for this. We should propose a new 'audit' or 'review' designation to the SARIF design team.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.