1 #
2 # Get-HardenFlags - Checks hardening flags on the binaries.
3 #
4 # Copyright 2015 Graham Bloice <graham.bloice@trihedral.com>
5 #
6 # Wireshark - Network traffic analyzer
7 # By Gerald Combs <gerald@wireshark.org>
8 # Copyright 1998 Gerald Combs
9 #
10 # SPDX-License-Identifier: GPL-2.0-or-later
11 
12 #requires -version 2
13 
14 # Get-HardenFlags does:
15 #   call the dumpbin utility to get the binary header flags
16 #   on all the binaries in the distribution, and then filters
17 #   for the NXCOMPAT and DYNAMICBASE flags.
18 
19 # This script will probably fail for the forseeable future.
20 #
21 # Many of our third-party libraries are compiled using MinGW-w64. Its version
22 # of `ld` doesn't enable the dynamicbase, nxcompat, or high-entropy-va flags
23 # by default. When you *do* pass --dynamicbase it strips the relocation
24 # section of the executable:
25 #
26 #   https://sourceware.org/bugzilla/show_bug.cgi?id=19011
27 #
28 # As a result, none of the distributions that produce Windows applications
29 # and libraries have any sort of hardening flags enabled:
30 #
31 #   https://mingw-w64.org/doku.php/download
32 #
33 
34 <#
35 .SYNOPSIS
36 Checks the NXCOMPAT and DYNAMICBASE flags on all the binaries.
37 
38 .DESCRIPTION
39 This script downloads and extracts third-party libraries required to compile
40 Wireshark.
41 
42 .PARAMETER BinaryDir
43 Specifies the directory where the binaries may be found.
44 
45 .INPUTS
46 -BinaryDir Directory containing the binaries to be checked.
47 
48 .OUTPUTS
49 Any binary that doesn't have the flags is written to the error stream
50 
51 .EXAMPLE
52 C:\PS> .\tools\Get-HardenFlags.ps1 -BinaryDir run\RelWithDebInfo
53 #>
54 
55 Param(
56     [Parameter(Mandatory=$true, Position=0)]
57     [String]
58     $BinaryDir
59 )
60 
61 # Create a list of 3rd party binaries that are not hardened
62 $SoftBins = (
63     "libpixmap.dll",
64     "libwimp.dll",
65     "libgail.dll",
66     "airpcap.dll",
67     "comerr32.dll",
68     "k5sprt32.dll",
69     "krb5_32.dll",
70     "libatk-1.0-0.dll",
71     "libcairo-2.dll",
72     "libffi-6.dll",
73     "libfontconfig-1.dll",
74     "libfreetype-6.dll",
75     "libgcc_s_sjlj-1.dll",
76     "libgcrypt-20.dll",
77     "libgdk-win32-2.0-0.dll",
78     "libgdk_pixbuf-2.0-0.dll",
79     "libgio-2.0-0.dll",
80     "libglib-2.0-0.dll",
81     "libgmodule-2.0-0.dll",
82     "libgmp-10.dll",
83     "libgnutls-28.dll",
84     "libgobject-2.0-0.dll",
85     "libgpg-error-0.dll",
86     "libgtk-win32-2.0-0.dll",
87     "libharfbuzz-0.dll",
88     "libhogweed-2-4.dll",
89     "libintl-8.dll",
90     "libjasper-1.dll",
91     "libjpeg-8.dll",
92     "liblzma-5.dll",
93     "libmaxminddb.dll",
94     "libnettle-4-6.dll",
95     "libp11-kit-0.dll",
96     "libpango-1.0-0.dll",
97     "libpangocairo-1.0-0.dll",
98     "libpangoft2-1.0-0.dll",
99     "libpangowin32-1.0-0.dll",
100     "libpixman-1-0.dll",
101     "libpng15-15.dll",
102     "libtasn1-6.dll",
103     "libtiff-5.dll",
104     "libxml2-2.dll",
105 # The x64 ones that are different
106     "comerr64.dll",
107     "k5sprt64.dll",
108     "krb5_64.dll",
109     "libgcc_s_seh-1.dll",
110     "libgpg-error6-0.dll",
111     "libpng16-16.dll",
112 # Unfortunately the nsis uninstaller is not hardened.
113     "uninstall.exe"
114 )
115 
116 # CD into the bindir, allows Resolve-Path to work in relative mode.
117 Push-Location $BinaryDir
118 [Console]::Error.WriteLine("Checking in $BinaryDir for unhardened binaries:")
119 
120 # Retrieve the list of binaries.  -Filter is quicker than -Include, but can only handle one item
121 $Binaries = Get-ChildItem -Path $BinaryDir -Recurse -Include *.exe,*.dll
122 
123 # Number of "soft" binaries found
124 $Count = 0;
125 
126 # Iterate over the list
127 $Binaries | ForEach-Object {
128 
129     # Get the flags
130     $flags = dumpbin $_ /HEADERS;
131 
132     # Check for the required flags
133     $match = $flags | Select-String -Pattern "NX compatible", "Dynamic base"
134     if ($match.Count -ne 2) {
135 
136         # Write-Error outputs error records, we simply want the filename
137         [Console]::Error.WriteLine((Resolve-Path $_ -Relative))
138 
139         # Don't count files that won't ever be OK
140         if ($SoftBins -notcontains (Split-Path $_ -Leaf)) {
141             $Count++
142         }
143     }
144 }
145 
146 exit $Count
147