Update: This post is a little bit out-of-date in regards to using the PowerShell script. Refer to the Github repo (https://github.com/NetSPI/PEchecker) for an updated script and instructions on how to use it. Today I am releasing a PowerShell script that easily displays whether images (DLLs and EXEs) are compiled with ASLR (Address Space Layout Randomization), DEP (Data Execution Prevention), and SafeSEH (Structured Exception Handling). It is located at the github repo here: https://github.com/NetSPI/PEchecker. Without going into much detail, ASLR, DEP, and SafeSEH are considered best practices for all developers to implement as they help protect against users exploiting insecure code. As a side note, SafeSEH is only available when linking 32bit images. There are a few solutions out there that do this already, namely PEStudio, CFFExplorer, Windbg with plugins, and Immunity Debugger with mona.py. However, I find that each of these are inefficient for scanning multiple files. PowerShell is a great solution for this because it is a native tool and can tap into the Windows API and carve out information within files. What I’m interested in are the PE (Portable Executable) headers within compiled 32bit and 64bit images. In simplistic terms, PE Headers contain all the information needed by Windows to run compiled images. Within PE headers there is an Optional Section that contains the DLLCharacteristics member. The DLLCharacteristic member is a hex value that provides information for compiled options in a file. It is set to the additive hex values contained in the following table:
|IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE0x0040||The DLL can be relocated at load time.|
|IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY0x0080||Code integrity checks are forced. If you set this flag and a section contains only uninitialized data, set thePointerToRawDatamember of IMAGE_SECTION_HEADERfor that section to zero; otherwise, the image will fail to load because the digital signature cannot be verified.|
|IMAGE_DLLCHARACTERISTICS_NX_COMPAT0x0100||The image is compatible with data execution prevention (DEP).|
|IMAGE_DLLCHARACTERISTICS_NO_ISOLATION0x0200||The image is isolation aware, but should not be isolated.|
|IMAGE_DLLCHARACTERISTICS_NO_SEH0x0400||The image does not use structured exception handling (SEH). No handlers can be called in this image.|
|IMAGE_DLLCHARACTERISTICS_NO_BIND0x0800||Do not bind the image.|
|IMAGE_DLLCHARACTERISTICS_WDM_DRIVER0x2000||A WDM driver.|
|IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE0x8000||The image is terminal server aware.|
This table is from Microsoft and is located here (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx). You can see in the table that there are values pertaining to the status of ASLR (IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE), DEP (IMAGE_DLLCHARACTERISTICS_NX_COMPAT), and SEH (IMAGE_DLLCHARACTERISTICS_NO_SEH) for a compiled image. Common DLLCharacteristics values are 140 for ASLR, DEP, and SEH, and 400 for no ASLR, DEP, and SEH. If IMAGE_DLLCHARACTERISTICS_NO_SEH is true then there is no SEH and SafeSEH is not needed. As stated before, SafeSEH is only available for 32bit images. SafeSEH can also only be used if every linked module supports it. To verify SafeSEH we need to look at the SafeSEH fields which reside in the IMAGE_LOAD_CONFIG_DIRECTORY section of a PE. Within this structure are the SEHandlerTable, which holds the virtual address of a table of relative virtual addresses for each valid handler, and the SEHandlerCount, which is the number of handlers in the valid handler table from SEHandlerTable. If SafeSEH is not used, these members and sometimes the IMAGE_LOAD_CONFIG_DIRECTORY section itself will be empty.
Note: The name of the script has been change to Check-PESecurity.ps1. All of the flags still work correctly. The PEchecker PowerShell script utilizes C# code to create the relevant structs needed for the PE Header format. A big thank you to the PowerSploit project (https://github.com/mattifestation/PowerSploit) and the Get-PEHeader script for providing a lot of insight into doing this. PEchecker provides a lot of functionality. To begin, I will show how to look at a single file. Using the command:
Get-PESecurity –file "filename"
We can see a list view of the current file with the filename, architecture, and whether it is compiled with ASLR, DEP, and SafeSEH: We can turn this into a table in PowerShell by piping it to the format-table function. Next we can use the directory switch to scan an entire directory of files for DLLs and EXEs.
Get-PESecurity –directory "directory"
The directory command also has support for recusing through directories. To do this simply add the recursive switch:
Get-PESecurity –directory "directory" –recursive
I also added in support for filtering files based on ASLR, DEP, and SafeSEH. To do this, use the following switches: -OnlyNoASLR -OnlyNoDEP -OnlyNoSafeSeH A great piece of functionality in PowerShell is being able to export csv files from our results. To do this run the following command:
Get-PESecurity –directory "directory" –recursive | Export-Csv output.csv