winchecksec
performs static detection of common Windows security features.
The following security features are currently detected:
- ASLR:
/DYNAMICBASE
with stripped relocation entries edge-case/HIGHENTROPYVA
for 64-bit systems
- Code integrity/signing:
/INTEGRITYCHECK
- Authenticode-signed with a valid (trusted, active) certificate (currently unsupported on Linux)
- DEP (a.k.a. W^X, NX)
- Manifest isolation via (
/ALLOWISOLATION
) - Structured Exception Handling and SafeSEH support
- Control Flow Guard and Return Flow Guard instrumentation
- Stack cookie (
/GS
) support
winchecksec
depends on pe-parse and
uthenticode, which can be installed via vcpkg
:
$ vcpkg install pe-parse uthenticode
NOTE: On Windows, vcpkg
defaults to 32-bit builds. If you're doing a 64-bit winchecksec
build, you'll need to explicitly build the dependencies as 64-bit:
$ vcpkg install pe-parse:x64-windows uthenticode:x64-windows
$ git clone https://github.com/trailofbits/winchecksec.git
$ cd winchecksec
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .
$ ./build/winchecksec
> git clone https://github.com/trailofbits/winchecksec.git
> cd winchecksec
> mkdir build
> cd build
> cmake ..
> cmake --build . --config Release
> .\Release\winchecksec.exe C:\Windows\notepad.exe
As a command-line tool, winchecksec
has two output modes: a plain-text mode for easy reading,
and a JSON mode for consumption in other programs. The plain-text mode is the default; JSON output
is enabled by passing --json
or -j
:
> .\Release\winchecksec.exe C:\Windows\notepad.exe
Dynamic Base : "Present"
ASLR : "Present"
High Entropy VA : "Present"
Force Integrity : "NotPresent"
Isolation : "Present"
NX : "Present"
SEH : "Present"
CFG : "NotPresent"
RFG : "NotPresent"
SafeSEH : "NotApplicable"
GS : "Present"
Authenticode : "NotPresent"
.NET : "NotPresent"
> .\Release\winchecksec.exe -j C:\Windows\notepad.exe
[{
"path": "C:\\Windows\\notepad.exe",
"mitigations": {
"dynamicBase": {
"presence": "Present",
"description": "Binaries with dynamic base support can be dynamically rebased, enabling ASLR."
},
"rfg": {
"description": "Binaries with RFG enabled have additional return-oriented-programming protections.",
"presence": "NotPresent"
},
"seh": {
"description": "Binaries with SEH support can use structured exception handlers.",
"presence": "Present"
},
// ...
}
}]
winchecksec
also provides a C++ API; documentation is hosted
here.
winchecksec
is formatted with clang-format
. You can use the clang-format
target to
auto-format it locally:
$ make clang-format
winchecksec
also comes with a suite of unit tests that use
pegoat as a reference for various security mitigations.
To build the unit tests, pass -DBUILD_TESTS=1
to the CMake build.
Prevalence of various security features on a vanilla Windows 10 (1803) installation:
aslr | authenticode | cfg | dynamicBase | forceIntegrity | gs | highEntropyVA | isolation | nx | rfg | safeSEH | seh |
---|---|---|---|---|---|---|---|---|---|---|---|
79% | 37% | 49% | 79% | 3% | 65% | 43% | 100% | 79% | 6% | 25% | 91% |