Get-HardenFlags.ps1 4.45 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#
# Get-HardenFlags - Checks hardening flags on the binaries.
#
# Copyright 2015 Graham Bloice <graham.bloice@trihedral.com>
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# Copyright 1998 Gerald Combs
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#requires -version 2

# Get-HardenFlags does:
#   call the dumpbin utility to get the binary header flags
#   on all the binaries in the distribution, and then filters
#   for the NXCOMPAT and DYNAMICBASE flags.

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
# This script will probably fail for the forseeable future.
#
# Many of our third-party libraries are compiled using MinGW-w64. Its version
# of `ld` doesn't enable the dynamicbase, nxcompat, or high-entropy-va flags
# by default. When you *do* pass --dynamicbase it strips the relocation
# section of the executable:
#
#   https://sourceware.org/bugzilla/show_bug.cgi?id=19011
#
# As a result, none of the distributions that produce Windows applications
# and libraries have any sort of hardening flags enabled:
#
#   http://mingw-w64.org/doku.php/download
#

46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
<#
.SYNOPSIS
Checks the NXCOMPAT and DYNAMICBASE flags on all the binaries.

.DESCRIPTION
This script downloads and extracts third-party libraries required to compile
Wireshark.

.PARAMETER BinaryDir
Specifies the directory where the binaries may be found.

.INPUTS
-BinaryDir Directory containing the binaries to be checked.

.OUTPUTS
Any binary that doesn't have the flags is written to the error stream

.EXAMPLE
C:\PS> .\tools\Get-HardenFlags.ps1 -BinaryDir run\RelWithDebInfo
#>

Param(
    [Parameter(Mandatory=$true, Position=0)]
    [String]
    $BinaryDir
)

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
# Create a list of 3rd party binaries that are not hardened
$SoftBins = (
    "libpixmap.dll",
    "libwimp.dll",
    "libgail.dll",
    "airpcap.dll",
    "comerr32.dll",
    "k5sprt32.dll",
    "krb5_32.dll",
    "libatk-1.0-0.dll",
    "libcairo-2.dll",
    "libffi-6.dll",
    "libfontconfig-1.dll",
    "libfreetype-6.dll",
    "libgcc_s_sjlj-1.dll",
    "libgcrypt-20.dll",
    "libgdk-win32-2.0-0.dll",
    "libgdk_pixbuf-2.0-0.dll",
    "libGeoIP-1.dll",
    "libgio-2.0-0.dll",
    "libglib-2.0-0.dll",
    "libgmodule-2.0-0.dll",
    "libgmp-10.dll",
    "libgnutls-28.dll",
    "libgobject-2.0-0.dll",
    "libgpg-error-0.dll",
    "libgtk-win32-2.0-0.dll",
    "libharfbuzz-0.dll",
    "libhogweed-2-4.dll",
    "libintl-8.dll",
    "libjasper-1.dll",
    "libjpeg-8.dll",
    "liblzma-5.dll",
    "libnettle-4-6.dll",
    "libp11-kit-0.dll",
    "libpango-1.0-0.dll",
    "libpangocairo-1.0-0.dll",
    "libpangoft2-1.0-0.dll",
    "libpangowin32-1.0-0.dll",
    "libpixman-1-0.dll",
    "libpng15-15.dll",
    "libtasn1-6.dll",
    "libtiff-5.dll",
    "libxml2-2.dll",
117 118 119 120 121 122 123
# The x64 ones that are different
    "comerr64.dll",
    "k5sprt64.dll",
    "krb5_64.dll",
    "libgcc_s_seh-1.dll",
    "libgpg-error6-0.dll",
    "libpng16-16.dll",
124 125 126 127
# Unfortunately the nsis uninstaller is not hardened.
    "uninstall.exe"
)

128
# CD into the bindir, allows Resolve-Path to work in relative mode.
129 130
Push-Location $BinaryDir
[Console]::Error.WriteLine("Checking in $BinaryDir for unhardened binaries:")
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

# Retrieve the list of binaries.  -Filter is quicker than -Include, but can only handle one item
$Binaries = Get-ChildItem -Path $BinaryDir -Recurse -Include *.exe,*.dll

# Number of "soft" binaries found
$Count = 0;

# Iterate over the list
$Binaries | ForEach-Object {

    # Get the flags
    $flags = dumpbin $_ /HEADERS;

    # Check for the required flags
    $match = $flags | Select-String -Pattern "NX compatible", "Dynamic base"
    if ($match.Count -ne 2) {

        # Write-Error outputs error records, we simply want the filename
        [Console]::Error.WriteLine((Resolve-Path $_ -Relative))

151 152 153 154
        # Don't count files that won't ever be OK
        if ($SoftBins -notcontains (Split-Path $_ -Leaf)) {
            $Count++
        }
155 156 157
    }
}

158
exit $Count