├── LICENSE ├── PowerHunt.psm1 ├── README.md ├── Report-Template-v1.html └── windows └── modules ├── analysis ├── search │ ├── analyze-003-01-events-1102.ps1 │ ├── analyze-003-02-events-4732-add-user-by-remotecomputer.ps1 │ ├── analyze-003-02-events-4732-add-user-by-workgroup.ps1 │ ├── analyze-003-02-events-4732-add-user-computeraccount.ps1 │ ├── analyze-003-02-events-4732-add-user.ps1 │ ├── analyze-003-02-events-4732.ps1 │ ├── analyze-005-01-installed-software-mgmt.ps1 │ ├── analyze-005-01-installed-software-offsec.ps1 │ ├── analyze-007-01named-pipes-known-bad.ps1 │ ├── analyze-011-01-services-badpath.ps1 │ ├── analyze-011-01-services-dotnet.ps1 │ ├── analyze-011-01-services-lolbas.ps1 │ ├── analyze-011-01-services-mgmt-software.ps1 │ ├── analyze-011-01-services-offsec-software.ps1 │ ├── analyze-011-01-services-outlier-file-owner.ps1 │ ├── analyze-011-01-services-unsigned.ps1 │ ├── analyze-012-01-startup-files-allusers-dotnet.ps1 │ ├── analyze-012-01-startup-files-allusers-lolbas.ps1 │ ├── analyze-012-01-startup-files-allusers-mgmt-software.ps1 │ ├── analyze-012-01-startup-files-allusers-offsec-software.ps1 │ ├── analyze-012-01-startup-files-allusers-outlier-file-owner.ps1 │ ├── analyze-012-01-startup-files-allusers-unsigned.ps1 │ ├── analyze-013-01-startup-registry-run-badpath.ps1 │ ├── analyze-013-01-startup-registry-run-dotnet.ps1 │ ├── analyze-013-01-startup-registry-run-lolbas.ps1 │ ├── analyze-013-01-startup-registry-run-mgmt-software.ps1 │ ├── analyze-013-01-startup-registry-run-offsec-software.ps1 │ ├── analyze-013-01-startup-registry-run-outlier-file-owner.ps1 │ ├── analyze-013-01-startup-registry-run-unsigned.ps1 │ ├── analyze-014-01-tasks-dotnet.ps1 │ ├── analyze-014-01-tasks-lolbas.ps1 │ ├── analyze-014-01-tasks-mgmt-software.ps1 │ ├── analyze-014-01-tasks-offsec-software.ps1 │ ├── analyze-014-01-tasks-outlier-file-owner.ps1 │ ├── analyze-014-01-tasks-unsigned.ps1 │ └── analyze-016-01-wmi-bindings-creatorsid.ps1 └── stack │ ├── analyze-001-01-connections-process-paths.ps1 │ ├── analyze-001-01-connections-remote-address.ps1 │ ├── analyze-005-01-installed-software.ps1 │ ├── analyze-007-01-named-pipes.ps1 │ ├── analyze-009-01-processes.ps1 │ ├── analyze-011-01-services.ps1 │ ├── analyze-012-01-startup-files-allusers.ps1 │ ├── analyze-013-01-startup-registry-run.ps1 │ ├── analyze-014-01-tasks.ps1 │ ├── analyze-016-01-wmi-bindings.ps1 │ └── analyze-017-01-wmi-providers.ps1 ├── collection ├── collect-001-01-connections.ps1 ├── collect-002-01-environmental-paths.ps1 ├── collect-002-02-environmental-variables.ps1 ├── collect-003-01-events-1102.ps1 ├── collect-003-02-events-4732.ps1 ├── collect-004-01-groups.ps1 ├── collect-004-02-group-members.ps1 ├── collect-005-01-installed-software.ps1 ├── collect-005-02-installed-software-antispyware.ps1 ├── collect-005-03-installed-software-antivirus.ps1 ├── collect-005-04-installed-software-firewall.ps1 ├── collect-006-01-mapped-drives.ps1 ├── collect-007-01-named-pipes.ps1 ├── collect-008-01-network-interfaces.ps1 ├── collect-009-01-processes.ps1 ├── collect-010-01-protocol-handlers.ps1 ├── collect-011-01-services.ps1 ├── collect-012-01-startup-files-allusers.ps1 ├── collect-013-01-startup-registry-run.ps1 ├── collect-014-01-tasks.ps1 ├── collect-015-01-users.ps1 ├── collect-016-01-wmi-bindings.ps1 ├── collect-016-02-wmi-consumers.ps1 ├── collect-016-03-wmi-filters.ps1 └── collect-017-04-wmi-providers.ps1 └── lists ├── list-default-users.txt ├── list-lolbas.txt ├── list-loldrivers.txt ├── list-mgmt-strings.txt ├── list-offsec-software.txt └── list-rmm.csv /LICENSE: -------------------------------------------------------------------------------- 1 | Invoke-HuntPersistPR is provided under the 3-clause BSD license below. 2 | 3 | ************************************************************* 4 | 5 | Copyright (c) 2024, NetSPI 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of Invoke-HuntPersistPR nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerHunt 2 | PowerHunt is a modular threat hunting framework written in PowerShell that leverages PowerShell Remoting for data collection at scale.

3 | It is designed to identify signs of compromise based on artifacts left behind by common MITRE ATT&CK techniques, and the collected data can be used to identify anomalies and outliers specific to the target environment. It was not designed to identify known bad files, domains, or IPs associated with specific APTs/malware, but I'm sure it could be extended to do that. 4 | 5 | It supports functionality to: 6 | * Authenticate using the current user context, a credential, or clear text user/password. 7 | * Discover accessible systems associated with an Active Directory domain automatically. 8 | * Target a single computer, list of computers, or discovered Active Directory computers (default). 9 | * Collect data source information from target systems using PowerShell Remoting and easy to build collection modules. 10 | * Analyze collected data using easy to build analysis modules based on behavior. 11 | * Report summary data and initial insights that can help analysts get started on simple threat hunting exercises that focus on common persistence and related techniques. 12 | 13 | This is not a novel approach to threat hunting, but I thought the project was worth sharing, because in certain environments the automation can be a time saver.

14 | User and developer guides can be found on the wiki here.
15 | 16 | Author
17 | Scott Sutherland (@_nullbind)
18 | 19 | License
20 | BSD 3-Clause 21 | 22 | Primary Todo 23 | -- 24 | **Pending Fixes / Higher Priorities** 25 | * Create an HTML summary report (summary for discovery(sample), collection, analysis; main page for each with dig in html files) 26 | * Fix groups and user collection on 2008 ps3 vs ps5 - function used are not backwards compatable 27 | * Fix cast error in field for wmi bindings modules 28 | * Update $AnalysisModuleDesc in each analysis module to include correct description. 29 | * Review events for potential additions https://github.com/ANSSI-FR/guide-journalisation-microsoft/blob/main/Standard_WEC_query.xml 30 | 31 | **Pending Features / Modules** 32 | 33 | Remote Collection Methods 34 | * WMI 35 | * SMB/RPC - Create Service 36 | * SMB/RPC - Create Scheduled Task 37 | * SMB/RCP - Remote registry 38 | 39 | Artifact Collection 40 | * Add RDP session collection 41 | * Add PS remoting session collection 42 | * Add netsess session collection 43 | * Add Pcap ingestion 44 | * Add Drivers installed 45 | * Add ransomware artifcats (files/reg keys/recovery removal) 46 | 47 | Analysis / Core 48 | * Add contextual LOLBAS process checks 49 | * Update LOLBAS list for persistence checks 50 | * Add https://www.loldrivers.io/ checks 51 | * Add parent / child rules for processes 52 | * Add network connection rules for processes 53 | * Add thresholds to all anomaly modules - make configurable. 54 | * Sigma rules ingestion. 55 | * Add hidden task hunter 56 | 57 | Report. 58 | * Excludede DC option. 59 | * Create square chart, with color desity associated with instances per subnets/system 60 | * Heat map chart. 61 | * Timeline chart. 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-01-events-1102.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-1102 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | # Save result summary 12 | $AnalysisModuleFileName = $_.name -replace(".ps1","-counts.csv") 13 | $FinalOutput = $CollectedData 14 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 15 | 16 | # Count instances 17 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 18 | 19 | # Count affected computers 20 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 21 | 22 | # Save summary metrics 23 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 24 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-02-events-4732-add-user-by-remotecomputer.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-4732-add-user-remotecomputer 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. This filters for instances of logs that show the member was added from a remote computer. 7 | # a.k.a the local system name does not match the subject used to add the member to the group. 8 | # License: 3-clause BSD 9 | 10 | $AnalysisModuleDesc = "Place holder description." 11 | 12 | 13 | # The local system name does not match the subject used to add the member to the group. 14 | $FinalOutput = $CollectedData | 15 | foreach { 16 | 17 | # Check if a computer account was used to add the user to the group 18 | if ($_.SubjectUser -like "*`$"){ 19 | 20 | # Parse computer and computer account 21 | $ComputerName = $_.ComputerName.split(".")[0] 22 | $ComputerAccount = $_.SubjectUser.split('$')[0] 23 | 24 | # Check if the remote computer and computer account used to add account match 25 | if($ComputerName -notlike $ComputerAccount){ 26 | "rare we have a MISmatch" 27 | $_ 28 | } 29 | } 30 | } 31 | 32 | # Save result details 33 | $AnalysisModuleFileName = $_.name -replace(".ps1",".csv") 34 | $Time = Get-Date -UFormat "%m/%d/%Y %R" 35 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 36 | 37 | # Count instances 38 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 39 | 40 | # Count affected computers 41 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 42 | 43 | # Save summary metrics 44 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 45 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-02-events-4732-add-user-by-workgroup.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-4732-add-user-by-workgroup 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. This filters for user additions that have been made where the subject domain is "workgroup". 7 | # In lab environments the appear to be associated with the addition of member from local system. However, testing need to be done to determine if group 8 | # policy additions have the same profile. 9 | # License: 3-clause BSD 10 | 11 | $AnalysisModuleDesc = "Place holder description." 12 | 13 | # Member add to local security group with subject of workgroup 14 | $FinalOutput = $CollectedData | where SubjectUserDomain -like "*workgroup*" | Where PrincipalName -notlike "*Domain Admins*" 15 | 16 | # Save result details 17 | $AnalysisModuleFileName = $_.name -replace(".ps1",".csv") 18 | $Time = Get-Date -UFormat "%m/%d/%Y %R" 19 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 20 | 21 | # Count instances 22 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 23 | 24 | # Count affected computers 25 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 26 | 27 | # Save summary metrics 28 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 29 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-02-events-4732-add-user-computeraccount.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-4732-add-user-computer 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. This filters for computer accounts they may have been added to the local administrators group. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | # Potential Computer account added to group 12 | $FinalOutput = $CollectedData | where PrincipalName -like "*`$" 13 | 14 | # Save result details 15 | $AnalysisModuleFileName = $_.name -replace(".ps1",".csv") 16 | $Time = Get-Date -UFormat "%m/%d/%Y %R" 17 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 18 | 19 | # Count instances 20 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 21 | 22 | # Count affected computers 23 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 24 | 25 | # Save summary metrics 26 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 27 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-02-events-4732-add-user.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-4732-add-user 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | # Potential Computer account added to group 12 | $FinalOutput = $CollectedData | where PrincipalName -like "*`$" 13 | 14 | # Save result details 15 | $AnalysisModuleFileName = $_.name -replace(".ps1",".csv") 16 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 17 | 18 | # Count instances 19 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 20 | 21 | # Count affected computers 22 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 23 | 24 | # Save summary metrics 25 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 26 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-003-02-events-4732.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-events-4732-count 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | 12 | # Save result summary 13 | $AnalysisModuleFileName = $_.name -replace(".ps1","-counts.csv") 14 | $FinalOutput = $CollectedData 15 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 16 | 17 | # Count instances 18 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 19 | 20 | # Count affected computers 21 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 22 | 23 | # Save summary metrics 24 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 25 | -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-005-01-installed-software-mgmt.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-005-01-installed-software-mgmt.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-005-01-installed-software-offsec.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-005-01-installed-software-offsec.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-007-01named-pipes-known-bad.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-007-01named-pipes-known-bad.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-badpath.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-badpath.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-dotnet.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-dotnet.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-lolbas.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-lolbas.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-mgmt-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-mgmt-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-offsec-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-offsec-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-outlier-file-owner.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-outlier-file-owner.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-011-01-services-unsigned.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-011-01-services-unsigned.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-dotnet.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-dotnet.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-lolbas.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-lolbas.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-mgmt-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-mgmt-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-offsec-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-offsec-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-outlier-file-owner.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-outlier-file-owner.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-012-01-startup-files-allusers-unsigned.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-012-01-startup-files-allusers-unsigned.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-badpath.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-badpath.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-dotnet.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-dotnet.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-lolbas.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-lolbas.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-mgmt-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-mgmt-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-offsec-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-offsec-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-outlier-file-owner.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-outlier-file-owner.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-013-01-startup-registry-run-unsigned.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-013-01-startup-registry-run-unsigned.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-dotnet.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-dotnet.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-lolbas.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-lolbas.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-mgmt-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-mgmt-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-offsec-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-offsec-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-outlier-file-owner.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-outlier-file-owner.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-014-01-tasks-unsigned.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/search/analyze-014-01-tasks-unsigned.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/search/analyze-016-01-wmi-bindings-creatorsid.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-wmi-bindings-creatorsid 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | 12 | # Save result summary 13 | $AnalysisModuleFileName = $_.name -replace(".ps1","-counts.csv") 14 | $FinalOutput = $CollectedData | group BindingCreatorSid | Sort-Object count -Descending | select count,name 15 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 16 | 17 | # Count instances 18 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 19 | 20 | # Count affected computers 21 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 22 | 23 | # Save summary metrics 24 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-001-01-connections-process-paths.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-connections-process-paths 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | 12 | # Save result summary 13 | $AnalysisModuleFileName = $_.name -replace(".ps1","ProcessPath-counts.csv") 14 | $FinalOutput = $CollectedData | group FilePath | Sort-Object count -Descending | select count,name 15 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 16 | 17 | # Count instances 18 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 19 | 20 | # Count affected computers 21 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 22 | 23 | # Save summary metrics 24 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 25 | -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-001-01-connections-remote-address.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-connections-remote-address 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | 12 | # Save result summary 13 | $AnalysisModuleFileName = $_.name -replace(".ps1","RemoteAddress-counts.csv") 14 | $FinalOutput = $CollectedData | group RemoteAddress | Sort-Object count -Descending | select count,name 15 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 16 | 17 | # Count instances 18 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 19 | 20 | # Count affected computers 21 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 22 | 23 | # Save summary metrics 24 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") 25 | -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-005-01-installed-software.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-005-01-installed-software.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-007-01-named-pipes.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-007-01-named-pipes.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-009-01-processes.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-009-01-processes.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-011-01-services.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-011-01-services.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-012-01-startup-files-allusers.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-012-01-startup-files-allusers.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-013-01-startup-registry-run.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-013-01-startup-registry-run.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-014-01-tasks.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-014-01-tasks.ps1 -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-016-01-wmi-bindings.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Script : Invoke-PowerHunt 3 | # Module : analyze-wmi-bindings 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | $AnalysisModuleDesc = "Place holder description." 10 | 11 | 12 | # Save result summary 13 | $AnalysisModuleFileName = $_.name -replace(".ps1","-counts.csv") 14 | $FinalOutput = $CollectedData | group __PATH | Sort-Object count -Descending | select count,name 15 | $FinalOutput | Export-Csv -NoTypeInformation "$OutputDirectory\analysis\$AnalysisSubDir\Hunt-$AnalysisModuleFileName" 16 | 17 | # Count instances 18 | $InstanceCount = $FinalOutput | measure | select count -expandproperty count 19 | 20 | # Count affected computers 21 | $AnalysisModuleAffectedComputerCount = $FinalOutput | select PSComputerName -Unique | measure | select count -ExpandProperty count 22 | 23 | # Save summary metrics 24 | $null = $ModuleOutputSummary.Rows.Add("$ModuleType","$CollectionModuleName","$CollectionDataSource","$AnalysisModuleName","$AnalysisModuleDesc","$AnalysisType","$InstanceCount","$AnalysisModuleAffectedComputerCount") -------------------------------------------------------------------------------- /windows/modules/analysis/stack/analyze-017-01-wmi-providers.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NetSPI/PowerHunt/5f48c458035c894c297754e44520ab21f63b5877/windows/modules/analysis/stack/analyze-017-01-wmi-providers.ps1 -------------------------------------------------------------------------------- /windows/modules/collection/collect-002-01-environmental-paths.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-environmental-paths 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of environmental paths 11 | $Env:Path | 12 | foreach { 13 | 14 | $EnvPath = $_.split(",;") 15 | $EnvPath | 16 | Foreach{ 17 | 18 | # Verify folder exists 19 | $PathExists = Test-Path "$_" 20 | 21 | if($PathExists -eq $true){ 22 | 23 | # Get folder info 24 | $FileInfo = Get-Item "$_" 25 | $FileOwner = $FileInfo.GetAccessControl().Owner 26 | $FileCreationTime = $FileInfo.CreationTime 27 | $FileLastWriteTime = $FileInfo.LastWriteTime 28 | $FileLastAccessTime = $FileInfo.LastAccessTime 29 | } 30 | 31 | # Create new object 32 | $Object = New-Object PSObject 33 | $Object | add-member EnvPath $_ 34 | $Object | add-member PathExists $PathExists 35 | $Object | add-member FileOwner $FileOwner 36 | $Object | add-member FileCreationTime $FileCreationTime 37 | $Object | add-member FileLastWriteTime $FileLastWriteTime 38 | $Object | add-member FileLastAccessTime $FileLastAccessTime 39 | $Object 40 | } 41 | } -------------------------------------------------------------------------------- /windows/modules/collection/collect-002-02-environmental-variables.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-environmental-variables 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of environmental variables 11 | Get-ChildItem env: 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-003-01-events-1102.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-events-1102 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Summary: This is script is part of the PowerHunt framework 6 | # and is used to collect information event 1102 (audit log was cleared). 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get event data 11 | $MyEvents = Get-WinEvent -FilterHashtable @{logname="security"; id="1102"} -ErrorAction SilentlyContinue | select MachineName,LogName,ProviderName,Id,ActivityId,Bookmark,ContainerLog,Keywords,KeywordsDisplayNames,Level,LevelDisplayName,MatchedQueryIds,Opcode,OpcodeDisplayName,ProcessId,Properties,ProviderId,Qualifiers,RecordId,RelatedActivityId,Task,TaskDisplayName,ThreadId,TimeCreated,UserId,Version,Message 12 | $MyEvents | 13 | foreach{ 14 | $MachineName = $_.MachineName 15 | $LogName = $_.LogName 16 | $EventId = $_.Id 17 | $Message = $_.Message 18 | 19 | # Parse domain of user 20 | $SubjectDomain = (($Message -split('\r?\n') | Select-String 'Domain Name:' -SimpleMatch) -split("Domain Name:"))[1].trim() 21 | 22 | # Parse name of user 23 | $SubjectUser = (($Message -split('\r?\n') | Select-String 'Subject' -Context 0, 2 | % {$_.Context.PostContext}) -split("Account Name:"))[2].trim() 24 | 25 | # Parse sid of user 26 | $SubjectUserSid = (($Message -split('\r?\n') | Select-String 'Subject' -Context 0, 1 | % {$_.Context.PostContext}) -split("Security ID:"))[1].trim() 27 | 28 | # If of the user or group added 29 | $objSID = New-Object System.Security.Principal.SecurityIdentifier $NewUserSid 30 | $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) 31 | $NewUser = $objUser.Value 32 | if($NewUser.Name){ 33 | $NewUserName = $NewUser.Name 34 | }else{ 35 | $NewUserName = $NewUser 36 | } 37 | 38 | # Create new object to return 39 | $Object = New-Object PSObject 40 | $Object | add-member ComputerName $MachineName 41 | $Object | add-member DataSource1 "event" 42 | $Object | add-member DataSource2 "1102" 43 | $Object | add-member LogName $LogName 44 | $Object | add-member EventId $EventId 45 | $Object | add-member SubjectUser $SubjectUser 46 | $Object | add-member SubjectUserSid $SubjectUserSid 47 | $Object | add-member SubjectUserDomain $SubjectDomain 48 | $Object | add-member TimeCreated $_.TimeCreated 49 | $Object | add-member LogMessage $Message 50 | $Object 51 | } -------------------------------------------------------------------------------- /windows/modules/collection/collect-003-02-events-4732.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-events-4732 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Summary: This is script is part of the PowerHunt framework 6 | # and is used to collect information event 4732 (member added to security-enabled local group). 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get event data 11 | $MyEvents = Get-WinEvent -FilterHashtable @{logname="security"; id="4732"} -ErrorAction SilentlyContinue | select MachineName,LogName,ProviderName,Id,ActivityId,Bookmark,ContainerLog,Keywords,KeywordsDisplayNames,Level,LevelDisplayName,MatchedQueryIds,Opcode,OpcodeDisplayName,ProcessId,Properties,ProviderId,Qualifiers,RecordId,RelatedActivityId,Task,TaskDisplayName,ThreadId,TimeCreated,UserId,Version,Message | where message -like "*Administrators*" 12 | $MyEvents | 13 | foreach{ 14 | $MachineName = $_.MachineName 15 | $LogName = $_.LogName 16 | $EventId = $_.Id 17 | $Message = $_.Message 18 | 19 | # Parse domain of user who added the new user 20 | $SubjectDomain = (($Message -split('\r?\n') | Select-String 'Account Domain:' -SimpleMatch) -split("Account Domain:"))[1].trim() 21 | 22 | # Parse name of user who added the new user 23 | $SubjectUser = (($Message -split('\r?\n') | Select-String 'Subject' -Context 0, 2 | % {$_.Context.PostContext}) -split("Account Name:"))[2].trim() 24 | 25 | # Parse sid of user who added the new user 26 | $SubjectUserSid = (($Message -split('\r?\n') | Select-String 'Subject' -Context 0, 1 | % {$_.Context.PostContext}) -split("Security ID:"))[1].trim() 27 | 28 | # Parse user sid that was added 29 | $NewUserSid = (($Message -split('\r?\n') | Select-String 'member' -Context 0, 1 | % {$_.Context.PostContext}) -split("Security ID:"))[2].trim() 30 | 31 | # Look up user's name from sid for local user 32 | # This step may not be needed 33 | 34 | # If of the user or group added 35 | $objSID = New-Object System.Security.Principal.SecurityIdentifier $NewUserSid 36 | $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) 37 | $NewUser = $objUser.Value 38 | if($NewUser.Name){ 39 | $NewUserName = $NewUser.Name 40 | }else{ 41 | $NewUserName = $NewUser 42 | } 43 | 44 | # Create new object to return 45 | $Object = New-Object PSObject 46 | $Object | add-member ComputerName $MachineName 47 | $Object | add-member DataSource1 "event" 48 | $Object | add-member DataSource2 "4732" 49 | $Object | add-member LogName $LogName 50 | $Object | add-member EventId $EventId 51 | $Object | add-member SubjectUser $SubjectUser 52 | $Object | add-member SubjectUserSid $SubjectUserSid 53 | $Object | add-member SubjectUserDomain $SubjectDomain 54 | $Object | add-member TimeCreated $_.TimeCreated 55 | $Object | add-member PrincipalName $NewUserName 56 | $Object | add-member PrincipalSid $NewUserSid 57 | $Object | add-member PrincipalEnabled $NewUser.Enabled 58 | $Object | add-member PrincipalLastLogon $NewUser.LastLogon 59 | $Object | add-member PrincipalPasswordLastSet $NewUser.PasswordLastSet 60 | $Object | add-member LogMessage $Message 61 | $Object 62 | } 63 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-004-01-groups.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-groups 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of group 11 | Get-LocalGroup 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-004-02-group-members.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-group-members 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of group members 11 | Get-LocalGroup | 12 | foreach{ 13 | $GroupName = $_.name 14 | Get-LocalGroupMember -Group $_.name | 15 | foreach { 16 | 17 | $PrincipalType = $_.ObjectClass 18 | $PrincipalName = $_.name 19 | $PrincipalSource = $_.PrincipalSource 20 | 21 | # Create new object to return 22 | $Object = New-Object PSObject 23 | $Object | add-member Group $GroupName 24 | $Object | add-member MemberType $PrincipalType 25 | $Object | add-member MemberName $PrincipalName 26 | $Object | add-member MemberSource $PrincipalSource 27 | $Object 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-005-01-installed-software.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-installed-software 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Author : Boe Prox (Get-Software) 6 | # https://mcpmag.com/articles/2017/07/27/gathering-installed-software-using-powershell.aspx 7 | # Summary: This is script is part of the PowerHunt framework 8 | # and is used to collect information about installed software. 9 | # License: 3-clause BSD 10 | 11 | 12 | 13 | Function Get-Software { 14 | 15 | [OutputType('System.Software.Inventory')] 16 | 17 | [Cmdletbinding()] 18 | 19 | Param( 20 | 21 | [Parameter(ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] 22 | 23 | [String[]]$Computername=$env:COMPUTERNAME 24 | 25 | ) 26 | 27 | Begin { 28 | 29 | } 30 | 31 | Process { 32 | 33 | ForEach ($Computer in $Computername){ 34 | 35 | If (Test-Connection -ComputerName $Computer -Count 1 -Quiet) { 36 | 37 | $Paths = @("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","SOFTWARE\\Wow6432node\\Microsoft\\Windows\\CurrentVersion\\Uninstall") 38 | 39 | ForEach($Path in $Paths) { 40 | 41 | Write-Verbose "Checking Path: $Path" 42 | 43 | # Create an instance of the Registry Object and open the HKLM base key 44 | 45 | Try { 46 | 47 | $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$Computer,'Registry64') 48 | 49 | } Catch { 50 | 51 | Write-Error $_ 52 | 53 | Continue 54 | 55 | } 56 | 57 | # Drill down into the Uninstall key using the OpenSubKey Method 58 | 59 | Try { 60 | 61 | $regkey=$reg.OpenSubKey($Path) 62 | 63 | # Retrieve an array of string that contain all the subkey names 64 | 65 | $subkeys=$regkey.GetSubKeyNames() 66 | 67 | # Open each Subkey and use GetValue Method to return the required values for each 68 | 69 | ForEach ($key in $subkeys){ 70 | 71 | Write-Verbose "Key: $Key" 72 | 73 | $thisKey=$Path+"\\"+$key 74 | 75 | Try { 76 | 77 | $thisSubKey=$reg.OpenSubKey($thisKey) 78 | 79 | # Prevent Objects with empty DisplayName 80 | 81 | $DisplayName = $thisSubKey.getValue("DisplayName") 82 | 83 | If ($DisplayName -AND $DisplayName -notmatch '^Update for|rollup|^Security Update|^Service Pack|^HotFix') { 84 | 85 | $Date = $thisSubKey.GetValue('InstallDate') 86 | 87 | If ($Date) { 88 | 89 | Try { 90 | 91 | $Date = [datetime]::ParseExact($Date, 'yyyyMMdd', $Null) 92 | 93 | } Catch{ 94 | 95 | Write-Warning "$($Computer): $_ <$($Date)>" 96 | 97 | $Date = $Null 98 | 99 | } 100 | 101 | } 102 | 103 | # Create New Object with empty Properties 104 | 105 | $Publisher = Try { 106 | 107 | $thisSubKey.GetValue('Publisher').Trim() 108 | 109 | } 110 | 111 | Catch { 112 | 113 | $thisSubKey.GetValue('Publisher') 114 | 115 | } 116 | 117 | $Version = Try { 118 | 119 | #Some weirdness with trailing [char]0 on some strings 120 | 121 | $thisSubKey.GetValue('DisplayVersion').TrimEnd(([char[]](32,0))) 122 | 123 | } 124 | 125 | Catch { 126 | 127 | $thisSubKey.GetValue('DisplayVersion') 128 | 129 | } 130 | 131 | $UninstallString = Try { 132 | 133 | $thisSubKey.GetValue('UninstallString').Trim() 134 | 135 | } 136 | 137 | Catch { 138 | 139 | $thisSubKey.GetValue('UninstallString') 140 | 141 | } 142 | 143 | $InstallLocation = Try { 144 | 145 | $thisSubKey.GetValue('InstallLocation').Trim() 146 | 147 | } 148 | 149 | Catch { 150 | 151 | $thisSubKey.GetValue('InstallLocation') 152 | 153 | } 154 | 155 | $InstallSource = Try { 156 | 157 | $thisSubKey.GetValue('InstallSource').Trim() 158 | 159 | } 160 | 161 | Catch { 162 | 163 | $thisSubKey.GetValue('InstallSource') 164 | 165 | } 166 | 167 | $HelpLink = Try { 168 | 169 | $thisSubKey.GetValue('HelpLink').Trim() 170 | 171 | } 172 | 173 | Catch { 174 | 175 | $thisSubKey.GetValue('HelpLink') 176 | 177 | } 178 | 179 | $Object = [pscustomobject]@{ 180 | 181 | Computername = $Computer 182 | 183 | DisplayName = $DisplayName 184 | 185 | Version = $Version 186 | 187 | InstallDate = $Date 188 | 189 | Publisher = $Publisher 190 | 191 | UninstallString = $UninstallString 192 | 193 | InstallLocation = $InstallLocation 194 | 195 | InstallSource = $InstallSource 196 | 197 | HelpLink = $thisSubKey.GetValue('HelpLink') 198 | 199 | EstimatedSizeMB = [decimal]([math]::Round(($thisSubKey.GetValue('EstimatedSize')*1024)/1MB,2)) 200 | 201 | } 202 | 203 | $Object.pstypenames.insert(0,'System.Software.Inventory') 204 | 205 | Write-Output $Object 206 | 207 | } 208 | 209 | } Catch { 210 | 211 | Write-Warning "$Key : $_" 212 | 213 | } 214 | 215 | } 216 | 217 | } Catch {} 218 | 219 | $reg.Close() 220 | 221 | } 222 | 223 | } Else { 224 | 225 | Write-Error "$($Computer): unable to reach remote system!" 226 | 227 | } 228 | 229 | } 230 | 231 | } 232 | 233 | } 234 | 235 | # Get installed software 236 | Get-Software 237 | 238 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-005-02-installed-software-antispyware.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-installed-software-antispyware 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get registred security software 11 | Get-WmiObject -Namespace ROOT/SecurityCenter2 -Class AntiSpywareProduct 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-005-03-installed-software-antivirus.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-installed-software-antivirus 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get registred security software 11 | Get-WmiObject -Namespace ROOT/SecurityCenter2 -Class AntiVirusProduct 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-005-04-installed-software-firewall.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-installed-software-firewall 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get registred security software 11 | Get-WmiObject -Namespace ROOT/SecurityCenter2 -Class FirewallProduct 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-006-01-mapped-drives.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-mapped-drives 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of mapped drives 11 | Get-WmiObject -ClassName Win32_MappedLogicalDisk 12 | 13 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-007-01-named-pipes.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-named-pipes 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Summary: This is script is part of the PowerHunt framework 6 | # and is used to collect information from named pipes. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get named pipes 11 | Get-ChildItem \\.\pipe\ | select name 12 | 13 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-008-01-network-interfaces.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-network-interfaces 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get adapters 11 | $AdapterInfo = Get-NetAdapter | Select name, InterfaceDescription, ifIndex, Status, MacAddress, LinkSpeed 12 | 13 | # Get policy and IP information 14 | $AdapterInfo | 15 | foreach{ 16 | 17 | # Set adapter variablse 18 | $AdapterName = $_.name 19 | $Status = $_.status 20 | $MacAddress = $_.macaddress 21 | $LinkSpeed = $_.linkspeed 22 | $ifIndex = $_.ifIndex 23 | 24 | # Get IP information 25 | $IPInfo = Get-NetAdapter | Get-NetIPAddress | select IPAddress, InterfaceIndex,InterfaceAlias,AddressFamily,Type,PrefixLength,Policy | where InterfaceAlias -like $_.name 26 | $IPInfo | 27 | Foreach { 28 | 29 | # Setup IP information variables 30 | $IpAddress = $_.IPAddress 31 | $AddressFamily = $_.AddressFamily 32 | $Type = $_.Type 33 | $PrefixLength = $_.PrefixLength 34 | $Policy = $_.Policy 35 | 36 | # Get policy information 37 | $ProfileInfo = Get-NetConnectionProfile | select Name,InterfaceIndex,InterfaceAlias,NetworkCategory,IPv4Connectivity,IPv6Connectivity | where InterfaceAlias -like $AdapterName 38 | 39 | # Create new object to return 40 | $Object = New-Object PSObject 41 | $Object | add-member AdapterName $AdapterName 42 | $Object | add-member Status $status 43 | $Object | add-member MacAddress $macaddress 44 | $Object | add-member IpAddress $IPAddress 45 | $Object | add-member AddressFamily $AddressFamily 46 | $Object | add-member Type $Type 47 | $Object | add-member PrefixLength $PrefixLength 48 | $Object | add-member Policy $Policy 49 | $Object | add-member LinkSpeed $linkspeed 50 | $Object | add-member DnsSuffix $ProfileInfo.name 51 | $Object | add-member ifIndex $ifIndex 52 | $Object | add-member InterfaceAlias $ProfileInfo.InterfaceAlias 53 | $Object | add-member NetworkCategory $ProfileInfo.NetworkCategory 54 | $Object | add-member IPv4Connectivity $ProfileInfo.IPv4Connectivity 55 | $Object | add-member IPv6Connectivity $ProfileInfo.IPv6Connectivity 56 | 57 | $Object 58 | } 59 | } -------------------------------------------------------------------------------- /windows/modules/collection/collect-009-01-processes.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-processes 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect process information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # /////////////////////////////////////// 11 | # Load Get-PESecurity 12 | # /////////////////////////////////////// 13 | # Source: https://github.com/NetSPI/PESecurity/blob/master/Get-PESecurity.psm1 14 | 15 | function Get-PESecurity 16 | { 17 | [CmdletBinding()] 18 | Param 19 | ( 20 | # Directory to scan 21 | [Parameter(Mandatory = $false, 22 | ValueFromPipelineByPropertyName = $true, 23 | Position = 0)] 24 | [String]$Directory, 25 | 26 | # File to scan 27 | [Parameter(Mandatory = $false, 28 | ValueFromPipelineByPropertyName = $true, 29 | Position = 0)] 30 | [String]$File, 31 | 32 | #Recursive flag 33 | [Parameter(Mandatory = $false, 34 | ValueFromPipelineByPropertyName = $false, 35 | Position = 1)] 36 | [Switch]$Recursive, 37 | 38 | #Skip Authenticode 39 | [Parameter(Mandatory = $false, 40 | ValueFromPipelineByPropertyName = $false, 41 | Position = 2)] 42 | [Switch]$SkipAuthenticode 43 | 44 | ) 45 | 46 | Begin 47 | { 48 | $ModuleName = 'Win32' 49 | $AssemblyName = [System.Reflection.AssemblyName]::new(${ModuleName}) 50 | $AssemblyAccess = [System.Reflection.Emit.AssemblyBuilderAccess]::Run 51 | if($PSVersionTable['PSEdition'] -eq 'Core') { 52 | $AssemblyBuilder = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 53 | } else 54 | { 55 | $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 56 | } 57 | $Mod = $AssemblyBuilder.DefineDynamicModule($ModuleName) 58 | 59 | $ImageDosSignature = enumerate $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 60 | DOS_SIGNATURE = 0x5A4D 61 | OS2_SIGNATURE = 0x454E 62 | OS2_SIGNATURE_LE = 0x454C 63 | VXD_SIGNATURE = 0x454C 64 | } 65 | 66 | $ImageFileMachine = enumerate $Mod PE.IMAGE_FILE_MACHINE UInt16 @{ 67 | UNKNOWN = 0x0000 68 | I386 = 0x014C # Intel 386. 69 | R3000 = 0x0162 # MIPS little-endian =0x160 big-endian 70 | R4000 = 0x0166 # MIPS little-endian 71 | R10000 = 0x0168 # MIPS little-endian 72 | WCEMIPSV2 = 0x0169 # MIPS little-endian WCE v2 73 | ALPHA = 0x0184 # Alpha_AXP 74 | SH3 = 0x01A2 # SH3 little-endian 75 | SH3DSP = 0x01A3 76 | SH3E = 0x01A4 # SH3E little-endian 77 | SH4 = 0x01A6 # SH4 little-endian 78 | SH5 = 0x01A8 # SH5 79 | ARM = 0x01C0 # ARM Little-Endian 80 | THUMB = 0x01C2 81 | ARMNT = 0x01C4 # ARM Thumb-2 Little-Endian 82 | AM33 = 0x01D3 83 | POWERPC = 0x01F0 # IBM PowerPC Little-Endian 84 | POWERPCFP = 0x01F1 85 | IA64 = 0x0200 # Intel 64 86 | MIPS16 = 0x0266 # MIPS 87 | ALPHA64 = 0x0284 # ALPHA64 88 | MIPSFPU = 0x0366 # MIPS 89 | MIPSFPU16 = 0x0466 # MIPS 90 | TRICORE = 0x0520 # Infineon 91 | CEF = 0x0CEF 92 | EBC = 0x0EBC # EFI public byte Code 93 | AMD64 = 0x8664 # AMD64 (K8) 94 | M32R = 0x9041 # M32R little-endian 95 | CEE = 0xC0EE 96 | } 97 | 98 | $ImageFileCharacteristics = enumerate $Mod PE.IMAGE_FILE_CHARACTERISTICS UInt16 @{ 99 | IMAGE_RELOCS_STRIPPED = 0x0001 # Relocation info stripped from file. 100 | IMAGE_EXECUTABLE_IMAGE = 0x0002 # File is executable (i.e. no unresolved external references). 101 | IMAGE_LINE_NUMS_STRIPPED = 0x0004 # Line nunbers stripped from file. 102 | IMAGE_LOCAL_SYMS_STRIPPED = 0x0008 # Local symbols stripped from file. 103 | IMAGE_AGGRESIVE_WS_TRIM = 0x0010 # Agressively trim working set 104 | IMAGE_LARGE_ADDRESS_AWARE = 0x0020 # App can handle >2gb addresses 105 | IMAGE_REVERSED_LO = 0x0080 # public bytes of machine public ushort are reversed. 106 | IMAGE_32BIT_MACHINE = 0x0100 # 32 bit public ushort machine. 107 | IMAGE_DEBUG_STRIPPED = 0x0200 # Debugging info stripped from file in .DBG file 108 | IMAGE_REMOVABLE_RUN_FROM_SWAP = 0x0400 # If Image is on removable media copy and run from the swap file. 109 | IMAGE_NET_RUN_FROM_SWAP = 0x0800 # If Image is on Net copy and run from the swap file. 110 | IMAGE_SYSTEM = 0x1000 # System File. 111 | IMAGE_DLL = 0x2000 # File is a DLL. 112 | IMAGE_UP_SYSTEM_ONLY = 0x4000 # File should only be run on a UP machine 113 | IMAGE_REVERSED_HI = 0x8000 # public bytes of machine public ushort are reversed. 114 | } -Bitfield 115 | 116 | $ImageHdrMagic = enumerate $Mod PE.IMAGE_NT_OPTIONAL_HDR_MAGIC UInt16 @{ 117 | PE32 = 0x010B 118 | PE64 = 0x020B 119 | } 120 | 121 | $ImageNTSig = enumerate $Mod PE.IMAGE_NT_SIGNATURE UInt32 @{ 122 | VALID_PE_SIGNATURE = 0x00004550 123 | } 124 | 125 | $ImageSubsystem = enumerate $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 126 | UNKNOWN = 0 127 | NATIVE = 1 # Image doesn't require a subsystem. 128 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 129 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 130 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 131 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 132 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 133 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 134 | EFI_APPLICATION = 10 135 | EFI_BOOT_SERVICE_DRIVER = 11 136 | EFI_RUNTIME_DRIVER = 12 137 | EFI_ROM = 13 138 | XBOX = 14 139 | WINDOWS_BOOT_APPLICATION = 16 140 | } 141 | 142 | $ImageDllCharacteristics = enumerate $Mod PE.IMAGE_DLLCHARACTERISTICS UInt16 @{ 143 | HIGH_ENTROPY_VA = 0x0020 # Opts in to high entropy ASLR 144 | DYNAMIC_BASE = 0x0040 # DLL can move. 145 | FORCE_INTEGRITY = 0x0080 # Code Integrity Image 146 | NX_COMPAT = 0x0100 # Image is NX compatible 147 | NO_ISOLATION = 0x0200 # Image understands isolation and doesn't want it 148 | NO_SEH = 0x0400 # Image does not use SEH. No SE handler may reside in this image 149 | NO_BIND = 0x0800 # Do not bind this image. 150 | WDM_DRIVER = 0x2000 # Driver uses WDM model 151 | GUARD_CF = 0x4000 # Control Flow Guard 152 | TERMINAL_SERVER_AWARE = 0x8000 153 | } -Bitfield 154 | 155 | $ImageScn = enumerate $Mod PE.IMAGE_SCN Int32 @{ 156 | TYPE_NO_PAD = 0x00000008 # Reserved. 157 | CNT_CODE = 0x00000020 # Section contains code. 158 | CNT_INITIALIZED_DATA = 0x00000040 # Section contains initialized data. 159 | CNT_UNINITIALIZED_DATA = 0x00000080 # Section contains uninitialized data. 160 | LNK_INFO = 0x00000200 # Section contains comments or some other type of information. 161 | LNK_REMOVE = 0x00000800 # Section contents will not become part of image. 162 | LNK_COMDAT = 0x00001000 # Section contents comdat. 163 | NO_DEFER_SPEC_EXC = 0x00004000 # Reset speculative exceptions handling bits in the TLB entries for this section. 164 | GPREL = 0x00008000 # Section content can be accessed relative to GP 165 | MEM_FARDATA = 0x00008000 166 | MEM_PURGEABLE = 0x00020000 167 | MEM_16BIT = 0x00020000 168 | MEM_LOCKED = 0x00040000 169 | MEM_PRELOAD = 0x00080000 170 | ALIGN_1BYTES = 0x00100000 171 | ALIGN_2BYTES = 0x00200000 172 | ALIGN_4BYTES = 0x00300000 173 | ALIGN_8BYTES = 0x00400000 174 | ALIGN_16BYTES = 0x00500000 # Default alignment if no others are specified. 175 | ALIGN_32BYTES = 0x00600000 176 | ALIGN_64BYTES = 0x00700000 177 | ALIGN_128BYTES = 0x00800000 178 | ALIGN_256BYTES = 0x00900000 179 | ALIGN_512BYTES = 0x00A00000 180 | ALIGN_1024BYTES = 0x00B00000 181 | ALIGN_2048BYTES = 0x00C00000 182 | ALIGN_4096BYTES = 0x00D00000 183 | ALIGN_8192BYTES = 0x00E00000 184 | ALIGN_MASK = 0x00F00000 185 | LNK_NRELOC_OVFL = 0x01000000 # Section contains extended relocations. 186 | MEM_DISCARDABLE = 0x02000000 # Section can be discarded. 187 | MEM_NOT_CACHED = 0x04000000 # Section is not cachable. 188 | MEM_NOT_PAGED = 0x08000000 # Section is not pageable. 189 | MEM_SHARED = 0x10000000 # Section is shareable. 190 | MEM_EXECUTE = 0x20000000 # Section is executable. 191 | MEM_READ = 0x40000000 # Section is readable. 192 | MEM_WRITE = 0x80000000 # Section is writeable. 193 | } -Bitfield 194 | 195 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 196 | e_magic = field 0 $ImageDosSignature 197 | e_cblp = field 1 UInt16 198 | e_cp = field 2 UInt16 199 | e_crlc = field 3 UInt16 200 | e_cparhdr = field 4 UInt16 201 | e_minalloc = field 5 UInt16 202 | e_maxalloc = field 6 UInt16 203 | e_ss = field 7 UInt16 204 | e_sp = field 8 UInt16 205 | e_csum = field 9 UInt16 206 | e_ip = field 10 UInt16 207 | e_cs = field 11 UInt16 208 | e_lfarlc = field 12 UInt16 209 | e_ovno = field 13 UInt16 210 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 211 | e_oemid = field 15 UInt16 212 | e_oeminfo = field 16 UInt16 213 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 214 | e_lfanew = field 18 Int32 215 | } 216 | 217 | $ImageFileHeader = struct $Mod PE.IMAGE_FILE_HEADER @{ 218 | Machine = field 0 $ImageFileMachine 219 | NumberOfSections = field 1 UInt16 220 | TimeDateStamp = field 2 UInt32 221 | PointerToSymbolTable = field 3 UInt32 222 | NumberOfSymbols = field 4 UInt32 223 | SizeOfOptionalHeader = field 5 UInt16 224 | Characteristics = field 6 $ImageFileCharacteristics 225 | } 226 | 227 | $PeImageDataDir = struct $Mod PE.IMAGE_DATA_DIRECTORY @{ 228 | VirtualAddress = field 0 UInt32 229 | Size = field 1 UInt32 230 | } 231 | 232 | $ImageOptionalHdr = struct $Mod PE.IMAGE_OPTIONAL_HEADER @{ 233 | Magic = field 0 $ImageHdrMagic 234 | MajorLinkerVersion = field 1 Byte 235 | MinorLinkerVersion = field 2 Byte 236 | SizeOfCode = field 3 UInt32 237 | SizeOfInitializedData = field 4 UInt32 238 | SizeOfUninitializedData = field 5 UInt32 239 | AddressOfEntryPoint = field 6 UInt32 240 | BaseOfCode = field 7 UInt32 241 | BaseOfData = field 8 UInt32 242 | ImageBase = field 9 UInt32 243 | SectionAlignment = field 10 UInt32 244 | FileAlignment = field 11 UInt32 245 | MajorOperatingSystemVersion = field 12 UInt16 246 | MinorOperatingSystemVersion = field 13 UInt16 247 | MajorImageVersion = field 14 UInt16 248 | MinorImageVersion = field 15 UInt16 249 | MajorSubsystemVersion = field 16 UInt16 250 | MinorSubsystemVersion = field 17 UInt16 251 | Win32VersionValue = field 18 UInt32 252 | SizeOfImage = field 19 UInt32 253 | SizeOfHeaders = field 20 UInt32 254 | CheckSum = field 21 UInt32 255 | Subsystem = field 22 $ImageSubsystem 256 | DllCharacteristics = field 23 $ImageDllCharacteristics 257 | SizeOfStackReserve = field 24 UInt32 258 | SizeOfStackCommit = field 25 UInt32 259 | SizeOfHeapReserve = field 26 UInt32 260 | SizeOfHeapCommit = field 27 UInt32 261 | LoaderFlags = field 28 UInt32 262 | NumberOfRvaAndSizes = field 29 UInt32 263 | DataDirectory = field 30 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 264 | } 265 | 266 | $ImageOptionalHdr64 = struct $Mod PE.IMAGE_OPTIONAL_HEADER64 @{ 267 | Magic = field 0 $ImageHdrMagic 268 | MajorLinkerVersion = field 1 Byte 269 | MinorLinkerVersion = field 2 Byte 270 | SizeOfCode = field 3 UInt32 271 | SizeOfInitializedData = field 4 UInt32 272 | SizeOfUninitializedData = field 5 UInt32 273 | AddressOfEntryPoint = field 6 UInt32 274 | BaseOfCode = field 7 UInt32 275 | ImageBase = field 8 UInt64 276 | SectionAlignment = field 9 UInt32 277 | FileAlignment = field 10 UInt32 278 | MajorOperatingSystemVersion = field 11 UInt16 279 | MinorOperatingSystemVersion = field 12 UInt16 280 | MajorImageVersion = field 13 UInt16 281 | MinorImageVersion = field 14 UInt16 282 | MajorSubsystemVersion = field 15 UInt16 283 | MinorSubsystemVersion = field 16 UInt16 284 | Win32VersionValue = field 17 UInt32 285 | SizeOfImage = field 18 UInt32 286 | SizeOfHeaders = field 19 UInt32 287 | CheckSum = field 20 UInt32 288 | Subsystem = field 21 $ImageSubsystem 289 | DllCharacteristics = field 22 $ImageDllCharacteristics 290 | SizeOfStackReserve = field 23 UInt64 291 | SizeOfStackCommit = field 24 UInt64 292 | SizeOfHeapReserve = field 25 UInt64 293 | SizeOfHeapCommit = field 26 UInt64 294 | LoaderFlags = field 27 UInt32 295 | NumberOfRvaAndSizes = field 28 UInt32 296 | DataDirectory = field 29 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 297 | } 298 | 299 | $ImageSectionHdrs = struct $Mod PE.IMAGE_SECTION_HEADER @{ 300 | Name = field 0 String -MarshalAs @('ByValTStr', 8) 301 | VirtualSize = field 1 UInt32 302 | VirtualAddress = field 2 UInt32 303 | SizeOfRawData = field 3 UInt32 304 | PointerToRawData = field 4 UInt32 305 | PointerToRelocations = field 5 UInt32 306 | PointerToLinenumbers = field 6 UInt32 307 | NumberOfRelocations = field 7 UInt16 308 | NumberOfLinenumbers = field 8 UInt16 309 | Characteristics = field 9 $ImageScn 310 | } 311 | 312 | $ImageConfigDirectory = struct $Mod PE.IMAGE_LOAD_CONFIG_DIRECTORY @{ 313 | Size = field 0 UInt32 314 | TimeDateStamp = field 1 UInt32 315 | MajorVersion = field 2 UInt16 316 | MinorVersion = field 3 UInt16 317 | GlobalFlagsClear = field 4 UInt32 318 | GlobalFlagsSet = field 5 UInt32 319 | CriticalSectionDefaultTimeout = field 6 UInt32 320 | DeCommitFreeBlockThreshold = field 7 UInt32 321 | DeCommitTotalFreeThreshold = field 8 UInt32 322 | LockPrefixTable = field 9 UInt32 323 | MaximumAllocationSize = field 10 UInt32 324 | VirtualMemoryThreshold = field 11 UInt32 325 | ProcessHeapFlags = field 12 UInt32 326 | ProcessAffinityMask = field 13 UInt32 327 | CSDVersion = field 14 UInt16 328 | Reserved1 = field 15 UInt16 329 | EditList = field 16 UInt32 330 | SecurityCookie = field 17 UInt32 331 | SEHandlerTable = field 18 UInt32 332 | SEHandlerCount = field 19 UInt32 333 | GuardCFCheckFunctionPointer = field 20 UInt32 334 | GuardCFDispatchFunctionPointer = field 21 UInt32 335 | GuardCFFunctionTable = field 22 UInt32 336 | GuardCFFunctionCount = field 23 UInt32 337 | GuardFlags = field 24 UInt32 338 | CodeIntegrity = field 25 UInt32 339 | GuardAddressTakenIatEntryTable = field 26 UInt32 340 | GuardAddressTakenIatEntryCount = field 27 UInt32 341 | GuardLongJumpTargetTable = field 28 UInt32 342 | GuardLongJumpTargetCount = field 29 UInt32 343 | 344 | } 345 | 346 | $ImageNTHdrs = struct $Mod PE.IMAGE_NT_HEADERS @{ 347 | Signature = field 0 $ImageNTSig 348 | FileHeader = field 1 $ImageFileHeader 349 | OptionalHeader = field 2 $ImageOptionalHdr 350 | } 351 | 352 | $ImageNTHdrs64 = struct $Mod PE.IMAGE_NT_HEADERS64 @{ 353 | Signature = field 0 $ImageNTSig 354 | FileHeader = field 1 $ImageFileHeader 355 | OptionalHeader = field 2 $ImageOptionalHdr64 356 | } 357 | 358 | $FunctionDefinitions = @( 359 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String])), 360 | (func kernel32 GetModuleHandle ([Intptr]) @([String])), 361 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 362 | ) 363 | 364 | $Table = New-Object system.Data.DataTable 'table' 365 | $Col1 = New-Object system.Data.DataColumn FileName, ([string]) 366 | $Col2 = New-Object system.Data.DataColumn ARCH, ([string]) 367 | $Col3 = New-Object system.Data.DataColumn DotNET, ([string]) 368 | $Col4 = New-Object system.Data.DataColumn ASLR, ([string]) 369 | $Col5 = New-Object system.Data.DataColumn DEP, ([string]) 370 | $Col6 = New-Object system.Data.DataColumn Authenticode, ([string]) 371 | $Col7 = New-Object system.Data.DataColumn StrongNaming, ([string]) 372 | $Col8 = New-Object system.Data.DataColumn SafeSEH, ([string]) 373 | $Col9 = New-Object system.Data.DataColumn ControlFlowGuard, ([string]) 374 | $Col10 = New-Object system.Data.DataColumn HighentropyVA, ([string]) 375 | $Table.columns.add($Col1) 376 | $Table.columns.add($Col2) 377 | $Table.columns.add($Col3) 378 | $Table.columns.add($Col4) 379 | $Table.columns.add($Col5) 380 | $Table.columns.add($Col6) 381 | $Table.columns.add($Col7) 382 | $Table.columns.add($Col8) 383 | $Table.columns.add($Col9) 384 | $Table.columns.add($Col10) 385 | } 386 | Process 387 | { 388 | $Files = Get-Files 389 | Enumerate-Files $Files $Table 390 | 391 | $Table 392 | } 393 | End 394 | { 395 | } 396 | } 397 | 398 | function Enumerate-Files 399 | { 400 | param 401 | ( 402 | [System.Object] 403 | $Files, 404 | 405 | [System.Object] 406 | $Table 407 | ) 408 | 409 | foreach ($CurrentFile in $Files) 410 | { 411 | $DotNET = $false 412 | $ASLR = $false 413 | $HighentropyVA = $false 414 | $DEP = $false 415 | $SEH = $false 416 | $ControlFlowGuard = $false 417 | $Authenticode = $false 418 | $StrongNaming = $false 419 | 420 | # Determine file length 421 | $FileInfo = New-Object System.IO.FileInfo($CurrentFile) 422 | $FileLength = $FileInfo.length 423 | 424 | $FileStream = New-Object System.IO.FileStream($CurrentFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) 425 | $FileByteArray = New-Object Byte[]($FileStream.Length) 426 | $FileStream.Read($FileByteArray, 0, $FileStream.Length) | Out-Null 427 | $FileStream.Close() 428 | 429 | $Handle = [System.Runtime.InteropServices.GCHandle]::Alloc($FileByteArray, 'Pinned') 430 | $PEBaseAddr = $Handle.AddrOfPinnedObject() 431 | $DosHeader = $PEBaseAddr -as $ImageDosHeader 432 | if ($FileByteArray.Length -lt $DosHeader.e_lfanew) 433 | { 434 | continue 435 | } 436 | $PointerNtHeader = [IntPtr] ($PEBaseAddr.ToInt64() + $DosHeader.e_lfanew) 437 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs 438 | if ($NTHeader.OptionalHeader.Magic -eq 0){ 439 | $Row = $Table.NewRow() 440 | $Row.FileName = $CurrentFile 441 | $Row.ARCH = 'Unknown Format' 442 | $Row.DotNET = 'Unknown Format' 443 | $Row.ASLR = 'Unknown Format' 444 | $Row.HighentropyVA = 'Unknown Format' 445 | $Row.DEP = 'Unknown Format' 446 | $Row.Authenticode = 'Unknown Format' 447 | $Row.StrongNaming = 'Unknown Format' 448 | $Row.SafeSEH = 'Unknown Format' 449 | $Row.ControlFlowGuard = 'Unknown Format' 450 | $Table.Rows.Add($Row) 451 | Continue 452 | } 453 | if ($NTHeader.OptionalHeader.Magic -eq 'PE64') 454 | { 455 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs64 456 | } 457 | 458 | if($NTHeader.OptionalHeader.DataDirectory[14].VirtualAddress -ne 0) { 459 | $DotNet = $true 460 | } 461 | 462 | $ARCH = $NTHeader.FileHeader.Machine.toString() 463 | $FileCharacteristics = $NTHeader.FileHeader.Characteristics.toString().Split(',') 464 | $DllCharacteristics = $NTHeader.OptionalHeader.DllCharacteristics.toString().Split(',') 465 | $value = 0 466 | $ASLR = $false 467 | if([int32]::TryParse($DllCharacteristics, [ref]$value)){ 468 | if($value -band 0x20){ 469 | $HighentropyVA = $true 470 | } 471 | if($value -band 0x40){ 472 | $ASLR = $true 473 | } 474 | if($value -band 0x100){ 475 | $DEP = $true 476 | } 477 | 478 | if($value -band 0x400){ 479 | $SEH = 'N/A' 480 | } 481 | 482 | if($value -band 0x4000){ 483 | $ControlFlowGuard = $true 484 | } 485 | } else { 486 | foreach($DllCharacteristic in $DllCharacteristics) 487 | { 488 | switch($DllCharacteristic.Trim()){ 489 | 'DYNAMIC_BASE' 490 | { 491 | $ASLR = $true 492 | } 493 | 'NX_COMPAT' 494 | { 495 | $DEP = $true 496 | } 497 | 'NO_SEH' 498 | { 499 | $SEH = 'N/A' 500 | } 501 | 'GUARD_CF' 502 | { 503 | $ControlFlowGuard = $true 504 | } 505 | 'HIGH_ENTROPY_VA' 506 | { 507 | $HighentropyVA = $true 508 | } 509 | } 510 | } 511 | } 512 | 513 | if($ASLR){ 514 | foreach($FileCharacteristic in $FileCharacteristics){ 515 | switch($FileCharacteristic.Trim()){ 516 | 'IMAGE_RELOCS_STRIPPED' 517 | { 518 | $Stripped = $true 519 | } 520 | } 521 | } 522 | 523 | $OS = [Environment]::OSVersion 524 | $WindowsCheck = $true 525 | if($OS.Version.Build -ge 9200){ 526 | $WindowsCheck = $false 527 | } 528 | 529 | if($WindowsCheck){ 530 | if (-not $DotNet -and $Stripped){ 531 | $ASLR = 'False (DYNAMICBASE Set And Relocation Table Stripped)' 532 | } 533 | } 534 | } 535 | 536 | if ($DotNet) { 537 | $ControlFlowGuard = 'N/A' 538 | } 539 | 540 | #Get Strongnaming Status 541 | $StrongNaming = Get-StrongNamingStatus $CurrentFile 542 | 543 | #Get Authenticode Status 544 | $Authenticode = 'N/A' 545 | if(!$SkipAuthenticode) 546 | { 547 | $Authenticode = Get-AuthenticodeStatus $CurrentFile 548 | } 549 | 550 | if ($ARCH -eq 'AMD64') 551 | { 552 | $SEH = 'N/A' 553 | } 554 | if ($ARCH -ne 'AMD64') 555 | { 556 | $HighentropyVA = 'N/A' 557 | } 558 | if ($SEH -ne 'N/A') 559 | { 560 | #Get SEH Status 561 | $SEH = Get-SEHStatus $CurrentFile $NTHeader $PointerNtHeader $PEBaseAddr 562 | 563 | } 564 | 565 | #Write everything to a DataTable 566 | $Row = $Table.NewRow() 567 | $Row.FileName = $CurrentFile 568 | $Row.ARCH = $ARCH 569 | $Row.DotNET = $DotNET 570 | $Row.ASLR = $ASLR 571 | $Row.DEP = $DEP 572 | $Row.Authenticode = $Authenticode 573 | $Row.StrongNaming = $StrongNaming 574 | $Row.SafeSEH = $SEH 575 | $Row.ControlFlowGuard = $ControlFlowGuard 576 | $Row.HighentropyVA = $HighentropyVA 577 | $Table.Rows.Add($Row) 578 | } 579 | } 580 | 581 | function Get-AuthenticodeStatus 582 | { 583 | param 584 | ( 585 | [System.Object] 586 | $CurrentFile 587 | 588 | ) 589 | 590 | $Status = Get-AuthenticodeSignature $CurrentFile | Select-Object -ExpandProperty Status 591 | 592 | if ($Status -eq 'Valid') 593 | { 594 | $Authenticode = $true 595 | } 596 | else 597 | { 598 | $Authenticode = $false 599 | } 600 | $Authenticode 601 | } 602 | 603 | function Get-SEHStatus 604 | { 605 | param 606 | ( 607 | [System.Object] 608 | $CurrentFile, 609 | 610 | [System.Object] 611 | $NTHeader, 612 | 613 | [System.Object] 614 | $PointerNtHeader, 615 | 616 | [System.Object] 617 | $PEBaseAddr 618 | ) 619 | $NumSections = $NTHeader.FileHeader.NumberOfSections 620 | $PointerSectionHeader = [IntPtr] ($PointerNtHeader.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageNTHdrs)) 621 | #Create an array of SectionHeaders 622 | $SectionHeaders = @(New-Object $ImageSectionHdrs) * $NumSections 623 | 624 | foreach ($i in 0..($NumSections - 1)) 625 | { 626 | $SectionHeaders[$i] = [System.Runtime.InteropServices.Marshal]::PtrToStructure(([IntPtr] ($PointerSectionHeader.ToInt64() + ($i * [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageSectionHdrs)))), [System.Type] $ImageSectionHdrs) 627 | } 628 | $ConfigPointer = [IntPtr] ($PEBaseAddr.ToInt64() + $NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress) 629 | $ConfigPointer = Convert-RVAToFileOffset $ConfigPointer 630 | $ConfigDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStructure([IntPtr] $ConfigPointer, [System.Type] $ImageConfigDirectory) 631 | $SEHandlerTable = $ConfigDirectory.SEHandlerTable 632 | $SEHandlerCount = $ConfigDirectory.SEHandlerCount 633 | 634 | if($NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress -eq 0) 635 | { 636 | $SEH = $false 637 | } 638 | elseif($ConfigDirectory.Size -lt 72) 639 | { 640 | $SEH = $false 641 | } 642 | elseif($SEHandlerTable -ne 0 -and $SEHandlerCount -ne 0) 643 | { 644 | $SEH = $true 645 | } 646 | elseif($SEHandlerTable -eq 0 -or $SEHandlerCount -eq 0) 647 | { 648 | $SEH = $false 649 | } 650 | $SEH 651 | } 652 | 653 | function Get-StrongNamingStatus 654 | { 655 | param 656 | ( 657 | [System.Object] 658 | $CurrentFile 659 | ) 660 | 661 | try 662 | { 663 | $StongNaming = [System.Reflection.AssemblyName]::GetAssemblyName($CurrentFile).GetPublicKeyToken().Count -gt 0 664 | } 665 | catch 666 | { 667 | $StongNaming = 'N/A' 668 | } 669 | $StongNaming 670 | } 671 | 672 | function Get-GS { 673 | } 674 | 675 | function Get-Files 676 | { 677 | $Files = @() 678 | if($Directory) 679 | { 680 | $Files += Get-FilesFromDirectory 681 | } 682 | if($File) 683 | { 684 | $Files += Get-ChildItem $File 685 | } 686 | $Files 687 | } 688 | 689 | function Get-FilesFromDirectory 690 | { 691 | if($Recursive) 692 | { 693 | Get-ChildItem -Path "$Directory\*" -Recurse -Include *.exe, *.dll | ForEach-Object { 694 | $Files += $_ 695 | } 696 | } 697 | else 698 | { 699 | Get-ChildItem -Path "$Directory\*" -Include *.exe, *.dll |ForEach-Object { 700 | $Files += $_ 701 | } 702 | } 703 | $Files 704 | } 705 | 706 | function Convert-RVAToFileOffset 707 | { 708 | #Author: Matthew Graeber (@mattifestation) 709 | param 710 | ( 711 | [IntPtr] 712 | $Rva 713 | ) 714 | 715 | foreach ($Section in $SectionHeaders) 716 | { 717 | if ((($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -ge $Section.VirtualAddress) -and (($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -lt ($Section.VirtualAddress + $Section.VirtualSize))) 718 | { 719 | return [IntPtr] ($Rva.ToInt64() - ($Section.VirtualAddress - $Section.PointerToRawData)) 720 | } 721 | } 722 | 723 | $Rva 724 | } 725 | 726 | <# 727 | The following functions are from Matt Graeber's method of PSReflection 728 | https://github.com/mattifestation/PSReflect 729 | #> 730 | 731 | function func 732 | { 733 | #Author: Matthew Graeber (@mattifestation) 734 | Param 735 | ( 736 | [Parameter(Position = 0, Mandatory = $true)] 737 | [String] 738 | $DllName, 739 | 740 | [Parameter(Position = 1, Mandatory = $true)] 741 | [string] 742 | $FunctionName, 743 | 744 | [Parameter(Position = 2, Mandatory = $true)] 745 | [Type] 746 | $ReturnType, 747 | 748 | [Parameter(Position = 3)] 749 | [Type[]] 750 | $ParameterTypes, 751 | 752 | [Parameter(Position = 4)] 753 | [Runtime.InteropServices.CallingConvention] 754 | $NativeCallingConvention, 755 | 756 | [Parameter(Position = 5)] 757 | [Runtime.InteropServices.CharSet] 758 | $Charset, 759 | 760 | [Switch] 761 | $SetLastError 762 | ) 763 | 764 | $Properties = @{ 765 | DllName = $DllName 766 | FunctionName = $FunctionName 767 | ReturnType = $ReturnType 768 | } 769 | 770 | if ($ParameterTypes) 771 | { 772 | $Properties['ParameterTypes'] = $ParameterTypes 773 | } 774 | if ($NativeCallingConvention) 775 | { 776 | $Properties['NativeCallingConvention'] = $NativeCallingConvention 777 | } 778 | if ($Charset) 779 | { 780 | $Properties['Charset'] = $Charset 781 | } 782 | if ($SetLastError) 783 | { 784 | $Properties['SetLastError'] = $SetLastError 785 | } 786 | 787 | New-Object PSObject -Property $Properties 788 | } 789 | 790 | function enumerate 791 | { 792 | <# 793 | Author: Matthew Graeber (@mattifestation) 794 | .SYNOPSIS 795 | 796 | Creates an in-memory enumeration for use in your PowerShell session. 797 | 798 | Author: Matthew Graeber (@mattifestation) 799 | License: BSD 3-Clause 800 | Required Dependencies: None 801 | Optional Dependencies: None 802 | 803 | .DESCRIPTION 804 | 805 | The 'enum' function facilitates the creation of enums entirely in 806 | memory using as close to a "C style" as PowerShell will allow. 807 | 808 | .PARAMETER Module 809 | 810 | The in-memory module that will host the enum. Use 811 | New-InMemoryModule to define an in-memory module. 812 | 813 | .PARAMETER FullName 814 | 815 | The fully-qualified name of the enum. 816 | 817 | .PARAMETER Type 818 | 819 | The type of each enum element. 820 | 821 | .PARAMETER EnumElements 822 | 823 | A hashtable of enum elements. 824 | 825 | .PARAMETER Bitfield 826 | 827 | Specifies that the enum should be treated as a bitfield. 828 | 829 | .EXAMPLE 830 | 831 | $Mod = New-InMemoryModule -ModuleName Win32 832 | 833 | $ImageSubsystem = enum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 834 | UNKNOWN = 0 835 | NATIVE = 1 # Image doesn't require a subsystem. 836 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 837 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 838 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 839 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 840 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 841 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 842 | EFI_APPLICATION = 10 843 | EFI_BOOT_SERVICE_DRIVER = 11 844 | EFI_RUNTIME_DRIVER = 12 845 | EFI_ROM = 13 846 | XBOX = 14 847 | WINDOWS_BOOT_APPLICATION = 16 848 | } 849 | 850 | .NOTES 851 | 852 | PowerShell purists may disagree with the naming of this function but 853 | again, this was developed in such a way so as to emulate a "C style" 854 | definition as closely as possible. Sorry, I'm not going to name it 855 | New-Enum. :P 856 | #> 857 | 858 | [OutputType([Type])] 859 | Param 860 | ( 861 | [Parameter(Position = 0, Mandatory = $true)] 862 | [Reflection.Emit.ModuleBuilder] 863 | $Module, 864 | 865 | [Parameter(Position = 1, Mandatory = $true)] 866 | [ValidateNotNullOrEmpty()] 867 | [String] 868 | $FullName, 869 | 870 | [Parameter(Position = 2, Mandatory = $true)] 871 | [Type] 872 | $Type, 873 | 874 | [Parameter(Position = 3, Mandatory = $true)] 875 | [ValidateNotNullOrEmpty()] 876 | [Hashtable] 877 | $EnumElements, 878 | 879 | [Switch] 880 | $Bitfield 881 | ) 882 | 883 | $EnumType = $Type -as [Type] 884 | 885 | $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType) 886 | 887 | if ($Bitfield) 888 | { 889 | $FlagsConstructor = [FlagsAttribute].GetConstructor(@()) 890 | $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) 891 | $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) 892 | } 893 | 894 | foreach ($Key in $EnumElements.Keys) 895 | { 896 | # Apply the specified enum type to each element 897 | $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType) 898 | } 899 | 900 | $EnumBuilder.CreateType() 901 | } 902 | 903 | function struct 904 | { 905 | <# 906 | Author: Matthew Graeber (@mattifestation) 907 | .SYNOPSIS 908 | 909 | Creates an in-memory struct for use in your PowerShell session. 910 | 911 | Author: Matthew Graeber (@mattifestation) 912 | License: BSD 3-Clause 913 | Required Dependencies: None 914 | Optional Dependencies: field 915 | 916 | .DESCRIPTION 917 | 918 | The 'struct' function facilitates the creation of structs entirely in 919 | memory using as close to a "C style" as PowerShell will allow. Struct 920 | fields are specified using a hashtable where each field of the struct 921 | is comprosed of the order in which it should be defined, its .NET 922 | type, and optionally, its offset and special marshaling attributes. 923 | 924 | One of the features of 'struct' is that after your struct is defined, 925 | it will come with a built-in GetSize method as well as an explicit 926 | converter so that you can easily cast an IntPtr to the struct without 927 | relying upon calling SizeOf and/or PtrToStructure in the Marshal 928 | class. 929 | 930 | .PARAMETER Module 931 | 932 | The in-memory module that will host the struct. Use 933 | New-InMemoryModule to define an in-memory module. 934 | 935 | .PARAMETER FullName 936 | 937 | The fully-qualified name of the struct. 938 | 939 | .PARAMETER StructFields 940 | 941 | A hashtable of fields. Use the 'field' helper function to ease 942 | defining each field. 943 | 944 | .PARAMETER PackingSize 945 | 946 | Specifies the memory alignment of fields. 947 | 948 | .PARAMETER ExplicitLayout 949 | 950 | Indicates that an explicit offset for each field will be specified. 951 | 952 | .EXAMPLE 953 | 954 | $Mod = New-InMemoryModule -ModuleName Win32 955 | 956 | $ImageDosSignature = enum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 957 | DOS_SIGNATURE = 0x5A4D 958 | OS2_SIGNATURE = 0x454E 959 | OS2_SIGNATURE_LE = 0x454C 960 | VXD_SIGNATURE = 0x454C 961 | } 962 | 963 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 964 | e_magic = field 0 $ImageDosSignature 965 | e_cblp = field 1 UInt16 966 | e_cp = field 2 UInt16 967 | e_crlc = field 3 UInt16 968 | e_cparhdr = field 4 UInt16 969 | e_minalloc = field 5 UInt16 970 | e_maxalloc = field 6 UInt16 971 | e_ss = field 7 UInt16 972 | e_sp = field 8 UInt16 973 | e_csum = field 9 UInt16 974 | e_ip = field 10 UInt16 975 | e_cs = field 11 UInt16 976 | e_lfarlc = field 12 UInt16 977 | e_ovno = field 13 UInt16 978 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 979 | e_oemid = field 15 UInt16 980 | e_oeminfo = field 16 UInt16 981 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 982 | e_lfanew = field 18 Int32 983 | } 984 | 985 | # Example of using an explicit layout in order to create a union. 986 | $TestUnion = struct $Mod TestUnion @{ 987 | field1 = field 0 UInt32 0 988 | field2 = field 1 IntPtr 0 989 | } -ExplicitLayout 990 | 991 | .NOTES 992 | 993 | PowerShell purists may disagree with the naming of this function but 994 | again, this was developed in such a way so as to emulate a "C style" 995 | definition as closely as possible. Sorry, I'm not going to name it 996 | New-Struct. :P 997 | #> 998 | [OutputType([Type])] 999 | Param 1000 | ( 1001 | [Parameter(Position = 1, Mandatory = $true)] 1002 | [Reflection.Emit.ModuleBuilder] 1003 | $Module, 1004 | 1005 | [Parameter(Position = 2, Mandatory = $true)] 1006 | [ValidateNotNullOrEmpty()] 1007 | [String] 1008 | $FullName, 1009 | 1010 | [Parameter(Position = 3, Mandatory = $true)] 1011 | [ValidateNotNullOrEmpty()] 1012 | [Hashtable] 1013 | $StructFields, 1014 | 1015 | [Reflection.Emit.PackingSize] 1016 | $PackingSize = [Reflection.Emit.PackingSize]::Unspecified, 1017 | 1018 | [Switch] 1019 | $ExplicitLayout 1020 | ) 1021 | 1022 | [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass, 1023 | Class, 1024 | Public, 1025 | Sealed, 1026 | BeforeFieldInit' 1027 | 1028 | if ($ExplicitLayout) 1029 | { 1030 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout 1031 | } 1032 | else 1033 | { 1034 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout 1035 | } 1036 | 1037 | $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize) 1038 | $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] 1039 | $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) 1040 | 1041 | $Fields = New-Object Hashtable[]($StructFields.Count) 1042 | 1043 | # Sort each field according to the orders specified 1044 | # Unfortunately, PSv2 doesn't have the luxury of the 1045 | # hashtable [Ordered] accelerator. 1046 | foreach ($Field in $StructFields.Keys) 1047 | { 1048 | $Index = $StructFields[$Field]['Position'] 1049 | $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]} 1050 | } 1051 | 1052 | foreach ($Field in $Fields) 1053 | { 1054 | $FieldName = $Field['FieldName'] 1055 | $FieldProp = $Field['Properties'] 1056 | 1057 | $Offset = $FieldProp['Offset'] 1058 | $Type = $FieldProp['Type'] 1059 | $MarshalAs = $FieldProp['MarshalAs'] 1060 | 1061 | $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public') 1062 | 1063 | if ($MarshalAs) 1064 | { 1065 | $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType]) 1066 | $Size = $MarshalAs[1] 1067 | $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, 1068 | $UnmanagedType, $SizeConst, @($Size)) 1069 | $NewField.SetCustomAttribute($AttribBuilder) 1070 | } 1071 | 1072 | if ($ExplicitLayout) 1073 | { 1074 | $NewField.SetOffset($Offset) 1075 | } 1076 | } 1077 | 1078 | # Make the struct aware of its own size. 1079 | # No more having to call [Runtime.InteropServices.Marshal]::SizeOf! 1080 | $SizeMethod = $StructBuilder.DefineMethod('GetSize', 1081 | 'Public, Static', 1082 | [Int], 1083 | [Type[]] @()) 1084 | $ILGenerator = $SizeMethod.GetILGenerator() 1085 | # Thanks for the help, Jason Shirk! 1086 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1087 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1088 | [Type].GetMethod('GetTypeFromHandle')) 1089 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1090 | [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type]))) 1091 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret) 1092 | 1093 | # Allow for explicit casting from an IntPtr 1094 | # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure! 1095 | $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit', 1096 | 'PrivateScope, Public, Static, HideBySig, SpecialName', 1097 | $StructBuilder, 1098 | [Type[]] @([IntPtr])) 1099 | $ILGenerator2 = $ImplicitConverter.GetILGenerator() 1100 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop) 1101 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 1102 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1103 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1104 | [Type].GetMethod('GetTypeFromHandle')) 1105 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1106 | [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type]))) 1107 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder) 1108 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret) 1109 | 1110 | $StructBuilder.CreateType() 1111 | } 1112 | 1113 | function field 1114 | { 1115 | #Author: Matthew Graeber (@mattifestation) 1116 | Param 1117 | ( 1118 | [Parameter(Position = 0, Mandatory = $true)] 1119 | [UInt16] 1120 | $Position, 1121 | 1122 | [Parameter(Position = 1, Mandatory = $true)] 1123 | [Type] 1124 | $Type, 1125 | 1126 | [Parameter(Position = 2)] 1127 | [UInt16] 1128 | $Offset, 1129 | 1130 | [Object[]] 1131 | $MarshalAs 1132 | ) 1133 | 1134 | @{ 1135 | Position = $Position 1136 | Type = $Type -as [Type] 1137 | Offset = $Offset 1138 | MarshalAs = $MarshalAs 1139 | } 1140 | } 1141 | 1142 | function Add-Win32Type 1143 | { 1144 | <# 1145 | Author: Matthew Graeber (@mattifestation) 1146 | .SYNOPSIS 1147 | 1148 | Creates a .NET type for an unmanaged Win32 function. 1149 | 1150 | Author: Matthew Graeber (@mattifestation) 1151 | License: BSD 3-Clause 1152 | Required Dependencies: None 1153 | Optional Dependencies: func 1154 | 1155 | .DESCRIPTION 1156 | 1157 | Add-Win32Type enables you to easily interact with unmanaged (i.e. 1158 | Win32 unmanaged) functions in PowerShell. After providing 1159 | Add-Win32Type with a function signature, a .NET type is created 1160 | using reflection (i.e. csc.exe is never called like with Add-Type). 1161 | 1162 | The 'func' helper function can be used to reduce typing when defining 1163 | multiple function definitions. 1164 | 1165 | .PARAMETER DllName 1166 | 1167 | The name of the DLL. 1168 | 1169 | .PARAMETER FunctionName 1170 | 1171 | The name of the target function. 1172 | 1173 | .PARAMETER ReturnType 1174 | 1175 | The return type of the function. 1176 | 1177 | .PARAMETER ParameterTypes 1178 | 1179 | The function parameters. 1180 | 1181 | .PARAMETER NativeCallingConvention 1182 | 1183 | Specifies the native calling convention of the function. Defaults to 1184 | stdcall. 1185 | 1186 | .PARAMETER Charset 1187 | 1188 | If you need to explicitly call an 'A' or 'W' Win32 function, you can 1189 | specify the character set. 1190 | 1191 | .PARAMETER SetLastError 1192 | 1193 | Indicates whether the callee calls the SetLastError Win32 API 1194 | function before returning from the attributed method. 1195 | 1196 | .PARAMETER Module 1197 | 1198 | The in-memory module that will host the functions. Use 1199 | New-InMemoryModule to define an in-memory module. 1200 | 1201 | .PARAMETER Namespace 1202 | 1203 | An optional namespace to prepend to the type. Add-Win32Type defaults 1204 | to a namespace consisting only of the name of the DLL. 1205 | 1206 | .EXAMPLE 1207 | 1208 | $Mod = New-InMemoryModule -ModuleName Win32 1209 | 1210 | $FunctionDefinitions = @( 1211 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError), 1212 | (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError), 1213 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 1214 | ) 1215 | 1216 | $Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' 1217 | $Kernel32 = $Types['kernel32'] 1218 | $Ntdll = $Types['ntdll'] 1219 | $Ntdll::RtlGetCurrentPeb() 1220 | $ntdllbase = $Kernel32::GetModuleHandle('ntdll') 1221 | $Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb') 1222 | 1223 | .NOTES 1224 | 1225 | Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189 1226 | 1227 | When defining multiple function prototypes, it is ideal to provide 1228 | Add-Win32Type with an array of function signatures. That way, they 1229 | are all incorporated into the same in-memory module. 1230 | #> 1231 | [OutputType([Hashtable])] 1232 | Param( 1233 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1234 | [String] 1235 | $DllName, 1236 | 1237 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1238 | [String] 1239 | $FunctionName, 1240 | 1241 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1242 | [Type] 1243 | $ReturnType, 1244 | 1245 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1246 | [Type[]] 1247 | $ParameterTypes, 1248 | 1249 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1250 | [Runtime.InteropServices.CallingConvention] 1251 | $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall, 1252 | 1253 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1254 | [Runtime.InteropServices.CharSet] 1255 | $Charset = [Runtime.InteropServices.CharSet]::Auto, 1256 | 1257 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1258 | [Switch] 1259 | $SetLastError, 1260 | 1261 | [Parameter(Mandatory = $true)] 1262 | [Reflection.Emit.ModuleBuilder] 1263 | $Module, 1264 | 1265 | [ValidateNotNull()] 1266 | [String] 1267 | $Namespace = '' 1268 | ) 1269 | 1270 | BEGIN 1271 | { 1272 | $TypeHash = @{} 1273 | } 1274 | 1275 | PROCESS 1276 | { 1277 | # Define one type for each DLL 1278 | if (!$TypeHash.ContainsKey($DllName)) 1279 | { 1280 | if ($Namespace) 1281 | { 1282 | $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit') 1283 | } 1284 | else 1285 | { 1286 | $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit') 1287 | } 1288 | } 1289 | 1290 | $Method = $TypeHash[$DllName].DefineMethod( 1291 | $FunctionName, 1292 | 'Public,Static,PinvokeImpl', 1293 | $ReturnType, 1294 | $ParameterTypes) 1295 | 1296 | # Make each ByRef parameter an Out parameter 1297 | $i = 1 1298 | foreach($Parameter in $ParameterTypes) 1299 | { 1300 | if ($Parameter.IsByRef) 1301 | { 1302 | [void] $Method.DefineParameter($i, 'Out', $null) 1303 | } 1304 | 1305 | $i++ 1306 | } 1307 | 1308 | $DllImport = [Runtime.InteropServices.DllImportAttribute] 1309 | $SetLastErrorField = $DllImport.GetField('SetLastError') 1310 | $CallingConventionField = $DllImport.GetField('CallingConvention') 1311 | $CharsetField = $DllImport.GetField('CharSet') 1312 | if ($SetLastError) 1313 | { 1314 | $SLEValue = $true 1315 | } 1316 | else 1317 | { 1318 | $SLEValue = $false 1319 | } 1320 | 1321 | # Equivalent to C# version of [DllImport(DllName)] 1322 | $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String]) 1323 | $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor, 1324 | $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(), 1325 | [Reflection.FieldInfo[]] @($SetLastErrorField, $CallingConventionField, $CharsetField), 1326 | [Object[]] @($SLEValue, ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention), ([Runtime.InteropServices.CharSet] $Charset))) 1327 | 1328 | $Method.SetCustomAttribute($DllImportAttribute) 1329 | } 1330 | 1331 | END 1332 | { 1333 | $ReturnTypes = @{} 1334 | 1335 | foreach ($Key in $TypeHash.Keys) 1336 | { 1337 | $Type = $TypeHash[$Key].CreateType() 1338 | 1339 | $ReturnTypes[$Key] = $Type 1340 | } 1341 | 1342 | return $ReturnTypes 1343 | } 1344 | } 1345 | 1346 | 1347 | # ///////////////////////////////////////////////////// 1348 | # Get-FileMd5 1349 | # ///////////////////////////////////////////////////// 1350 | function Get-FileMd5{ 1351 | 1352 | param ( 1353 | [string]$FilePath 1354 | ) 1355 | 1356 | $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider 1357 | $stream = [System.IO.File]::Open("$FilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read) 1358 | $hash = [System.BitConverter]::ToString($md5.ComputeHash($stream)) 1359 | $stream.Close() 1360 | $hash.tostring().replace('-','').trim() 1361 | } 1362 | 1363 | 1364 | # ///////////////////////////////////////////////////// 1365 | # Get Process Information 1366 | # ///////////////////////////////////////////////////// 1367 | 1368 | # Check process 1369 | Get-WMIObject Win32_Process | Select name,ProcessId,description, commandline,creationdate | 1370 | foreach{ 1371 | 1372 | # Parse exe path 1373 | if ($_.pathname -like "*`"*"){ 1374 | $ExePath = $_.commandline -split("`"") 1375 | $TargetPath = "`"" + $ExePath[1] + "`"" 1376 | }else{ 1377 | $ExePath = $_.commandline -split(".exe") 1378 | $TargetPath = "`"" + $ExePath[0] + ".exe`"" 1379 | } 1380 | 1381 | $TargetPath = $TargetPath -Replace('"','') 1382 | 1383 | # Grab file data 1384 | if(Test-Path $TargetPath){ 1385 | 1386 | # Grab PE info 1387 | $PEConfig = Get-PESecurity -File $TargetPath 1388 | $ARCH = $PEConfig.ARCH 1389 | $ASLR = $PEConfig.ASLR 1390 | $Authenticode = $PEConfig.Authenticode 1391 | $ControlFlowGuard = $PEConfig.ControlFlowGuard 1392 | $DEP = $PEConfig.DEP 1393 | $DotNET = $PEConfig.DotNET 1394 | $HighentropyVA = $PEConfig.HighentropyVA 1395 | $SafeSEH = $PEConfig.SafeSEH 1396 | $StrongNaming = $PEConfig.StrongNaming 1397 | 1398 | # Grab owner info 1399 | $FileInfo = Get-Item $TargetPath -ErrorAction SilentlyContinue 1400 | $FileOwner = $FileInfo.GetAccessControl().Owner 1401 | $FileCreationTime = $FileInfo.CreationTime 1402 | $FileLastWriteTime = $FileInfo.LastWriteTime 1403 | $FileLastAccessTime = $FileInfo.LastAccessTime 1404 | 1405 | # Check file hash 1406 | $FileHash = Get-FileMd5 "$TargetPath" 1407 | }else{ 1408 | $FileHash = "" 1409 | $FileInfo = "" 1410 | $PEConfig = "" 1411 | $ARCH = "" 1412 | $ASLR = "" 1413 | $Authenticode = "" 1414 | $ControlFlowGuard = "" 1415 | $DEP = "" 1416 | $DotNET = "" 1417 | $HighentropyVA = "" 1418 | $SafeSEH = "" 1419 | $StrongNaming = "" 1420 | $FileOwner = "" 1421 | $FileCreationTime = "" 1422 | $FileLastWriteTime = "" 1423 | $FileLastAccessTime = "" 1424 | } 1425 | 1426 | if($TargetPath -notlike "*`:*"){ 1427 | $TargetPath = $_.name 1428 | } 1429 | 1430 | # Create new object to return 1431 | $Object = New-Object PSObject 1432 | $Object | add-member DataSource1 "Processes" 1433 | $Object | add-member DataSource2 "Get-WMIObject Win32_Process" 1434 | $Object | add-member ProcessName $_.name 1435 | $Object | add-member ProcessId $_.ProcessId 1436 | $Object | add-member FilePath $TargetPath 1437 | $Object | add-member FileMd5Hash $FileHash 1438 | $Object | add-member FileOwner $FileOwner 1439 | $Object | add-member FileCreationTime $FileCreationTime 1440 | $Object | add-member FileLastWriteTime $FileLastWriteTime 1441 | $Object | add-member FileLastAccessTime $FileLastAccessTime 1442 | $Object | add-member ARCH $ARCH 1443 | $Object | add-member ASLR $ASLR 1444 | $Object | add-member Authenticode $Authenticode 1445 | $Object | add-member ControlFlowGuard $ControlFlowGuard 1446 | $Object | add-member DEP $DEP 1447 | $Object | add-member DotNET $DotNET 1448 | $Object | add-member HighentropyVA $HighentropyVA 1449 | $Object | add-member SafeSEH $SafeSEH 1450 | $Object | add-member StrongNaming $StrongNaming 1451 | 1452 | $Object 1453 | } 1454 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-010-01-protocol-handlers.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-protocol-handlers 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Summary: This is script is part of the PowerHunt framework. 6 | # License: 3-clause BSD 7 | 8 | 9 | # Create datatable for output 10 | $null = $DataTable = New-Object System.Data.DataTable; 11 | $null = $DataTable.Columns.Add("key"); 12 | $null = $DataTable.Columns.Add("path"); 13 | 14 | # Get protocol handlers 15 | foreach ($Key in Get-ChildItem Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT) 16 | { 17 | $Path = $Key.PSPath + '\shell\open\command'; 18 | $HasURLProtocol = $Key.Property -contains 'URL Protocol'; 19 | 20 | if(($HasURLProtocol) -and (Test-Path $Path)){ 21 | $CommandKey = Get-Item $Path; 22 | $ProtBin = $CommandKey.GetValue("") 23 | $ProtKey = $Key.Name.SubString($Key.Name.IndexOf('\') + 1) 24 | $null = $DataTable.Rows.Add($ProtKey,$ProtBin) 25 | } 26 | } 27 | 28 | # Get protocol handlers 29 | $DataTable -------------------------------------------------------------------------------- /windows/modules/collection/collect-011-01-services.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-services 3 | # Version: 1.1 4 | # Author : Scott Sutherland 5 | # Author : Eric Gruber (Get-PESecurity) 6 | # https://github.com/NetSPI/PESecurity/blob/master/Get-PESecurity.psm1 7 | # Summary: This is script is part of the PowerHunt framework 8 | # and is used to collect information from windows services. 9 | # License: 3-clause BSD 10 | 11 | 12 | # /////////////////////////////////////// 13 | # Load Get-PESecurity 14 | # /////////////////////////////////////// 15 | # Source: https://github.com/NetSPI/PESecurity/blob/master/Get-PESecurity.psm1 16 | 17 | function Get-PESecurity 18 | { 19 | [CmdletBinding()] 20 | Param 21 | ( 22 | # Directory to scan 23 | [Parameter(Mandatory = $false, 24 | ValueFromPipelineByPropertyName = $true, 25 | Position = 0)] 26 | [String]$Directory, 27 | 28 | # File to scan 29 | [Parameter(Mandatory = $false, 30 | ValueFromPipelineByPropertyName = $true, 31 | Position = 0)] 32 | [String]$File, 33 | 34 | #Recursive flag 35 | [Parameter(Mandatory = $false, 36 | ValueFromPipelineByPropertyName = $false, 37 | Position = 1)] 38 | [Switch]$Recursive, 39 | 40 | #Skip Authenticode 41 | [Parameter(Mandatory = $false, 42 | ValueFromPipelineByPropertyName = $false, 43 | Position = 2)] 44 | [Switch]$SkipAuthenticode 45 | 46 | ) 47 | 48 | Begin 49 | { 50 | $ModuleName = 'Win32' 51 | $AssemblyName = [System.Reflection.AssemblyName]::new(${ModuleName}) 52 | $AssemblyAccess = [System.Reflection.Emit.AssemblyBuilderAccess]::Run 53 | if($PSVersionTable['PSEdition'] -eq 'Core') { 54 | $AssemblyBuilder = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 55 | } else 56 | { 57 | $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 58 | } 59 | $Mod = $AssemblyBuilder.DefineDynamicModule($ModuleName) 60 | 61 | $ImageDosSignature = enumerate $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 62 | DOS_SIGNATURE = 0x5A4D 63 | OS2_SIGNATURE = 0x454E 64 | OS2_SIGNATURE_LE = 0x454C 65 | VXD_SIGNATURE = 0x454C 66 | } 67 | 68 | $ImageFileMachine = enumerate $Mod PE.IMAGE_FILE_MACHINE UInt16 @{ 69 | UNKNOWN = 0x0000 70 | I386 = 0x014C # Intel 386. 71 | R3000 = 0x0162 # MIPS little-endian =0x160 big-endian 72 | R4000 = 0x0166 # MIPS little-endian 73 | R10000 = 0x0168 # MIPS little-endian 74 | WCEMIPSV2 = 0x0169 # MIPS little-endian WCE v2 75 | ALPHA = 0x0184 # Alpha_AXP 76 | SH3 = 0x01A2 # SH3 little-endian 77 | SH3DSP = 0x01A3 78 | SH3E = 0x01A4 # SH3E little-endian 79 | SH4 = 0x01A6 # SH4 little-endian 80 | SH5 = 0x01A8 # SH5 81 | ARM = 0x01C0 # ARM Little-Endian 82 | THUMB = 0x01C2 83 | ARMNT = 0x01C4 # ARM Thumb-2 Little-Endian 84 | AM33 = 0x01D3 85 | POWERPC = 0x01F0 # IBM PowerPC Little-Endian 86 | POWERPCFP = 0x01F1 87 | IA64 = 0x0200 # Intel 64 88 | MIPS16 = 0x0266 # MIPS 89 | ALPHA64 = 0x0284 # ALPHA64 90 | MIPSFPU = 0x0366 # MIPS 91 | MIPSFPU16 = 0x0466 # MIPS 92 | TRICORE = 0x0520 # Infineon 93 | CEF = 0x0CEF 94 | EBC = 0x0EBC # EFI public byte Code 95 | AMD64 = 0x8664 # AMD64 (K8) 96 | M32R = 0x9041 # M32R little-endian 97 | CEE = 0xC0EE 98 | } 99 | 100 | $ImageFileCharacteristics = enumerate $Mod PE.IMAGE_FILE_CHARACTERISTICS UInt16 @{ 101 | IMAGE_RELOCS_STRIPPED = 0x0001 # Relocation info stripped from file. 102 | IMAGE_EXECUTABLE_IMAGE = 0x0002 # File is executable (i.e. no unresolved external references). 103 | IMAGE_LINE_NUMS_STRIPPED = 0x0004 # Line nunbers stripped from file. 104 | IMAGE_LOCAL_SYMS_STRIPPED = 0x0008 # Local symbols stripped from file. 105 | IMAGE_AGGRESIVE_WS_TRIM = 0x0010 # Agressively trim working set 106 | IMAGE_LARGE_ADDRESS_AWARE = 0x0020 # App can handle >2gb addresses 107 | IMAGE_REVERSED_LO = 0x0080 # public bytes of machine public ushort are reversed. 108 | IMAGE_32BIT_MACHINE = 0x0100 # 32 bit public ushort machine. 109 | IMAGE_DEBUG_STRIPPED = 0x0200 # Debugging info stripped from file in .DBG file 110 | IMAGE_REMOVABLE_RUN_FROM_SWAP = 0x0400 # If Image is on removable media copy and run from the swap file. 111 | IMAGE_NET_RUN_FROM_SWAP = 0x0800 # If Image is on Net copy and run from the swap file. 112 | IMAGE_SYSTEM = 0x1000 # System File. 113 | IMAGE_DLL = 0x2000 # File is a DLL. 114 | IMAGE_UP_SYSTEM_ONLY = 0x4000 # File should only be run on a UP machine 115 | IMAGE_REVERSED_HI = 0x8000 # public bytes of machine public ushort are reversed. 116 | } -Bitfield 117 | 118 | $ImageHdrMagic = enumerate $Mod PE.IMAGE_NT_OPTIONAL_HDR_MAGIC UInt16 @{ 119 | PE32 = 0x010B 120 | PE64 = 0x020B 121 | } 122 | 123 | $ImageNTSig = enumerate $Mod PE.IMAGE_NT_SIGNATURE UInt32 @{ 124 | VALID_PE_SIGNATURE = 0x00004550 125 | } 126 | 127 | $ImageSubsystem = enumerate $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 128 | UNKNOWN = 0 129 | NATIVE = 1 # Image doesn't require a subsystem. 130 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 131 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 132 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 133 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 134 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 135 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 136 | EFI_APPLICATION = 10 137 | EFI_BOOT_SERVICE_DRIVER = 11 138 | EFI_RUNTIME_DRIVER = 12 139 | EFI_ROM = 13 140 | XBOX = 14 141 | WINDOWS_BOOT_APPLICATION = 16 142 | } 143 | 144 | $ImageDllCharacteristics = enumerate $Mod PE.IMAGE_DLLCHARACTERISTICS UInt16 @{ 145 | HIGH_ENTROPY_VA = 0x0020 # Opts in to high entropy ASLR 146 | DYNAMIC_BASE = 0x0040 # DLL can move. 147 | FORCE_INTEGRITY = 0x0080 # Code Integrity Image 148 | NX_COMPAT = 0x0100 # Image is NX compatible 149 | NO_ISOLATION = 0x0200 # Image understands isolation and doesn't want it 150 | NO_SEH = 0x0400 # Image does not use SEH. No SE handler may reside in this image 151 | NO_BIND = 0x0800 # Do not bind this image. 152 | WDM_DRIVER = 0x2000 # Driver uses WDM model 153 | GUARD_CF = 0x4000 # Control Flow Guard 154 | TERMINAL_SERVER_AWARE = 0x8000 155 | } -Bitfield 156 | 157 | $ImageScn = enumerate $Mod PE.IMAGE_SCN Int32 @{ 158 | TYPE_NO_PAD = 0x00000008 # Reserved. 159 | CNT_CODE = 0x00000020 # Section contains code. 160 | CNT_INITIALIZED_DATA = 0x00000040 # Section contains initialized data. 161 | CNT_UNINITIALIZED_DATA = 0x00000080 # Section contains uninitialized data. 162 | LNK_INFO = 0x00000200 # Section contains comments or some other type of information. 163 | LNK_REMOVE = 0x00000800 # Section contents will not become part of image. 164 | LNK_COMDAT = 0x00001000 # Section contents comdat. 165 | NO_DEFER_SPEC_EXC = 0x00004000 # Reset speculative exceptions handling bits in the TLB entries for this section. 166 | GPREL = 0x00008000 # Section content can be accessed relative to GP 167 | MEM_FARDATA = 0x00008000 168 | MEM_PURGEABLE = 0x00020000 169 | MEM_16BIT = 0x00020000 170 | MEM_LOCKED = 0x00040000 171 | MEM_PRELOAD = 0x00080000 172 | ALIGN_1BYTES = 0x00100000 173 | ALIGN_2BYTES = 0x00200000 174 | ALIGN_4BYTES = 0x00300000 175 | ALIGN_8BYTES = 0x00400000 176 | ALIGN_16BYTES = 0x00500000 # Default alignment if no others are specified. 177 | ALIGN_32BYTES = 0x00600000 178 | ALIGN_64BYTES = 0x00700000 179 | ALIGN_128BYTES = 0x00800000 180 | ALIGN_256BYTES = 0x00900000 181 | ALIGN_512BYTES = 0x00A00000 182 | ALIGN_1024BYTES = 0x00B00000 183 | ALIGN_2048BYTES = 0x00C00000 184 | ALIGN_4096BYTES = 0x00D00000 185 | ALIGN_8192BYTES = 0x00E00000 186 | ALIGN_MASK = 0x00F00000 187 | LNK_NRELOC_OVFL = 0x01000000 # Section contains extended relocations. 188 | MEM_DISCARDABLE = 0x02000000 # Section can be discarded. 189 | MEM_NOT_CACHED = 0x04000000 # Section is not cachable. 190 | MEM_NOT_PAGED = 0x08000000 # Section is not pageable. 191 | MEM_SHARED = 0x10000000 # Section is shareable. 192 | MEM_EXECUTE = 0x20000000 # Section is executable. 193 | MEM_READ = 0x40000000 # Section is readable. 194 | MEM_WRITE = 0x80000000 # Section is writeable. 195 | } -Bitfield 196 | 197 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 198 | e_magic = field 0 $ImageDosSignature 199 | e_cblp = field 1 UInt16 200 | e_cp = field 2 UInt16 201 | e_crlc = field 3 UInt16 202 | e_cparhdr = field 4 UInt16 203 | e_minalloc = field 5 UInt16 204 | e_maxalloc = field 6 UInt16 205 | e_ss = field 7 UInt16 206 | e_sp = field 8 UInt16 207 | e_csum = field 9 UInt16 208 | e_ip = field 10 UInt16 209 | e_cs = field 11 UInt16 210 | e_lfarlc = field 12 UInt16 211 | e_ovno = field 13 UInt16 212 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 213 | e_oemid = field 15 UInt16 214 | e_oeminfo = field 16 UInt16 215 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 216 | e_lfanew = field 18 Int32 217 | } 218 | 219 | $ImageFileHeader = struct $Mod PE.IMAGE_FILE_HEADER @{ 220 | Machine = field 0 $ImageFileMachine 221 | NumberOfSections = field 1 UInt16 222 | TimeDateStamp = field 2 UInt32 223 | PointerToSymbolTable = field 3 UInt32 224 | NumberOfSymbols = field 4 UInt32 225 | SizeOfOptionalHeader = field 5 UInt16 226 | Characteristics = field 6 $ImageFileCharacteristics 227 | } 228 | 229 | $PeImageDataDir = struct $Mod PE.IMAGE_DATA_DIRECTORY @{ 230 | VirtualAddress = field 0 UInt32 231 | Size = field 1 UInt32 232 | } 233 | 234 | $ImageOptionalHdr = struct $Mod PE.IMAGE_OPTIONAL_HEADER @{ 235 | Magic = field 0 $ImageHdrMagic 236 | MajorLinkerVersion = field 1 Byte 237 | MinorLinkerVersion = field 2 Byte 238 | SizeOfCode = field 3 UInt32 239 | SizeOfInitializedData = field 4 UInt32 240 | SizeOfUninitializedData = field 5 UInt32 241 | AddressOfEntryPoint = field 6 UInt32 242 | BaseOfCode = field 7 UInt32 243 | BaseOfData = field 8 UInt32 244 | ImageBase = field 9 UInt32 245 | SectionAlignment = field 10 UInt32 246 | FileAlignment = field 11 UInt32 247 | MajorOperatingSystemVersion = field 12 UInt16 248 | MinorOperatingSystemVersion = field 13 UInt16 249 | MajorImageVersion = field 14 UInt16 250 | MinorImageVersion = field 15 UInt16 251 | MajorSubsystemVersion = field 16 UInt16 252 | MinorSubsystemVersion = field 17 UInt16 253 | Win32VersionValue = field 18 UInt32 254 | SizeOfImage = field 19 UInt32 255 | SizeOfHeaders = field 20 UInt32 256 | CheckSum = field 21 UInt32 257 | Subsystem = field 22 $ImageSubsystem 258 | DllCharacteristics = field 23 $ImageDllCharacteristics 259 | SizeOfStackReserve = field 24 UInt32 260 | SizeOfStackCommit = field 25 UInt32 261 | SizeOfHeapReserve = field 26 UInt32 262 | SizeOfHeapCommit = field 27 UInt32 263 | LoaderFlags = field 28 UInt32 264 | NumberOfRvaAndSizes = field 29 UInt32 265 | DataDirectory = field 30 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 266 | } 267 | 268 | $ImageOptionalHdr64 = struct $Mod PE.IMAGE_OPTIONAL_HEADER64 @{ 269 | Magic = field 0 $ImageHdrMagic 270 | MajorLinkerVersion = field 1 Byte 271 | MinorLinkerVersion = field 2 Byte 272 | SizeOfCode = field 3 UInt32 273 | SizeOfInitializedData = field 4 UInt32 274 | SizeOfUninitializedData = field 5 UInt32 275 | AddressOfEntryPoint = field 6 UInt32 276 | BaseOfCode = field 7 UInt32 277 | ImageBase = field 8 UInt64 278 | SectionAlignment = field 9 UInt32 279 | FileAlignment = field 10 UInt32 280 | MajorOperatingSystemVersion = field 11 UInt16 281 | MinorOperatingSystemVersion = field 12 UInt16 282 | MajorImageVersion = field 13 UInt16 283 | MinorImageVersion = field 14 UInt16 284 | MajorSubsystemVersion = field 15 UInt16 285 | MinorSubsystemVersion = field 16 UInt16 286 | Win32VersionValue = field 17 UInt32 287 | SizeOfImage = field 18 UInt32 288 | SizeOfHeaders = field 19 UInt32 289 | CheckSum = field 20 UInt32 290 | Subsystem = field 21 $ImageSubsystem 291 | DllCharacteristics = field 22 $ImageDllCharacteristics 292 | SizeOfStackReserve = field 23 UInt64 293 | SizeOfStackCommit = field 24 UInt64 294 | SizeOfHeapReserve = field 25 UInt64 295 | SizeOfHeapCommit = field 26 UInt64 296 | LoaderFlags = field 27 UInt32 297 | NumberOfRvaAndSizes = field 28 UInt32 298 | DataDirectory = field 29 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 299 | } 300 | 301 | $ImageSectionHdrs = struct $Mod PE.IMAGE_SECTION_HEADER @{ 302 | Name = field 0 String -MarshalAs @('ByValTStr', 8) 303 | VirtualSize = field 1 UInt32 304 | VirtualAddress = field 2 UInt32 305 | SizeOfRawData = field 3 UInt32 306 | PointerToRawData = field 4 UInt32 307 | PointerToRelocations = field 5 UInt32 308 | PointerToLinenumbers = field 6 UInt32 309 | NumberOfRelocations = field 7 UInt16 310 | NumberOfLinenumbers = field 8 UInt16 311 | Characteristics = field 9 $ImageScn 312 | } 313 | 314 | $ImageConfigDirectory = struct $Mod PE.IMAGE_LOAD_CONFIG_DIRECTORY @{ 315 | Size = field 0 UInt32 316 | TimeDateStamp = field 1 UInt32 317 | MajorVersion = field 2 UInt16 318 | MinorVersion = field 3 UInt16 319 | GlobalFlagsClear = field 4 UInt32 320 | GlobalFlagsSet = field 5 UInt32 321 | CriticalSectionDefaultTimeout = field 6 UInt32 322 | DeCommitFreeBlockThreshold = field 7 UInt32 323 | DeCommitTotalFreeThreshold = field 8 UInt32 324 | LockPrefixTable = field 9 UInt32 325 | MaximumAllocationSize = field 10 UInt32 326 | VirtualMemoryThreshold = field 11 UInt32 327 | ProcessHeapFlags = field 12 UInt32 328 | ProcessAffinityMask = field 13 UInt32 329 | CSDVersion = field 14 UInt16 330 | Reserved1 = field 15 UInt16 331 | EditList = field 16 UInt32 332 | SecurityCookie = field 17 UInt32 333 | SEHandlerTable = field 18 UInt32 334 | SEHandlerCount = field 19 UInt32 335 | GuardCFCheckFunctionPointer = field 20 UInt32 336 | GuardCFDispatchFunctionPointer = field 21 UInt32 337 | GuardCFFunctionTable = field 22 UInt32 338 | GuardCFFunctionCount = field 23 UInt32 339 | GuardFlags = field 24 UInt32 340 | CodeIntegrity = field 25 UInt32 341 | GuardAddressTakenIatEntryTable = field 26 UInt32 342 | GuardAddressTakenIatEntryCount = field 27 UInt32 343 | GuardLongJumpTargetTable = field 28 UInt32 344 | GuardLongJumpTargetCount = field 29 UInt32 345 | 346 | } 347 | 348 | $ImageNTHdrs = struct $Mod PE.IMAGE_NT_HEADERS @{ 349 | Signature = field 0 $ImageNTSig 350 | FileHeader = field 1 $ImageFileHeader 351 | OptionalHeader = field 2 $ImageOptionalHdr 352 | } 353 | 354 | $ImageNTHdrs64 = struct $Mod PE.IMAGE_NT_HEADERS64 @{ 355 | Signature = field 0 $ImageNTSig 356 | FileHeader = field 1 $ImageFileHeader 357 | OptionalHeader = field 2 $ImageOptionalHdr64 358 | } 359 | 360 | $FunctionDefinitions = @( 361 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String])), 362 | (func kernel32 GetModuleHandle ([Intptr]) @([String])), 363 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 364 | ) 365 | 366 | $Table = New-Object system.Data.DataTable 'table' 367 | $Col1 = New-Object system.Data.DataColumn FileName, ([string]) 368 | $Col2 = New-Object system.Data.DataColumn ARCH, ([string]) 369 | $Col3 = New-Object system.Data.DataColumn DotNET, ([string]) 370 | $Col4 = New-Object system.Data.DataColumn ASLR, ([string]) 371 | $Col5 = New-Object system.Data.DataColumn DEP, ([string]) 372 | $Col6 = New-Object system.Data.DataColumn Authenticode, ([string]) 373 | $Col7 = New-Object system.Data.DataColumn StrongNaming, ([string]) 374 | $Col8 = New-Object system.Data.DataColumn SafeSEH, ([string]) 375 | $Col9 = New-Object system.Data.DataColumn ControlFlowGuard, ([string]) 376 | $Col10 = New-Object system.Data.DataColumn HighentropyVA, ([string]) 377 | $Table.columns.add($Col1) 378 | $Table.columns.add($Col2) 379 | $Table.columns.add($Col3) 380 | $Table.columns.add($Col4) 381 | $Table.columns.add($Col5) 382 | $Table.columns.add($Col6) 383 | $Table.columns.add($Col7) 384 | $Table.columns.add($Col8) 385 | $Table.columns.add($Col9) 386 | $Table.columns.add($Col10) 387 | } 388 | Process 389 | { 390 | $Files = Get-Files 391 | Enumerate-Files $Files $Table 392 | 393 | $Table 394 | } 395 | End 396 | { 397 | } 398 | } 399 | 400 | function Enumerate-Files 401 | { 402 | param 403 | ( 404 | [System.Object] 405 | $Files, 406 | 407 | [System.Object] 408 | $Table 409 | ) 410 | 411 | foreach ($CurrentFile in $Files) 412 | { 413 | $DotNET = $false 414 | $ASLR = $false 415 | $HighentropyVA = $false 416 | $DEP = $false 417 | $SEH = $false 418 | $ControlFlowGuard = $false 419 | $Authenticode = $false 420 | $StrongNaming = $false 421 | 422 | # Determine file length 423 | $FileInfo = New-Object System.IO.FileInfo($CurrentFile) 424 | $FileLength = $FileInfo.length 425 | 426 | $FileStream = New-Object System.IO.FileStream($CurrentFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) 427 | $FileByteArray = New-Object Byte[]($FileStream.Length) 428 | $FileStream.Read($FileByteArray, 0, $FileStream.Length) | Out-Null 429 | $FileStream.Close() 430 | 431 | $Handle = [System.Runtime.InteropServices.GCHandle]::Alloc($FileByteArray, 'Pinned') 432 | $PEBaseAddr = $Handle.AddrOfPinnedObject() 433 | $DosHeader = $PEBaseAddr -as $ImageDosHeader 434 | if ($FileByteArray.Length -lt $DosHeader.e_lfanew) 435 | { 436 | continue 437 | } 438 | $PointerNtHeader = [IntPtr] ($PEBaseAddr.ToInt64() + $DosHeader.e_lfanew) 439 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs 440 | if ($NTHeader.OptionalHeader.Magic -eq 0){ 441 | $Row = $Table.NewRow() 442 | $Row.FileName = $CurrentFile 443 | $Row.ARCH = 'Unknown Format' 444 | $Row.DotNET = 'Unknown Format' 445 | $Row.ASLR = 'Unknown Format' 446 | $Row.HighentropyVA = 'Unknown Format' 447 | $Row.DEP = 'Unknown Format' 448 | $Row.Authenticode = 'Unknown Format' 449 | $Row.StrongNaming = 'Unknown Format' 450 | $Row.SafeSEH = 'Unknown Format' 451 | $Row.ControlFlowGuard = 'Unknown Format' 452 | $Table.Rows.Add($Row) 453 | Continue 454 | } 455 | if ($NTHeader.OptionalHeader.Magic -eq 'PE64') 456 | { 457 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs64 458 | } 459 | 460 | if($NTHeader.OptionalHeader.DataDirectory[14].VirtualAddress -ne 0) { 461 | $DotNet = $true 462 | } 463 | 464 | $ARCH = $NTHeader.FileHeader.Machine.toString() 465 | $FileCharacteristics = $NTHeader.FileHeader.Characteristics.toString().Split(',') 466 | $DllCharacteristics = $NTHeader.OptionalHeader.DllCharacteristics.toString().Split(',') 467 | $value = 0 468 | $ASLR = $false 469 | if([int32]::TryParse($DllCharacteristics, [ref]$value)){ 470 | if($value -band 0x20){ 471 | $HighentropyVA = $true 472 | } 473 | if($value -band 0x40){ 474 | $ASLR = $true 475 | } 476 | if($value -band 0x100){ 477 | $DEP = $true 478 | } 479 | 480 | if($value -band 0x400){ 481 | $SEH = 'N/A' 482 | } 483 | 484 | if($value -band 0x4000){ 485 | $ControlFlowGuard = $true 486 | } 487 | } else { 488 | foreach($DllCharacteristic in $DllCharacteristics) 489 | { 490 | switch($DllCharacteristic.Trim()){ 491 | 'DYNAMIC_BASE' 492 | { 493 | $ASLR = $true 494 | } 495 | 'NX_COMPAT' 496 | { 497 | $DEP = $true 498 | } 499 | 'NO_SEH' 500 | { 501 | $SEH = 'N/A' 502 | } 503 | 'GUARD_CF' 504 | { 505 | $ControlFlowGuard = $true 506 | } 507 | 'HIGH_ENTROPY_VA' 508 | { 509 | $HighentropyVA = $true 510 | } 511 | } 512 | } 513 | } 514 | 515 | if($ASLR){ 516 | foreach($FileCharacteristic in $FileCharacteristics){ 517 | switch($FileCharacteristic.Trim()){ 518 | 'IMAGE_RELOCS_STRIPPED' 519 | { 520 | $Stripped = $true 521 | } 522 | } 523 | } 524 | 525 | $OS = [Environment]::OSVersion 526 | $WindowsCheck = $true 527 | if($OS.Version.Build -ge 9200){ 528 | $WindowsCheck = $false 529 | } 530 | 531 | if($WindowsCheck){ 532 | if (-not $DotNet -and $Stripped){ 533 | $ASLR = 'False (DYNAMICBASE Set And Relocation Table Stripped)' 534 | } 535 | } 536 | } 537 | 538 | if ($DotNet) { 539 | $ControlFlowGuard = 'N/A' 540 | } 541 | 542 | #Get Strongnaming Status 543 | $StrongNaming = Get-StrongNamingStatus $CurrentFile 544 | 545 | #Get Authenticode Status 546 | $Authenticode = 'N/A' 547 | if(!$SkipAuthenticode) 548 | { 549 | $Authenticode = Get-AuthenticodeStatus $CurrentFile 550 | } 551 | 552 | if ($ARCH -eq 'AMD64') 553 | { 554 | $SEH = 'N/A' 555 | } 556 | if ($ARCH -ne 'AMD64') 557 | { 558 | $HighentropyVA = 'N/A' 559 | } 560 | if ($SEH -ne 'N/A') 561 | { 562 | #Get SEH Status 563 | $SEH = Get-SEHStatus $CurrentFile $NTHeader $PointerNtHeader $PEBaseAddr 564 | 565 | } 566 | 567 | #Write everything to a DataTable 568 | $Row = $Table.NewRow() 569 | $Row.FileName = $CurrentFile 570 | $Row.ARCH = $ARCH 571 | $Row.DotNET = $DotNET 572 | $Row.ASLR = $ASLR 573 | $Row.DEP = $DEP 574 | $Row.Authenticode = $Authenticode 575 | $Row.StrongNaming = $StrongNaming 576 | $Row.SafeSEH = $SEH 577 | $Row.ControlFlowGuard = $ControlFlowGuard 578 | $Row.HighentropyVA = $HighentropyVA 579 | $Table.Rows.Add($Row) 580 | } 581 | } 582 | 583 | function Get-AuthenticodeStatus 584 | { 585 | param 586 | ( 587 | [System.Object] 588 | $CurrentFile 589 | 590 | ) 591 | 592 | $Status = Get-AuthenticodeSignature $CurrentFile | Select-Object -ExpandProperty Status 593 | 594 | if ($Status -eq 'Valid') 595 | { 596 | $Authenticode = $true 597 | } 598 | else 599 | { 600 | $Authenticode = $false 601 | } 602 | $Authenticode 603 | } 604 | 605 | function Get-SEHStatus 606 | { 607 | param 608 | ( 609 | [System.Object] 610 | $CurrentFile, 611 | 612 | [System.Object] 613 | $NTHeader, 614 | 615 | [System.Object] 616 | $PointerNtHeader, 617 | 618 | [System.Object] 619 | $PEBaseAddr 620 | ) 621 | $NumSections = $NTHeader.FileHeader.NumberOfSections 622 | $PointerSectionHeader = [IntPtr] ($PointerNtHeader.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageNTHdrs)) 623 | #Create an array of SectionHeaders 624 | $SectionHeaders = @(New-Object $ImageSectionHdrs) * $NumSections 625 | 626 | foreach ($i in 0..($NumSections - 1)) 627 | { 628 | $SectionHeaders[$i] = [System.Runtime.InteropServices.Marshal]::PtrToStructure(([IntPtr] ($PointerSectionHeader.ToInt64() + ($i * [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageSectionHdrs)))), [System.Type] $ImageSectionHdrs) 629 | } 630 | $ConfigPointer = [IntPtr] ($PEBaseAddr.ToInt64() + $NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress) 631 | $ConfigPointer = Convert-RVAToFileOffset $ConfigPointer 632 | $ConfigDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStructure([IntPtr] $ConfigPointer, [System.Type] $ImageConfigDirectory) 633 | $SEHandlerTable = $ConfigDirectory.SEHandlerTable 634 | $SEHandlerCount = $ConfigDirectory.SEHandlerCount 635 | 636 | if($NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress -eq 0) 637 | { 638 | $SEH = $false 639 | } 640 | elseif($ConfigDirectory.Size -lt 72) 641 | { 642 | $SEH = $false 643 | } 644 | elseif($SEHandlerTable -ne 0 -and $SEHandlerCount -ne 0) 645 | { 646 | $SEH = $true 647 | } 648 | elseif($SEHandlerTable -eq 0 -or $SEHandlerCount -eq 0) 649 | { 650 | $SEH = $false 651 | } 652 | $SEH 653 | } 654 | 655 | function Get-StrongNamingStatus 656 | { 657 | param 658 | ( 659 | [System.Object] 660 | $CurrentFile 661 | ) 662 | 663 | try 664 | { 665 | $StongNaming = [System.Reflection.AssemblyName]::GetAssemblyName($CurrentFile).GetPublicKeyToken().Count -gt 0 666 | } 667 | catch 668 | { 669 | $StongNaming = 'N/A' 670 | } 671 | $StongNaming 672 | } 673 | 674 | function Get-GS { 675 | } 676 | 677 | function Get-Files 678 | { 679 | $Files = @() 680 | if($Directory) 681 | { 682 | $Files += Get-FilesFromDirectory 683 | } 684 | if($File) 685 | { 686 | $Files += Get-ChildItem $File 687 | } 688 | $Files 689 | } 690 | 691 | function Get-FilesFromDirectory 692 | { 693 | if($Recursive) 694 | { 695 | Get-ChildItem -Path "$Directory\*" -Recurse -Include *.exe, *.dll | ForEach-Object { 696 | $Files += $_ 697 | } 698 | } 699 | else 700 | { 701 | Get-ChildItem -Path "$Directory\*" -Include *.exe, *.dll |ForEach-Object { 702 | $Files += $_ 703 | } 704 | } 705 | $Files 706 | } 707 | 708 | function Convert-RVAToFileOffset 709 | { 710 | #Author: Matthew Graeber (@mattifestation) 711 | param 712 | ( 713 | [IntPtr] 714 | $Rva 715 | ) 716 | 717 | foreach ($Section in $SectionHeaders) 718 | { 719 | if ((($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -ge $Section.VirtualAddress) -and (($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -lt ($Section.VirtualAddress + $Section.VirtualSize))) 720 | { 721 | return [IntPtr] ($Rva.ToInt64() - ($Section.VirtualAddress - $Section.PointerToRawData)) 722 | } 723 | } 724 | 725 | $Rva 726 | } 727 | 728 | <# 729 | The following functions are from Matt Graeber's method of PSReflection 730 | https://github.com/mattifestation/PSReflect 731 | #> 732 | 733 | function func 734 | { 735 | #Author: Matthew Graeber (@mattifestation) 736 | Param 737 | ( 738 | [Parameter(Position = 0, Mandatory = $true)] 739 | [String] 740 | $DllName, 741 | 742 | [Parameter(Position = 1, Mandatory = $true)] 743 | [string] 744 | $FunctionName, 745 | 746 | [Parameter(Position = 2, Mandatory = $true)] 747 | [Type] 748 | $ReturnType, 749 | 750 | [Parameter(Position = 3)] 751 | [Type[]] 752 | $ParameterTypes, 753 | 754 | [Parameter(Position = 4)] 755 | [Runtime.InteropServices.CallingConvention] 756 | $NativeCallingConvention, 757 | 758 | [Parameter(Position = 5)] 759 | [Runtime.InteropServices.CharSet] 760 | $Charset, 761 | 762 | [Switch] 763 | $SetLastError 764 | ) 765 | 766 | $Properties = @{ 767 | DllName = $DllName 768 | FunctionName = $FunctionName 769 | ReturnType = $ReturnType 770 | } 771 | 772 | if ($ParameterTypes) 773 | { 774 | $Properties['ParameterTypes'] = $ParameterTypes 775 | } 776 | if ($NativeCallingConvention) 777 | { 778 | $Properties['NativeCallingConvention'] = $NativeCallingConvention 779 | } 780 | if ($Charset) 781 | { 782 | $Properties['Charset'] = $Charset 783 | } 784 | if ($SetLastError) 785 | { 786 | $Properties['SetLastError'] = $SetLastError 787 | } 788 | 789 | New-Object PSObject -Property $Properties 790 | } 791 | 792 | function enumerate 793 | { 794 | <# 795 | Author: Matthew Graeber (@mattifestation) 796 | .SYNOPSIS 797 | 798 | Creates an in-memory enumeration for use in your PowerShell session. 799 | 800 | Author: Matthew Graeber (@mattifestation) 801 | License: BSD 3-Clause 802 | Required Dependencies: None 803 | Optional Dependencies: None 804 | 805 | .DESCRIPTION 806 | 807 | The 'enum' function facilitates the creation of enums entirely in 808 | memory using as close to a "C style" as PowerShell will allow. 809 | 810 | .PARAMETER Module 811 | 812 | The in-memory module that will host the enum. Use 813 | New-InMemoryModule to define an in-memory module. 814 | 815 | .PARAMETER FullName 816 | 817 | The fully-qualified name of the enum. 818 | 819 | .PARAMETER Type 820 | 821 | The type of each enum element. 822 | 823 | .PARAMETER EnumElements 824 | 825 | A hashtable of enum elements. 826 | 827 | .PARAMETER Bitfield 828 | 829 | Specifies that the enum should be treated as a bitfield. 830 | 831 | .EXAMPLE 832 | 833 | $Mod = New-InMemoryModule -ModuleName Win32 834 | 835 | $ImageSubsystem = enum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 836 | UNKNOWN = 0 837 | NATIVE = 1 # Image doesn't require a subsystem. 838 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 839 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 840 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 841 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 842 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 843 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 844 | EFI_APPLICATION = 10 845 | EFI_BOOT_SERVICE_DRIVER = 11 846 | EFI_RUNTIME_DRIVER = 12 847 | EFI_ROM = 13 848 | XBOX = 14 849 | WINDOWS_BOOT_APPLICATION = 16 850 | } 851 | 852 | .NOTES 853 | 854 | PowerShell purists may disagree with the naming of this function but 855 | again, this was developed in such a way so as to emulate a "C style" 856 | definition as closely as possible. Sorry, I'm not going to name it 857 | New-Enum. :P 858 | #> 859 | 860 | [OutputType([Type])] 861 | Param 862 | ( 863 | [Parameter(Position = 0, Mandatory = $true)] 864 | [Reflection.Emit.ModuleBuilder] 865 | $Module, 866 | 867 | [Parameter(Position = 1, Mandatory = $true)] 868 | [ValidateNotNullOrEmpty()] 869 | [String] 870 | $FullName, 871 | 872 | [Parameter(Position = 2, Mandatory = $true)] 873 | [Type] 874 | $Type, 875 | 876 | [Parameter(Position = 3, Mandatory = $true)] 877 | [ValidateNotNullOrEmpty()] 878 | [Hashtable] 879 | $EnumElements, 880 | 881 | [Switch] 882 | $Bitfield 883 | ) 884 | 885 | $EnumType = $Type -as [Type] 886 | 887 | $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType) 888 | 889 | if ($Bitfield) 890 | { 891 | $FlagsConstructor = [FlagsAttribute].GetConstructor(@()) 892 | $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) 893 | $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) 894 | } 895 | 896 | foreach ($Key in $EnumElements.Keys) 897 | { 898 | # Apply the specified enum type to each element 899 | $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType) 900 | } 901 | 902 | $EnumBuilder.CreateType() 903 | } 904 | 905 | function struct 906 | { 907 | <# 908 | Author: Matthew Graeber (@mattifestation) 909 | .SYNOPSIS 910 | 911 | Creates an in-memory struct for use in your PowerShell session. 912 | 913 | Author: Matthew Graeber (@mattifestation) 914 | License: BSD 3-Clause 915 | Required Dependencies: None 916 | Optional Dependencies: field 917 | 918 | .DESCRIPTION 919 | 920 | The 'struct' function facilitates the creation of structs entirely in 921 | memory using as close to a "C style" as PowerShell will allow. Struct 922 | fields are specified using a hashtable where each field of the struct 923 | is comprosed of the order in which it should be defined, its .NET 924 | type, and optionally, its offset and special marshaling attributes. 925 | 926 | One of the features of 'struct' is that after your struct is defined, 927 | it will come with a built-in GetSize method as well as an explicit 928 | converter so that you can easily cast an IntPtr to the struct without 929 | relying upon calling SizeOf and/or PtrToStructure in the Marshal 930 | class. 931 | 932 | .PARAMETER Module 933 | 934 | The in-memory module that will host the struct. Use 935 | New-InMemoryModule to define an in-memory module. 936 | 937 | .PARAMETER FullName 938 | 939 | The fully-qualified name of the struct. 940 | 941 | .PARAMETER StructFields 942 | 943 | A hashtable of fields. Use the 'field' helper function to ease 944 | defining each field. 945 | 946 | .PARAMETER PackingSize 947 | 948 | Specifies the memory alignment of fields. 949 | 950 | .PARAMETER ExplicitLayout 951 | 952 | Indicates that an explicit offset for each field will be specified. 953 | 954 | .EXAMPLE 955 | 956 | $Mod = New-InMemoryModule -ModuleName Win32 957 | 958 | $ImageDosSignature = enum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 959 | DOS_SIGNATURE = 0x5A4D 960 | OS2_SIGNATURE = 0x454E 961 | OS2_SIGNATURE_LE = 0x454C 962 | VXD_SIGNATURE = 0x454C 963 | } 964 | 965 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 966 | e_magic = field 0 $ImageDosSignature 967 | e_cblp = field 1 UInt16 968 | e_cp = field 2 UInt16 969 | e_crlc = field 3 UInt16 970 | e_cparhdr = field 4 UInt16 971 | e_minalloc = field 5 UInt16 972 | e_maxalloc = field 6 UInt16 973 | e_ss = field 7 UInt16 974 | e_sp = field 8 UInt16 975 | e_csum = field 9 UInt16 976 | e_ip = field 10 UInt16 977 | e_cs = field 11 UInt16 978 | e_lfarlc = field 12 UInt16 979 | e_ovno = field 13 UInt16 980 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 981 | e_oemid = field 15 UInt16 982 | e_oeminfo = field 16 UInt16 983 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 984 | e_lfanew = field 18 Int32 985 | } 986 | 987 | # Example of using an explicit layout in order to create a union. 988 | $TestUnion = struct $Mod TestUnion @{ 989 | field1 = field 0 UInt32 0 990 | field2 = field 1 IntPtr 0 991 | } -ExplicitLayout 992 | 993 | .NOTES 994 | 995 | PowerShell purists may disagree with the naming of this function but 996 | again, this was developed in such a way so as to emulate a "C style" 997 | definition as closely as possible. Sorry, I'm not going to name it 998 | New-Struct. :P 999 | #> 1000 | [OutputType([Type])] 1001 | Param 1002 | ( 1003 | [Parameter(Position = 1, Mandatory = $true)] 1004 | [Reflection.Emit.ModuleBuilder] 1005 | $Module, 1006 | 1007 | [Parameter(Position = 2, Mandatory = $true)] 1008 | [ValidateNotNullOrEmpty()] 1009 | [String] 1010 | $FullName, 1011 | 1012 | [Parameter(Position = 3, Mandatory = $true)] 1013 | [ValidateNotNullOrEmpty()] 1014 | [Hashtable] 1015 | $StructFields, 1016 | 1017 | [Reflection.Emit.PackingSize] 1018 | $PackingSize = [Reflection.Emit.PackingSize]::Unspecified, 1019 | 1020 | [Switch] 1021 | $ExplicitLayout 1022 | ) 1023 | 1024 | [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass, 1025 | Class, 1026 | Public, 1027 | Sealed, 1028 | BeforeFieldInit' 1029 | 1030 | if ($ExplicitLayout) 1031 | { 1032 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout 1033 | } 1034 | else 1035 | { 1036 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout 1037 | } 1038 | 1039 | $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize) 1040 | $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] 1041 | $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) 1042 | 1043 | $Fields = New-Object Hashtable[]($StructFields.Count) 1044 | 1045 | # Sort each field according to the orders specified 1046 | # Unfortunately, PSv2 doesn't have the luxury of the 1047 | # hashtable [Ordered] accelerator. 1048 | foreach ($Field in $StructFields.Keys) 1049 | { 1050 | $Index = $StructFields[$Field]['Position'] 1051 | $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]} 1052 | } 1053 | 1054 | foreach ($Field in $Fields) 1055 | { 1056 | $FieldName = $Field['FieldName'] 1057 | $FieldProp = $Field['Properties'] 1058 | 1059 | $Offset = $FieldProp['Offset'] 1060 | $Type = $FieldProp['Type'] 1061 | $MarshalAs = $FieldProp['MarshalAs'] 1062 | 1063 | $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public') 1064 | 1065 | if ($MarshalAs) 1066 | { 1067 | $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType]) 1068 | $Size = $MarshalAs[1] 1069 | $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, 1070 | $UnmanagedType, $SizeConst, @($Size)) 1071 | $NewField.SetCustomAttribute($AttribBuilder) 1072 | } 1073 | 1074 | if ($ExplicitLayout) 1075 | { 1076 | $NewField.SetOffset($Offset) 1077 | } 1078 | } 1079 | 1080 | # Make the struct aware of its own size. 1081 | # No more having to call [Runtime.InteropServices.Marshal]::SizeOf! 1082 | $SizeMethod = $StructBuilder.DefineMethod('GetSize', 1083 | 'Public, Static', 1084 | [Int], 1085 | [Type[]] @()) 1086 | $ILGenerator = $SizeMethod.GetILGenerator() 1087 | # Thanks for the help, Jason Shirk! 1088 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1089 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1090 | [Type].GetMethod('GetTypeFromHandle')) 1091 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1092 | [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type]))) 1093 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret) 1094 | 1095 | # Allow for explicit casting from an IntPtr 1096 | # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure! 1097 | $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit', 1098 | 'PrivateScope, Public, Static, HideBySig, SpecialName', 1099 | $StructBuilder, 1100 | [Type[]] @([IntPtr])) 1101 | $ILGenerator2 = $ImplicitConverter.GetILGenerator() 1102 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop) 1103 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 1104 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1105 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1106 | [Type].GetMethod('GetTypeFromHandle')) 1107 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1108 | [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type]))) 1109 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder) 1110 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret) 1111 | 1112 | $StructBuilder.CreateType() 1113 | } 1114 | 1115 | function field 1116 | { 1117 | #Author: Matthew Graeber (@mattifestation) 1118 | Param 1119 | ( 1120 | [Parameter(Position = 0, Mandatory = $true)] 1121 | [UInt16] 1122 | $Position, 1123 | 1124 | [Parameter(Position = 1, Mandatory = $true)] 1125 | [Type] 1126 | $Type, 1127 | 1128 | [Parameter(Position = 2)] 1129 | [UInt16] 1130 | $Offset, 1131 | 1132 | [Object[]] 1133 | $MarshalAs 1134 | ) 1135 | 1136 | @{ 1137 | Position = $Position 1138 | Type = $Type -as [Type] 1139 | Offset = $Offset 1140 | MarshalAs = $MarshalAs 1141 | } 1142 | } 1143 | 1144 | function Add-Win32Type 1145 | { 1146 | <# 1147 | Author: Matthew Graeber (@mattifestation) 1148 | .SYNOPSIS 1149 | 1150 | Creates a .NET type for an unmanaged Win32 function. 1151 | 1152 | Author: Matthew Graeber (@mattifestation) 1153 | License: BSD 3-Clause 1154 | Required Dependencies: None 1155 | Optional Dependencies: func 1156 | 1157 | .DESCRIPTION 1158 | 1159 | Add-Win32Type enables you to easily interact with unmanaged (i.e. 1160 | Win32 unmanaged) functions in PowerShell. After providing 1161 | Add-Win32Type with a function signature, a .NET type is created 1162 | using reflection (i.e. csc.exe is never called like with Add-Type). 1163 | 1164 | The 'func' helper function can be used to reduce typing when defining 1165 | multiple function definitions. 1166 | 1167 | .PARAMETER DllName 1168 | 1169 | The name of the DLL. 1170 | 1171 | .PARAMETER FunctionName 1172 | 1173 | The name of the target function. 1174 | 1175 | .PARAMETER ReturnType 1176 | 1177 | The return type of the function. 1178 | 1179 | .PARAMETER ParameterTypes 1180 | 1181 | The function parameters. 1182 | 1183 | .PARAMETER NativeCallingConvention 1184 | 1185 | Specifies the native calling convention of the function. Defaults to 1186 | stdcall. 1187 | 1188 | .PARAMETER Charset 1189 | 1190 | If you need to explicitly call an 'A' or 'W' Win32 function, you can 1191 | specify the character set. 1192 | 1193 | .PARAMETER SetLastError 1194 | 1195 | Indicates whether the callee calls the SetLastError Win32 API 1196 | function before returning from the attributed method. 1197 | 1198 | .PARAMETER Module 1199 | 1200 | The in-memory module that will host the functions. Use 1201 | New-InMemoryModule to define an in-memory module. 1202 | 1203 | .PARAMETER Namespace 1204 | 1205 | An optional namespace to prepend to the type. Add-Win32Type defaults 1206 | to a namespace consisting only of the name of the DLL. 1207 | 1208 | .EXAMPLE 1209 | 1210 | $Mod = New-InMemoryModule -ModuleName Win32 1211 | 1212 | $FunctionDefinitions = @( 1213 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError), 1214 | (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError), 1215 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 1216 | ) 1217 | 1218 | $Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' 1219 | $Kernel32 = $Types['kernel32'] 1220 | $Ntdll = $Types['ntdll'] 1221 | $Ntdll::RtlGetCurrentPeb() 1222 | $ntdllbase = $Kernel32::GetModuleHandle('ntdll') 1223 | $Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb') 1224 | 1225 | .NOTES 1226 | 1227 | Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189 1228 | 1229 | When defining multiple function prototypes, it is ideal to provide 1230 | Add-Win32Type with an array of function signatures. That way, they 1231 | are all incorporated into the same in-memory module. 1232 | #> 1233 | [OutputType([Hashtable])] 1234 | Param( 1235 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1236 | [String] 1237 | $DllName, 1238 | 1239 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1240 | [String] 1241 | $FunctionName, 1242 | 1243 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1244 | [Type] 1245 | $ReturnType, 1246 | 1247 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1248 | [Type[]] 1249 | $ParameterTypes, 1250 | 1251 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1252 | [Runtime.InteropServices.CallingConvention] 1253 | $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall, 1254 | 1255 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1256 | [Runtime.InteropServices.CharSet] 1257 | $Charset = [Runtime.InteropServices.CharSet]::Auto, 1258 | 1259 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1260 | [Switch] 1261 | $SetLastError, 1262 | 1263 | [Parameter(Mandatory = $true)] 1264 | [Reflection.Emit.ModuleBuilder] 1265 | $Module, 1266 | 1267 | [ValidateNotNull()] 1268 | [String] 1269 | $Namespace = '' 1270 | ) 1271 | 1272 | BEGIN 1273 | { 1274 | $TypeHash = @{} 1275 | } 1276 | 1277 | PROCESS 1278 | { 1279 | # Define one type for each DLL 1280 | if (!$TypeHash.ContainsKey($DllName)) 1281 | { 1282 | if ($Namespace) 1283 | { 1284 | $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit') 1285 | } 1286 | else 1287 | { 1288 | $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit') 1289 | } 1290 | } 1291 | 1292 | $Method = $TypeHash[$DllName].DefineMethod( 1293 | $FunctionName, 1294 | 'Public,Static,PinvokeImpl', 1295 | $ReturnType, 1296 | $ParameterTypes) 1297 | 1298 | # Make each ByRef parameter an Out parameter 1299 | $i = 1 1300 | foreach($Parameter in $ParameterTypes) 1301 | { 1302 | if ($Parameter.IsByRef) 1303 | { 1304 | [void] $Method.DefineParameter($i, 'Out', $null) 1305 | } 1306 | 1307 | $i++ 1308 | } 1309 | 1310 | $DllImport = [Runtime.InteropServices.DllImportAttribute] 1311 | $SetLastErrorField = $DllImport.GetField('SetLastError') 1312 | $CallingConventionField = $DllImport.GetField('CallingConvention') 1313 | $CharsetField = $DllImport.GetField('CharSet') 1314 | if ($SetLastError) 1315 | { 1316 | $SLEValue = $true 1317 | } 1318 | else 1319 | { 1320 | $SLEValue = $false 1321 | } 1322 | 1323 | # Equivalent to C# version of [DllImport(DllName)] 1324 | $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String]) 1325 | $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor, 1326 | $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(), 1327 | [Reflection.FieldInfo[]] @($SetLastErrorField, $CallingConventionField, $CharsetField), 1328 | [Object[]] @($SLEValue, ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention), ([Runtime.InteropServices.CharSet] $Charset))) 1329 | 1330 | $Method.SetCustomAttribute($DllImportAttribute) 1331 | } 1332 | 1333 | END 1334 | { 1335 | $ReturnTypes = @{} 1336 | 1337 | foreach ($Key in $TypeHash.Keys) 1338 | { 1339 | $Type = $TypeHash[$Key].CreateType() 1340 | 1341 | $ReturnTypes[$Key] = $Type 1342 | } 1343 | 1344 | return $ReturnTypes 1345 | } 1346 | } 1347 | 1348 | # ///////////////////////////////////////////////////// 1349 | # Get-FileMd5 1350 | # ///////////////////////////////////////////////////// 1351 | function Get-FileMd5{ 1352 | 1353 | param ( 1354 | [string]$FilePath 1355 | ) 1356 | 1357 | $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider 1358 | $stream = [System.IO.File]::Open("$FilePath",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read) 1359 | $hash = [System.BitConverter]::ToString($md5.ComputeHash($stream)) 1360 | $stream.Close() 1361 | $hash.tostring().replace('-','').trim() 1362 | } 1363 | 1364 | 1365 | # /////////////////////////////////////// 1366 | # Get windows service information 1367 | # /////////////////////////////////////// 1368 | 1369 | Get-WmiObject -Class win32_service | Select Name,ServiceName,Description,PathName,ServiceType,StartMode,Status,InstallDate,StartName | 1370 | foreach { 1371 | 1372 | # Parse exe path 1373 | if ($_.pathname -like "*`"*"){ 1374 | $ExePath = $_.pathname -split("`"") 1375 | $TargetPath = "`"" + $ExePath[1] + "`"" 1376 | #$TargetPath 1377 | }else{ 1378 | $ExePath = $_.pathname -split(".exe") 1379 | $TargetPath = "`"" + $ExePath[0] + ".exe`"" 1380 | #$TargetPath 1381 | } 1382 | 1383 | $TargetPath = $TargetPath -Replace('"','') 1384 | 1385 | # Grab PE info 1386 | $PEConfig = Get-PESecurity -File $TargetPath 1387 | $ARCH = $PEConfig.ARCH 1388 | $ASLR = $PEConfig.ASLR 1389 | $Authenticode = $PEConfig.Authenticode 1390 | $ControlFlowGuard = $PEConfig.ControlFlowGuard 1391 | $DEP = $PEConfig.DEP 1392 | $DotNET = $PEConfig.DotNET 1393 | $HighentropyVA = $PEConfig.HighentropyVA 1394 | $SafeSEH = $PEConfig.SafeSEH 1395 | $StrongNaming = $PEConfig.StrongNaming 1396 | $FileHash = Get-FileMd5 "$TargetPath" 1397 | 1398 | # Grab file meta data info 1399 | $FileInfo = Get-Item $TargetPath 1400 | 1401 | # Create new object to return 1402 | $Object = New-Object PSObject 1403 | $Object | add-member DataSource1 "service" 1404 | $Object | add-member DataSource2 "Get-WmiObject -Class win32_service" 1405 | $Object | add-member ServiceName $_.Name 1406 | $Object | add-member Description $_.Description 1407 | $Object | add-member ServiceType $_.ServiceType 1408 | $Object | add-member StartMode $_.StartMode 1409 | $Object | add-member Status $_.Status 1410 | $Object | add-member InstallDate $_.InstallDate 1411 | $Object | add-member ServiceAccount $_.startname 1412 | $Object | add-member PathName $_.PathName 1413 | $Object | add-member FilePath $TargetPath 1414 | $Object | add-member FileMd5Hash $FileHash 1415 | $Object | add-member FileOwner $FileInfo.GetAccessControl().Owner 1416 | $Object | add-member FileCreationTime $FileInfo.CreationTime 1417 | $Object | add-member FileLastWriteTime $FileInfo.LastWriteTime 1418 | $Object | add-member FileLastAccessTime $FileInfo.LastAccessTime 1419 | $Object | add-member ARCH $ARCH 1420 | $Object | add-member ASLR $ASLR 1421 | $Object | add-member Authenticode $Authenticode 1422 | $Object | add-member ControlFlowGuard $ControlFlowGuard 1423 | $Object | add-member DEP $DEP 1424 | $Object | add-member DotNET $DotNET 1425 | $Object | add-member HighentropyVA $HighentropyVA 1426 | $Object | add-member SafeSEH $SafeSEH 1427 | $Object | add-member StrongNaming $StrongNaming 1428 | 1429 | $Object 1430 | } -------------------------------------------------------------------------------- /windows/modules/collection/collect-015-01-users.ps1: -------------------------------------------------------------------------------- 1 | 2 | # Script : Invoke-PowerHunt 3 | # Module : collect-users 4 | # Version: 1.0 5 | # Author : Scott Sutherland 6 | # Summary: This is script is part of the PowerHunt framework and collect connection information. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get list of users 11 | Get-LocalUser 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-016-01-wmi-bindings.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-wmi-bindings 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Author : Alexander Polce Leary 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get WMI bindings 11 | Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding | 12 | foreach{ 13 | 14 | # Grab value from binding 15 | $Filter = $_.Filter -replace('__EventFilter.Name="','') -replace('"','') 16 | $Consumer = $_.Consumer -replace('NTEventLogEventConsumer.Name=','') -replace('"','') 17 | 18 | # Get wmi filter information 19 | $FilterInfo = Get-WmiObject -Namespace root/subscription -Class __EventFilter | where name -like "$Filter" 20 | 21 | # Get wmi consumer information 22 | $ConsumerInfo = Get-WmiObject -Namespace root/subscription -Class __EventConsumer | where name -like "$Consumer" 23 | 24 | # Create new object to return 25 | $Object = New-Object PSObject 26 | 27 | # Filter info 28 | $object | add-member FilterName $Filter 29 | $object | add-member FilterQuery $FilterInfo.Query 30 | $object | add-member FilterLanguage $FilterInfo.QueryLanguage 31 | $object | add-member FilterEventAccess $FilterInfo.EventAccess 32 | $object | add-member FilterCreatorSide (New-Object System.Security.Principal.SecurityIdentifier($FilterInfo.creatorsid,0)).Value 33 | 34 | # Consumer info 35 | $object | add-member ConsumerName $Consumer 36 | $object | add-member ConsumerSourceName $ConsumerInfo.SourceName 37 | $object | add-member ConsumerInsertionStringTemplates $ConsumerInfo.InsertionStringTemplates 38 | $object | add-member ConsumerEventID $ConsumerInfo.EventID 39 | $object | add-member ConsumerEventType $ConsumerInfo.EventType 40 | $object | add-member ConsumerUncServerName $ConsumerInfo.UncServerName 41 | $object | add-member ConsumerCreatorSide (New-Object System.Security.Principal.SecurityIdentifier($ConsumerInfo.creatorsid,0)).Value 42 | 43 | # Binding info 44 | $object | add-member BindingCreatorSid (New-Object System.Security.Principal.SecurityIdentifier($_.creatorsid,0)).Value 45 | $object | add-member __PATH $_.__PATH 46 | $object | add-member __RELPATH $_.__RELPATH 47 | $object | add-member __GENUS $_.__GENUS 48 | $object | add-member __CLASS $_.__CLASS 49 | $object | add-member __SUPERCLASS $_.__SUPERCLASS 50 | $object | add-member __DYNASTY $_.__DYNASTY 51 | $object | add-member __PROPERTY_COUNT $_.__PROPERTY_COUNT 52 | $object | add-member __DERIVATION $_.__DERIVATION 53 | $object | add-member __SERVER $_.__SERVER 54 | $object | add-member __NAMESPACE $_.__NAMESPACE 55 | $object | add-member SlowDownProviders $_.SlowDownProviders 56 | $object | add-member MaintainSecurityContext $_.MaintainSecurityContext 57 | $object | add-member DeliveryQoS $_.DeliveryQoS 58 | $object | add-member DeliverSynchronously $_.DeliverSynchronously 59 | 60 | $Object 61 | } -------------------------------------------------------------------------------- /windows/modules/collection/collect-016-02-wmi-consumers.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-wmi-consumers 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Author : Alexander Polce Leary 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get wmi consumer information 11 | Get-WmiObject -Namespace root/subscription -Class __EventConsumer 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-016-03-wmi-filters.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-wmi-filters 3 | # Version: 1.0 4 | # Author : Scott Sutherland 5 | # Author : Alexander Polce Leary 6 | # Summary: This is script is part of the PowerHunt framework. 7 | # License: 3-clause BSD 8 | 9 | 10 | # Get wmi filter information 11 | Get-WmiObject -Namespace root/subscription -Class __EventFilter 12 | -------------------------------------------------------------------------------- /windows/modules/collection/collect-017-04-wmi-providers.ps1: -------------------------------------------------------------------------------- 1 | # Script : Invoke-PowerHunt 2 | # Module : collect-wmi-providers 3 | # Version: 1.1 4 | # Author : Scott Sutherland 5 | # Author : Eric Gruber (Get-PESecurity) 6 | # https://github.com/NetSPI/PESecurity/blob/master/Get-PESecurity.psm1 7 | # Summary: This is script is part of the PowerHunt framework 8 | # and is used to collect wmi provider data. 9 | # License: 3-clause BSD 10 | 11 | 12 | # /////////////////////////////////////// 13 | # Load Get-PESecurity 14 | # /////////////////////////////////////// 15 | # Source: https://github.com/NetSPI/PESecurity/blob/master/Get-PESecurity.psm1 16 | 17 | function Get-PESecurity 18 | { 19 | [CmdletBinding()] 20 | Param 21 | ( 22 | # Directory to scan 23 | [Parameter(Mandatory = $false, 24 | ValueFromPipelineByPropertyName = $true, 25 | Position = 0)] 26 | [String]$Directory, 27 | 28 | # File to scan 29 | [Parameter(Mandatory = $false, 30 | ValueFromPipelineByPropertyName = $true, 31 | Position = 0)] 32 | [String]$File, 33 | 34 | #Recursive flag 35 | [Parameter(Mandatory = $false, 36 | ValueFromPipelineByPropertyName = $false, 37 | Position = 1)] 38 | [Switch]$Recursive, 39 | 40 | #Skip Authenticode 41 | [Parameter(Mandatory = $false, 42 | ValueFromPipelineByPropertyName = $false, 43 | Position = 2)] 44 | [Switch]$SkipAuthenticode 45 | 46 | ) 47 | 48 | Begin 49 | { 50 | $ModuleName = 'Win32' 51 | $AssemblyName = [System.Reflection.AssemblyName]::new(${ModuleName}) 52 | $AssemblyAccess = [System.Reflection.Emit.AssemblyBuilderAccess]::Run 53 | if($PSVersionTable['PSEdition'] -eq 'Core') { 54 | $AssemblyBuilder = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 55 | } else 56 | { 57 | $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($AssemblyName, $AssemblyAccess) 58 | } 59 | $Mod = $AssemblyBuilder.DefineDynamicModule($ModuleName) 60 | 61 | $ImageDosSignature = enumerate $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 62 | DOS_SIGNATURE = 0x5A4D 63 | OS2_SIGNATURE = 0x454E 64 | OS2_SIGNATURE_LE = 0x454C 65 | VXD_SIGNATURE = 0x454C 66 | } 67 | 68 | $ImageFileMachine = enumerate $Mod PE.IMAGE_FILE_MACHINE UInt16 @{ 69 | UNKNOWN = 0x0000 70 | I386 = 0x014C # Intel 386. 71 | R3000 = 0x0162 # MIPS little-endian =0x160 big-endian 72 | R4000 = 0x0166 # MIPS little-endian 73 | R10000 = 0x0168 # MIPS little-endian 74 | WCEMIPSV2 = 0x0169 # MIPS little-endian WCE v2 75 | ALPHA = 0x0184 # Alpha_AXP 76 | SH3 = 0x01A2 # SH3 little-endian 77 | SH3DSP = 0x01A3 78 | SH3E = 0x01A4 # SH3E little-endian 79 | SH4 = 0x01A6 # SH4 little-endian 80 | SH5 = 0x01A8 # SH5 81 | ARM = 0x01C0 # ARM Little-Endian 82 | THUMB = 0x01C2 83 | ARMNT = 0x01C4 # ARM Thumb-2 Little-Endian 84 | AM33 = 0x01D3 85 | POWERPC = 0x01F0 # IBM PowerPC Little-Endian 86 | POWERPCFP = 0x01F1 87 | IA64 = 0x0200 # Intel 64 88 | MIPS16 = 0x0266 # MIPS 89 | ALPHA64 = 0x0284 # ALPHA64 90 | MIPSFPU = 0x0366 # MIPS 91 | MIPSFPU16 = 0x0466 # MIPS 92 | TRICORE = 0x0520 # Infineon 93 | CEF = 0x0CEF 94 | EBC = 0x0EBC # EFI public byte Code 95 | AMD64 = 0x8664 # AMD64 (K8) 96 | M32R = 0x9041 # M32R little-endian 97 | CEE = 0xC0EE 98 | } 99 | 100 | $ImageFileCharacteristics = enumerate $Mod PE.IMAGE_FILE_CHARACTERISTICS UInt16 @{ 101 | IMAGE_RELOCS_STRIPPED = 0x0001 # Relocation info stripped from file. 102 | IMAGE_EXECUTABLE_IMAGE = 0x0002 # File is executable (i.e. no unresolved external references). 103 | IMAGE_LINE_NUMS_STRIPPED = 0x0004 # Line nunbers stripped from file. 104 | IMAGE_LOCAL_SYMS_STRIPPED = 0x0008 # Local symbols stripped from file. 105 | IMAGE_AGGRESIVE_WS_TRIM = 0x0010 # Agressively trim working set 106 | IMAGE_LARGE_ADDRESS_AWARE = 0x0020 # App can handle >2gb addresses 107 | IMAGE_REVERSED_LO = 0x0080 # public bytes of machine public ushort are reversed. 108 | IMAGE_32BIT_MACHINE = 0x0100 # 32 bit public ushort machine. 109 | IMAGE_DEBUG_STRIPPED = 0x0200 # Debugging info stripped from file in .DBG file 110 | IMAGE_REMOVABLE_RUN_FROM_SWAP = 0x0400 # If Image is on removable media copy and run from the swap file. 111 | IMAGE_NET_RUN_FROM_SWAP = 0x0800 # If Image is on Net copy and run from the swap file. 112 | IMAGE_SYSTEM = 0x1000 # System File. 113 | IMAGE_DLL = 0x2000 # File is a DLL. 114 | IMAGE_UP_SYSTEM_ONLY = 0x4000 # File should only be run on a UP machine 115 | IMAGE_REVERSED_HI = 0x8000 # public bytes of machine public ushort are reversed. 116 | } -Bitfield 117 | 118 | $ImageHdrMagic = enumerate $Mod PE.IMAGE_NT_OPTIONAL_HDR_MAGIC UInt16 @{ 119 | PE32 = 0x010B 120 | PE64 = 0x020B 121 | } 122 | 123 | $ImageNTSig = enumerate $Mod PE.IMAGE_NT_SIGNATURE UInt32 @{ 124 | VALID_PE_SIGNATURE = 0x00004550 125 | } 126 | 127 | $ImageSubsystem = enumerate $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 128 | UNKNOWN = 0 129 | NATIVE = 1 # Image doesn't require a subsystem. 130 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 131 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 132 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 133 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 134 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 135 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 136 | EFI_APPLICATION = 10 137 | EFI_BOOT_SERVICE_DRIVER = 11 138 | EFI_RUNTIME_DRIVER = 12 139 | EFI_ROM = 13 140 | XBOX = 14 141 | WINDOWS_BOOT_APPLICATION = 16 142 | } 143 | 144 | $ImageDllCharacteristics = enumerate $Mod PE.IMAGE_DLLCHARACTERISTICS UInt16 @{ 145 | HIGH_ENTROPY_VA = 0x0020 # Opts in to high entropy ASLR 146 | DYNAMIC_BASE = 0x0040 # DLL can move. 147 | FORCE_INTEGRITY = 0x0080 # Code Integrity Image 148 | NX_COMPAT = 0x0100 # Image is NX compatible 149 | NO_ISOLATION = 0x0200 # Image understands isolation and doesn't want it 150 | NO_SEH = 0x0400 # Image does not use SEH. No SE handler may reside in this image 151 | NO_BIND = 0x0800 # Do not bind this image. 152 | WDM_DRIVER = 0x2000 # Driver uses WDM model 153 | GUARD_CF = 0x4000 # Control Flow Guard 154 | TERMINAL_SERVER_AWARE = 0x8000 155 | } -Bitfield 156 | 157 | $ImageScn = enumerate $Mod PE.IMAGE_SCN Int32 @{ 158 | TYPE_NO_PAD = 0x00000008 # Reserved. 159 | CNT_CODE = 0x00000020 # Section contains code. 160 | CNT_INITIALIZED_DATA = 0x00000040 # Section contains initialized data. 161 | CNT_UNINITIALIZED_DATA = 0x00000080 # Section contains uninitialized data. 162 | LNK_INFO = 0x00000200 # Section contains comments or some other type of information. 163 | LNK_REMOVE = 0x00000800 # Section contents will not become part of image. 164 | LNK_COMDAT = 0x00001000 # Section contents comdat. 165 | NO_DEFER_SPEC_EXC = 0x00004000 # Reset speculative exceptions handling bits in the TLB entries for this section. 166 | GPREL = 0x00008000 # Section content can be accessed relative to GP 167 | MEM_FARDATA = 0x00008000 168 | MEM_PURGEABLE = 0x00020000 169 | MEM_16BIT = 0x00020000 170 | MEM_LOCKED = 0x00040000 171 | MEM_PRELOAD = 0x00080000 172 | ALIGN_1BYTES = 0x00100000 173 | ALIGN_2BYTES = 0x00200000 174 | ALIGN_4BYTES = 0x00300000 175 | ALIGN_8BYTES = 0x00400000 176 | ALIGN_16BYTES = 0x00500000 # Default alignment if no others are specified. 177 | ALIGN_32BYTES = 0x00600000 178 | ALIGN_64BYTES = 0x00700000 179 | ALIGN_128BYTES = 0x00800000 180 | ALIGN_256BYTES = 0x00900000 181 | ALIGN_512BYTES = 0x00A00000 182 | ALIGN_1024BYTES = 0x00B00000 183 | ALIGN_2048BYTES = 0x00C00000 184 | ALIGN_4096BYTES = 0x00D00000 185 | ALIGN_8192BYTES = 0x00E00000 186 | ALIGN_MASK = 0x00F00000 187 | LNK_NRELOC_OVFL = 0x01000000 # Section contains extended relocations. 188 | MEM_DISCARDABLE = 0x02000000 # Section can be discarded. 189 | MEM_NOT_CACHED = 0x04000000 # Section is not cachable. 190 | MEM_NOT_PAGED = 0x08000000 # Section is not pageable. 191 | MEM_SHARED = 0x10000000 # Section is shareable. 192 | MEM_EXECUTE = 0x20000000 # Section is executable. 193 | MEM_READ = 0x40000000 # Section is readable. 194 | MEM_WRITE = 0x80000000 # Section is writeable. 195 | } -Bitfield 196 | 197 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 198 | e_magic = field 0 $ImageDosSignature 199 | e_cblp = field 1 UInt16 200 | e_cp = field 2 UInt16 201 | e_crlc = field 3 UInt16 202 | e_cparhdr = field 4 UInt16 203 | e_minalloc = field 5 UInt16 204 | e_maxalloc = field 6 UInt16 205 | e_ss = field 7 UInt16 206 | e_sp = field 8 UInt16 207 | e_csum = field 9 UInt16 208 | e_ip = field 10 UInt16 209 | e_cs = field 11 UInt16 210 | e_lfarlc = field 12 UInt16 211 | e_ovno = field 13 UInt16 212 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 213 | e_oemid = field 15 UInt16 214 | e_oeminfo = field 16 UInt16 215 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 216 | e_lfanew = field 18 Int32 217 | } 218 | 219 | $ImageFileHeader = struct $Mod PE.IMAGE_FILE_HEADER @{ 220 | Machine = field 0 $ImageFileMachine 221 | NumberOfSections = field 1 UInt16 222 | TimeDateStamp = field 2 UInt32 223 | PointerToSymbolTable = field 3 UInt32 224 | NumberOfSymbols = field 4 UInt32 225 | SizeOfOptionalHeader = field 5 UInt16 226 | Characteristics = field 6 $ImageFileCharacteristics 227 | } 228 | 229 | $PeImageDataDir = struct $Mod PE.IMAGE_DATA_DIRECTORY @{ 230 | VirtualAddress = field 0 UInt32 231 | Size = field 1 UInt32 232 | } 233 | 234 | $ImageOptionalHdr = struct $Mod PE.IMAGE_OPTIONAL_HEADER @{ 235 | Magic = field 0 $ImageHdrMagic 236 | MajorLinkerVersion = field 1 Byte 237 | MinorLinkerVersion = field 2 Byte 238 | SizeOfCode = field 3 UInt32 239 | SizeOfInitializedData = field 4 UInt32 240 | SizeOfUninitializedData = field 5 UInt32 241 | AddressOfEntryPoint = field 6 UInt32 242 | BaseOfCode = field 7 UInt32 243 | BaseOfData = field 8 UInt32 244 | ImageBase = field 9 UInt32 245 | SectionAlignment = field 10 UInt32 246 | FileAlignment = field 11 UInt32 247 | MajorOperatingSystemVersion = field 12 UInt16 248 | MinorOperatingSystemVersion = field 13 UInt16 249 | MajorImageVersion = field 14 UInt16 250 | MinorImageVersion = field 15 UInt16 251 | MajorSubsystemVersion = field 16 UInt16 252 | MinorSubsystemVersion = field 17 UInt16 253 | Win32VersionValue = field 18 UInt32 254 | SizeOfImage = field 19 UInt32 255 | SizeOfHeaders = field 20 UInt32 256 | CheckSum = field 21 UInt32 257 | Subsystem = field 22 $ImageSubsystem 258 | DllCharacteristics = field 23 $ImageDllCharacteristics 259 | SizeOfStackReserve = field 24 UInt32 260 | SizeOfStackCommit = field 25 UInt32 261 | SizeOfHeapReserve = field 26 UInt32 262 | SizeOfHeapCommit = field 27 UInt32 263 | LoaderFlags = field 28 UInt32 264 | NumberOfRvaAndSizes = field 29 UInt32 265 | DataDirectory = field 30 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 266 | } 267 | 268 | $ImageOptionalHdr64 = struct $Mod PE.IMAGE_OPTIONAL_HEADER64 @{ 269 | Magic = field 0 $ImageHdrMagic 270 | MajorLinkerVersion = field 1 Byte 271 | MinorLinkerVersion = field 2 Byte 272 | SizeOfCode = field 3 UInt32 273 | SizeOfInitializedData = field 4 UInt32 274 | SizeOfUninitializedData = field 5 UInt32 275 | AddressOfEntryPoint = field 6 UInt32 276 | BaseOfCode = field 7 UInt32 277 | ImageBase = field 8 UInt64 278 | SectionAlignment = field 9 UInt32 279 | FileAlignment = field 10 UInt32 280 | MajorOperatingSystemVersion = field 11 UInt16 281 | MinorOperatingSystemVersion = field 12 UInt16 282 | MajorImageVersion = field 13 UInt16 283 | MinorImageVersion = field 14 UInt16 284 | MajorSubsystemVersion = field 15 UInt16 285 | MinorSubsystemVersion = field 16 UInt16 286 | Win32VersionValue = field 17 UInt32 287 | SizeOfImage = field 18 UInt32 288 | SizeOfHeaders = field 19 UInt32 289 | CheckSum = field 20 UInt32 290 | Subsystem = field 21 $ImageSubsystem 291 | DllCharacteristics = field 22 $ImageDllCharacteristics 292 | SizeOfStackReserve = field 23 UInt64 293 | SizeOfStackCommit = field 24 UInt64 294 | SizeOfHeapReserve = field 25 UInt64 295 | SizeOfHeapCommit = field 26 UInt64 296 | LoaderFlags = field 27 UInt32 297 | NumberOfRvaAndSizes = field 28 UInt32 298 | DataDirectory = field 29 $PeImageDataDir.MakeArrayType() -MarshalAs @('ByValArray', 16) 299 | } 300 | 301 | $ImageSectionHdrs = struct $Mod PE.IMAGE_SECTION_HEADER @{ 302 | Name = field 0 String -MarshalAs @('ByValTStr', 8) 303 | VirtualSize = field 1 UInt32 304 | VirtualAddress = field 2 UInt32 305 | SizeOfRawData = field 3 UInt32 306 | PointerToRawData = field 4 UInt32 307 | PointerToRelocations = field 5 UInt32 308 | PointerToLinenumbers = field 6 UInt32 309 | NumberOfRelocations = field 7 UInt16 310 | NumberOfLinenumbers = field 8 UInt16 311 | Characteristics = field 9 $ImageScn 312 | } 313 | 314 | $ImageConfigDirectory = struct $Mod PE.IMAGE_LOAD_CONFIG_DIRECTORY @{ 315 | Size = field 0 UInt32 316 | TimeDateStamp = field 1 UInt32 317 | MajorVersion = field 2 UInt16 318 | MinorVersion = field 3 UInt16 319 | GlobalFlagsClear = field 4 UInt32 320 | GlobalFlagsSet = field 5 UInt32 321 | CriticalSectionDefaultTimeout = field 6 UInt32 322 | DeCommitFreeBlockThreshold = field 7 UInt32 323 | DeCommitTotalFreeThreshold = field 8 UInt32 324 | LockPrefixTable = field 9 UInt32 325 | MaximumAllocationSize = field 10 UInt32 326 | VirtualMemoryThreshold = field 11 UInt32 327 | ProcessHeapFlags = field 12 UInt32 328 | ProcessAffinityMask = field 13 UInt32 329 | CSDVersion = field 14 UInt16 330 | Reserved1 = field 15 UInt16 331 | EditList = field 16 UInt32 332 | SecurityCookie = field 17 UInt32 333 | SEHandlerTable = field 18 UInt32 334 | SEHandlerCount = field 19 UInt32 335 | GuardCFCheckFunctionPointer = field 20 UInt32 336 | GuardCFDispatchFunctionPointer = field 21 UInt32 337 | GuardCFFunctionTable = field 22 UInt32 338 | GuardCFFunctionCount = field 23 UInt32 339 | GuardFlags = field 24 UInt32 340 | CodeIntegrity = field 25 UInt32 341 | GuardAddressTakenIatEntryTable = field 26 UInt32 342 | GuardAddressTakenIatEntryCount = field 27 UInt32 343 | GuardLongJumpTargetTable = field 28 UInt32 344 | GuardLongJumpTargetCount = field 29 UInt32 345 | 346 | } 347 | 348 | $ImageNTHdrs = struct $Mod PE.IMAGE_NT_HEADERS @{ 349 | Signature = field 0 $ImageNTSig 350 | FileHeader = field 1 $ImageFileHeader 351 | OptionalHeader = field 2 $ImageOptionalHdr 352 | } 353 | 354 | $ImageNTHdrs64 = struct $Mod PE.IMAGE_NT_HEADERS64 @{ 355 | Signature = field 0 $ImageNTSig 356 | FileHeader = field 1 $ImageFileHeader 357 | OptionalHeader = field 2 $ImageOptionalHdr64 358 | } 359 | 360 | $FunctionDefinitions = @( 361 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String])), 362 | (func kernel32 GetModuleHandle ([Intptr]) @([String])), 363 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 364 | ) 365 | 366 | $Table = New-Object system.Data.DataTable 'table' 367 | $Col1 = New-Object system.Data.DataColumn FileName, ([string]) 368 | $Col2 = New-Object system.Data.DataColumn ARCH, ([string]) 369 | $Col3 = New-Object system.Data.DataColumn DotNET, ([string]) 370 | $Col4 = New-Object system.Data.DataColumn ASLR, ([string]) 371 | $Col5 = New-Object system.Data.DataColumn DEP, ([string]) 372 | $Col6 = New-Object system.Data.DataColumn Authenticode, ([string]) 373 | $Col7 = New-Object system.Data.DataColumn StrongNaming, ([string]) 374 | $Col8 = New-Object system.Data.DataColumn SafeSEH, ([string]) 375 | $Col9 = New-Object system.Data.DataColumn ControlFlowGuard, ([string]) 376 | $Col10 = New-Object system.Data.DataColumn HighentropyVA, ([string]) 377 | $Table.columns.add($Col1) 378 | $Table.columns.add($Col2) 379 | $Table.columns.add($Col3) 380 | $Table.columns.add($Col4) 381 | $Table.columns.add($Col5) 382 | $Table.columns.add($Col6) 383 | $Table.columns.add($Col7) 384 | $Table.columns.add($Col8) 385 | $Table.columns.add($Col9) 386 | $Table.columns.add($Col10) 387 | } 388 | Process 389 | { 390 | $Files = Get-Files 391 | Enumerate-Files $Files $Table 392 | 393 | $Table 394 | } 395 | End 396 | { 397 | } 398 | } 399 | 400 | function Enumerate-Files 401 | { 402 | param 403 | ( 404 | [System.Object] 405 | $Files, 406 | 407 | [System.Object] 408 | $Table 409 | ) 410 | 411 | foreach ($CurrentFile in $Files) 412 | { 413 | $DotNET = $false 414 | $ASLR = $false 415 | $HighentropyVA = $false 416 | $DEP = $false 417 | $SEH = $false 418 | $ControlFlowGuard = $false 419 | $Authenticode = $false 420 | $StrongNaming = $false 421 | 422 | # Determine file length 423 | $FileInfo = New-Object System.IO.FileInfo($CurrentFile) 424 | $FileLength = $FileInfo.length 425 | 426 | $FileStream = New-Object System.IO.FileStream($CurrentFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) 427 | $FileByteArray = New-Object Byte[]($FileStream.Length) 428 | $FileStream.Read($FileByteArray, 0, $FileStream.Length) | Out-Null 429 | $FileStream.Close() 430 | 431 | $Handle = [System.Runtime.InteropServices.GCHandle]::Alloc($FileByteArray, 'Pinned') 432 | $PEBaseAddr = $Handle.AddrOfPinnedObject() 433 | $DosHeader = $PEBaseAddr -as $ImageDosHeader 434 | if ($FileByteArray.Length -lt $DosHeader.e_lfanew) 435 | { 436 | continue 437 | } 438 | $PointerNtHeader = [IntPtr] ($PEBaseAddr.ToInt64() + $DosHeader.e_lfanew) 439 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs 440 | if ($NTHeader.OptionalHeader.Magic -eq 0){ 441 | $Row = $Table.NewRow() 442 | $Row.FileName = $CurrentFile 443 | $Row.ARCH = 'Unknown Format' 444 | $Row.DotNET = 'Unknown Format' 445 | $Row.ASLR = 'Unknown Format' 446 | $Row.HighentropyVA = 'Unknown Format' 447 | $Row.DEP = 'Unknown Format' 448 | $Row.Authenticode = 'Unknown Format' 449 | $Row.StrongNaming = 'Unknown Format' 450 | $Row.SafeSEH = 'Unknown Format' 451 | $Row.ControlFlowGuard = 'Unknown Format' 452 | $Table.Rows.Add($Row) 453 | Continue 454 | } 455 | if ($NTHeader.OptionalHeader.Magic -eq 'PE64') 456 | { 457 | $NTHeader = $PointerNtHeader -as $ImageNTHdrs64 458 | } 459 | 460 | if($NTHeader.OptionalHeader.DataDirectory[14].VirtualAddress -ne 0) { 461 | $DotNet = $true 462 | } 463 | 464 | $ARCH = $NTHeader.FileHeader.Machine.toString() 465 | $FileCharacteristics = $NTHeader.FileHeader.Characteristics.toString().Split(',') 466 | $DllCharacteristics = $NTHeader.OptionalHeader.DllCharacteristics.toString().Split(',') 467 | $value = 0 468 | $ASLR = $false 469 | if([int32]::TryParse($DllCharacteristics, [ref]$value)){ 470 | if($value -band 0x20){ 471 | $HighentropyVA = $true 472 | } 473 | if($value -band 0x40){ 474 | $ASLR = $true 475 | } 476 | if($value -band 0x100){ 477 | $DEP = $true 478 | } 479 | 480 | if($value -band 0x400){ 481 | $SEH = 'N/A' 482 | } 483 | 484 | if($value -band 0x4000){ 485 | $ControlFlowGuard = $true 486 | } 487 | } else { 488 | foreach($DllCharacteristic in $DllCharacteristics) 489 | { 490 | switch($DllCharacteristic.Trim()){ 491 | 'DYNAMIC_BASE' 492 | { 493 | $ASLR = $true 494 | } 495 | 'NX_COMPAT' 496 | { 497 | $DEP = $true 498 | } 499 | 'NO_SEH' 500 | { 501 | $SEH = 'N/A' 502 | } 503 | 'GUARD_CF' 504 | { 505 | $ControlFlowGuard = $true 506 | } 507 | 'HIGH_ENTROPY_VA' 508 | { 509 | $HighentropyVA = $true 510 | } 511 | } 512 | } 513 | } 514 | 515 | if($ASLR){ 516 | foreach($FileCharacteristic in $FileCharacteristics){ 517 | switch($FileCharacteristic.Trim()){ 518 | 'IMAGE_RELOCS_STRIPPED' 519 | { 520 | $Stripped = $true 521 | } 522 | } 523 | } 524 | 525 | $OS = [Environment]::OSVersion 526 | $WindowsCheck = $true 527 | if($OS.Version.Build -ge 9200){ 528 | $WindowsCheck = $false 529 | } 530 | 531 | if($WindowsCheck){ 532 | if (-not $DotNet -and $Stripped){ 533 | $ASLR = 'False (DYNAMICBASE Set And Relocation Table Stripped)' 534 | } 535 | } 536 | } 537 | 538 | if ($DotNet) { 539 | $ControlFlowGuard = 'N/A' 540 | } 541 | 542 | #Get Strongnaming Status 543 | $StrongNaming = Get-StrongNamingStatus $CurrentFile 544 | 545 | #Get Authenticode Status 546 | $Authenticode = 'N/A' 547 | if(!$SkipAuthenticode) 548 | { 549 | $Authenticode = Get-AuthenticodeStatus $CurrentFile 550 | } 551 | 552 | if ($ARCH -eq 'AMD64') 553 | { 554 | $SEH = 'N/A' 555 | } 556 | if ($ARCH -ne 'AMD64') 557 | { 558 | $HighentropyVA = 'N/A' 559 | } 560 | if ($SEH -ne 'N/A') 561 | { 562 | #Get SEH Status 563 | $SEH = Get-SEHStatus $CurrentFile $NTHeader $PointerNtHeader $PEBaseAddr 564 | 565 | } 566 | 567 | #Write everything to a DataTable 568 | $Row = $Table.NewRow() 569 | $Row.FileName = $CurrentFile 570 | $Row.ARCH = $ARCH 571 | $Row.DotNET = $DotNET 572 | $Row.ASLR = $ASLR 573 | $Row.DEP = $DEP 574 | $Row.Authenticode = $Authenticode 575 | $Row.StrongNaming = $StrongNaming 576 | $Row.SafeSEH = $SEH 577 | $Row.ControlFlowGuard = $ControlFlowGuard 578 | $Row.HighentropyVA = $HighentropyVA 579 | $Table.Rows.Add($Row) 580 | } 581 | } 582 | 583 | function Get-AuthenticodeStatus 584 | { 585 | param 586 | ( 587 | [System.Object] 588 | $CurrentFile 589 | 590 | ) 591 | 592 | $Status = Get-AuthenticodeSignature $CurrentFile | Select-Object -ExpandProperty Status 593 | 594 | if ($Status -eq 'Valid') 595 | { 596 | $Authenticode = $true 597 | } 598 | else 599 | { 600 | $Authenticode = $false 601 | } 602 | $Authenticode 603 | } 604 | 605 | function Get-SEHStatus 606 | { 607 | param 608 | ( 609 | [System.Object] 610 | $CurrentFile, 611 | 612 | [System.Object] 613 | $NTHeader, 614 | 615 | [System.Object] 616 | $PointerNtHeader, 617 | 618 | [System.Object] 619 | $PEBaseAddr 620 | ) 621 | $NumSections = $NTHeader.FileHeader.NumberOfSections 622 | $PointerSectionHeader = [IntPtr] ($PointerNtHeader.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageNTHdrs)) 623 | #Create an array of SectionHeaders 624 | $SectionHeaders = @(New-Object $ImageSectionHdrs) * $NumSections 625 | 626 | foreach ($i in 0..($NumSections - 1)) 627 | { 628 | $SectionHeaders[$i] = [System.Runtime.InteropServices.Marshal]::PtrToStructure(([IntPtr] ($PointerSectionHeader.ToInt64() + ($i * [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $ImageSectionHdrs)))), [System.Type] $ImageSectionHdrs) 629 | } 630 | $ConfigPointer = [IntPtr] ($PEBaseAddr.ToInt64() + $NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress) 631 | $ConfigPointer = Convert-RVAToFileOffset $ConfigPointer 632 | $ConfigDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStructure([IntPtr] $ConfigPointer, [System.Type] $ImageConfigDirectory) 633 | $SEHandlerTable = $ConfigDirectory.SEHandlerTable 634 | $SEHandlerCount = $ConfigDirectory.SEHandlerCount 635 | 636 | if($NTHeader.OptionalHeader.DataDirectory[10].VirtualAddress -eq 0) 637 | { 638 | $SEH = $false 639 | } 640 | elseif($ConfigDirectory.Size -lt 72) 641 | { 642 | $SEH = $false 643 | } 644 | elseif($SEHandlerTable -ne 0 -and $SEHandlerCount -ne 0) 645 | { 646 | $SEH = $true 647 | } 648 | elseif($SEHandlerTable -eq 0 -or $SEHandlerCount -eq 0) 649 | { 650 | $SEH = $false 651 | } 652 | $SEH 653 | } 654 | 655 | function Get-StrongNamingStatus 656 | { 657 | param 658 | ( 659 | [System.Object] 660 | $CurrentFile 661 | ) 662 | 663 | try 664 | { 665 | $StongNaming = [System.Reflection.AssemblyName]::GetAssemblyName($CurrentFile).GetPublicKeyToken().Count -gt 0 666 | } 667 | catch 668 | { 669 | $StongNaming = 'N/A' 670 | } 671 | $StongNaming 672 | } 673 | 674 | function Get-GS { 675 | } 676 | 677 | function Get-Files 678 | { 679 | $Files = @() 680 | if($Directory) 681 | { 682 | $Files += Get-FilesFromDirectory 683 | } 684 | if($File) 685 | { 686 | $Files += Get-ChildItem $File 687 | } 688 | $Files 689 | } 690 | 691 | function Get-FilesFromDirectory 692 | { 693 | if($Recursive) 694 | { 695 | Get-ChildItem -Path "$Directory\*" -Recurse -Include *.exe, *.dll | ForEach-Object { 696 | $Files += $_ 697 | } 698 | } 699 | else 700 | { 701 | Get-ChildItem -Path "$Directory\*" -Include *.exe, *.dll |ForEach-Object { 702 | $Files += $_ 703 | } 704 | } 705 | $Files 706 | } 707 | 708 | function Convert-RVAToFileOffset 709 | { 710 | #Author: Matthew Graeber (@mattifestation) 711 | param 712 | ( 713 | [IntPtr] 714 | $Rva 715 | ) 716 | 717 | foreach ($Section in $SectionHeaders) 718 | { 719 | if ((($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -ge $Section.VirtualAddress) -and (($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -lt ($Section.VirtualAddress + $Section.VirtualSize))) 720 | { 721 | return [IntPtr] ($Rva.ToInt64() - ($Section.VirtualAddress - $Section.PointerToRawData)) 722 | } 723 | } 724 | 725 | $Rva 726 | } 727 | 728 | <# 729 | The following functions are from Matt Graeber's method of PSReflection 730 | https://github.com/mattifestation/PSReflect 731 | #> 732 | 733 | function func 734 | { 735 | #Author: Matthew Graeber (@mattifestation) 736 | Param 737 | ( 738 | [Parameter(Position = 0, Mandatory = $true)] 739 | [String] 740 | $DllName, 741 | 742 | [Parameter(Position = 1, Mandatory = $true)] 743 | [string] 744 | $FunctionName, 745 | 746 | [Parameter(Position = 2, Mandatory = $true)] 747 | [Type] 748 | $ReturnType, 749 | 750 | [Parameter(Position = 3)] 751 | [Type[]] 752 | $ParameterTypes, 753 | 754 | [Parameter(Position = 4)] 755 | [Runtime.InteropServices.CallingConvention] 756 | $NativeCallingConvention, 757 | 758 | [Parameter(Position = 5)] 759 | [Runtime.InteropServices.CharSet] 760 | $Charset, 761 | 762 | [Switch] 763 | $SetLastError 764 | ) 765 | 766 | $Properties = @{ 767 | DllName = $DllName 768 | FunctionName = $FunctionName 769 | ReturnType = $ReturnType 770 | } 771 | 772 | if ($ParameterTypes) 773 | { 774 | $Properties['ParameterTypes'] = $ParameterTypes 775 | } 776 | if ($NativeCallingConvention) 777 | { 778 | $Properties['NativeCallingConvention'] = $NativeCallingConvention 779 | } 780 | if ($Charset) 781 | { 782 | $Properties['Charset'] = $Charset 783 | } 784 | if ($SetLastError) 785 | { 786 | $Properties['SetLastError'] = $SetLastError 787 | } 788 | 789 | New-Object PSObject -Property $Properties 790 | } 791 | 792 | function enumerate 793 | { 794 | <# 795 | Author: Matthew Graeber (@mattifestation) 796 | .SYNOPSIS 797 | 798 | Creates an in-memory enumeration for use in your PowerShell session. 799 | 800 | Author: Matthew Graeber (@mattifestation) 801 | License: BSD 3-Clause 802 | Required Dependencies: None 803 | Optional Dependencies: None 804 | 805 | .DESCRIPTION 806 | 807 | The 'enum' function facilitates the creation of enums entirely in 808 | memory using as close to a "C style" as PowerShell will allow. 809 | 810 | .PARAMETER Module 811 | 812 | The in-memory module that will host the enum. Use 813 | New-InMemoryModule to define an in-memory module. 814 | 815 | .PARAMETER FullName 816 | 817 | The fully-qualified name of the enum. 818 | 819 | .PARAMETER Type 820 | 821 | The type of each enum element. 822 | 823 | .PARAMETER EnumElements 824 | 825 | A hashtable of enum elements. 826 | 827 | .PARAMETER Bitfield 828 | 829 | Specifies that the enum should be treated as a bitfield. 830 | 831 | .EXAMPLE 832 | 833 | $Mod = New-InMemoryModule -ModuleName Win32 834 | 835 | $ImageSubsystem = enum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{ 836 | UNKNOWN = 0 837 | NATIVE = 1 # Image doesn't require a subsystem. 838 | WINDOWS_GUI = 2 # Image runs in the Windows GUI subsystem. 839 | WINDOWS_CUI = 3 # Image runs in the Windows character subsystem. 840 | OS2_CUI = 5 # Image runs in the OS/2 character subsystem. 841 | POSIX_CUI = 7 # Image runs in the Posix character subsystem. 842 | NATIVE_WINDOWS = 8 # Image is a native Win9x driver. 843 | WINDOWS_CE_GUI = 9 # Image runs in the Windows CE subsystem. 844 | EFI_APPLICATION = 10 845 | EFI_BOOT_SERVICE_DRIVER = 11 846 | EFI_RUNTIME_DRIVER = 12 847 | EFI_ROM = 13 848 | XBOX = 14 849 | WINDOWS_BOOT_APPLICATION = 16 850 | } 851 | 852 | .NOTES 853 | 854 | PowerShell purists may disagree with the naming of this function but 855 | again, this was developed in such a way so as to emulate a "C style" 856 | definition as closely as possible. Sorry, I'm not going to name it 857 | New-Enum. :P 858 | #> 859 | 860 | [OutputType([Type])] 861 | Param 862 | ( 863 | [Parameter(Position = 0, Mandatory = $true)] 864 | [Reflection.Emit.ModuleBuilder] 865 | $Module, 866 | 867 | [Parameter(Position = 1, Mandatory = $true)] 868 | [ValidateNotNullOrEmpty()] 869 | [String] 870 | $FullName, 871 | 872 | [Parameter(Position = 2, Mandatory = $true)] 873 | [Type] 874 | $Type, 875 | 876 | [Parameter(Position = 3, Mandatory = $true)] 877 | [ValidateNotNullOrEmpty()] 878 | [Hashtable] 879 | $EnumElements, 880 | 881 | [Switch] 882 | $Bitfield 883 | ) 884 | 885 | $EnumType = $Type -as [Type] 886 | 887 | $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType) 888 | 889 | if ($Bitfield) 890 | { 891 | $FlagsConstructor = [FlagsAttribute].GetConstructor(@()) 892 | $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @()) 893 | $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute) 894 | } 895 | 896 | foreach ($Key in $EnumElements.Keys) 897 | { 898 | # Apply the specified enum type to each element 899 | $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType) 900 | } 901 | 902 | $EnumBuilder.CreateType() 903 | } 904 | 905 | function struct 906 | { 907 | <# 908 | Author: Matthew Graeber (@mattifestation) 909 | .SYNOPSIS 910 | 911 | Creates an in-memory struct for use in your PowerShell session. 912 | 913 | Author: Matthew Graeber (@mattifestation) 914 | License: BSD 3-Clause 915 | Required Dependencies: None 916 | Optional Dependencies: field 917 | 918 | .DESCRIPTION 919 | 920 | The 'struct' function facilitates the creation of structs entirely in 921 | memory using as close to a "C style" as PowerShell will allow. Struct 922 | fields are specified using a hashtable where each field of the struct 923 | is comprosed of the order in which it should be defined, its .NET 924 | type, and optionally, its offset and special marshaling attributes. 925 | 926 | One of the features of 'struct' is that after your struct is defined, 927 | it will come with a built-in GetSize method as well as an explicit 928 | converter so that you can easily cast an IntPtr to the struct without 929 | relying upon calling SizeOf and/or PtrToStructure in the Marshal 930 | class. 931 | 932 | .PARAMETER Module 933 | 934 | The in-memory module that will host the struct. Use 935 | New-InMemoryModule to define an in-memory module. 936 | 937 | .PARAMETER FullName 938 | 939 | The fully-qualified name of the struct. 940 | 941 | .PARAMETER StructFields 942 | 943 | A hashtable of fields. Use the 'field' helper function to ease 944 | defining each field. 945 | 946 | .PARAMETER PackingSize 947 | 948 | Specifies the memory alignment of fields. 949 | 950 | .PARAMETER ExplicitLayout 951 | 952 | Indicates that an explicit offset for each field will be specified. 953 | 954 | .EXAMPLE 955 | 956 | $Mod = New-InMemoryModule -ModuleName Win32 957 | 958 | $ImageDosSignature = enum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{ 959 | DOS_SIGNATURE = 0x5A4D 960 | OS2_SIGNATURE = 0x454E 961 | OS2_SIGNATURE_LE = 0x454C 962 | VXD_SIGNATURE = 0x454C 963 | } 964 | 965 | $ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{ 966 | e_magic = field 0 $ImageDosSignature 967 | e_cblp = field 1 UInt16 968 | e_cp = field 2 UInt16 969 | e_crlc = field 3 UInt16 970 | e_cparhdr = field 4 UInt16 971 | e_minalloc = field 5 UInt16 972 | e_maxalloc = field 6 UInt16 973 | e_ss = field 7 UInt16 974 | e_sp = field 8 UInt16 975 | e_csum = field 9 UInt16 976 | e_ip = field 10 UInt16 977 | e_cs = field 11 UInt16 978 | e_lfarlc = field 12 UInt16 979 | e_ovno = field 13 UInt16 980 | e_res = field 14 UInt16[] -MarshalAs @('ByValArray', 4) 981 | e_oemid = field 15 UInt16 982 | e_oeminfo = field 16 UInt16 983 | e_res2 = field 17 UInt16[] -MarshalAs @('ByValArray', 10) 984 | e_lfanew = field 18 Int32 985 | } 986 | 987 | # Example of using an explicit layout in order to create a union. 988 | $TestUnion = struct $Mod TestUnion @{ 989 | field1 = field 0 UInt32 0 990 | field2 = field 1 IntPtr 0 991 | } -ExplicitLayout 992 | 993 | .NOTES 994 | 995 | PowerShell purists may disagree with the naming of this function but 996 | again, this was developed in such a way so as to emulate a "C style" 997 | definition as closely as possible. Sorry, I'm not going to name it 998 | New-Struct. :P 999 | #> 1000 | [OutputType([Type])] 1001 | Param 1002 | ( 1003 | [Parameter(Position = 1, Mandatory = $true)] 1004 | [Reflection.Emit.ModuleBuilder] 1005 | $Module, 1006 | 1007 | [Parameter(Position = 2, Mandatory = $true)] 1008 | [ValidateNotNullOrEmpty()] 1009 | [String] 1010 | $FullName, 1011 | 1012 | [Parameter(Position = 3, Mandatory = $true)] 1013 | [ValidateNotNullOrEmpty()] 1014 | [Hashtable] 1015 | $StructFields, 1016 | 1017 | [Reflection.Emit.PackingSize] 1018 | $PackingSize = [Reflection.Emit.PackingSize]::Unspecified, 1019 | 1020 | [Switch] 1021 | $ExplicitLayout 1022 | ) 1023 | 1024 | [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass, 1025 | Class, 1026 | Public, 1027 | Sealed, 1028 | BeforeFieldInit' 1029 | 1030 | if ($ExplicitLayout) 1031 | { 1032 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout 1033 | } 1034 | else 1035 | { 1036 | $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout 1037 | } 1038 | 1039 | $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize) 1040 | $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0] 1041 | $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst')) 1042 | 1043 | $Fields = New-Object Hashtable[]($StructFields.Count) 1044 | 1045 | # Sort each field according to the orders specified 1046 | # Unfortunately, PSv2 doesn't have the luxury of the 1047 | # hashtable [Ordered] accelerator. 1048 | foreach ($Field in $StructFields.Keys) 1049 | { 1050 | $Index = $StructFields[$Field]['Position'] 1051 | $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]} 1052 | } 1053 | 1054 | foreach ($Field in $Fields) 1055 | { 1056 | $FieldName = $Field['FieldName'] 1057 | $FieldProp = $Field['Properties'] 1058 | 1059 | $Offset = $FieldProp['Offset'] 1060 | $Type = $FieldProp['Type'] 1061 | $MarshalAs = $FieldProp['MarshalAs'] 1062 | 1063 | $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public') 1064 | 1065 | if ($MarshalAs) 1066 | { 1067 | $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType]) 1068 | $Size = $MarshalAs[1] 1069 | $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, 1070 | $UnmanagedType, $SizeConst, @($Size)) 1071 | $NewField.SetCustomAttribute($AttribBuilder) 1072 | } 1073 | 1074 | if ($ExplicitLayout) 1075 | { 1076 | $NewField.SetOffset($Offset) 1077 | } 1078 | } 1079 | 1080 | # Make the struct aware of its own size. 1081 | # No more having to call [Runtime.InteropServices.Marshal]::SizeOf! 1082 | $SizeMethod = $StructBuilder.DefineMethod('GetSize', 1083 | 'Public, Static', 1084 | [Int], 1085 | [Type[]] @()) 1086 | $ILGenerator = $SizeMethod.GetILGenerator() 1087 | # Thanks for the help, Jason Shirk! 1088 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1089 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1090 | [Type].GetMethod('GetTypeFromHandle')) 1091 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call, 1092 | [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type]))) 1093 | $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret) 1094 | 1095 | # Allow for explicit casting from an IntPtr 1096 | # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure! 1097 | $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit', 1098 | 'PrivateScope, Public, Static, HideBySig, SpecialName', 1099 | $StructBuilder, 1100 | [Type[]] @([IntPtr])) 1101 | $ILGenerator2 = $ImplicitConverter.GetILGenerator() 1102 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop) 1103 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0) 1104 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder) 1105 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1106 | [Type].GetMethod('GetTypeFromHandle')) 1107 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call, 1108 | [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type]))) 1109 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder) 1110 | $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret) 1111 | 1112 | $StructBuilder.CreateType() 1113 | } 1114 | 1115 | function field 1116 | { 1117 | #Author: Matthew Graeber (@mattifestation) 1118 | Param 1119 | ( 1120 | [Parameter(Position = 0, Mandatory = $true)] 1121 | [UInt16] 1122 | $Position, 1123 | 1124 | [Parameter(Position = 1, Mandatory = $true)] 1125 | [Type] 1126 | $Type, 1127 | 1128 | [Parameter(Position = 2)] 1129 | [UInt16] 1130 | $Offset, 1131 | 1132 | [Object[]] 1133 | $MarshalAs 1134 | ) 1135 | 1136 | @{ 1137 | Position = $Position 1138 | Type = $Type -as [Type] 1139 | Offset = $Offset 1140 | MarshalAs = $MarshalAs 1141 | } 1142 | } 1143 | 1144 | function Add-Win32Type 1145 | { 1146 | <# 1147 | Author: Matthew Graeber (@mattifestation) 1148 | .SYNOPSIS 1149 | 1150 | Creates a .NET type for an unmanaged Win32 function. 1151 | 1152 | Author: Matthew Graeber (@mattifestation) 1153 | License: BSD 3-Clause 1154 | Required Dependencies: None 1155 | Optional Dependencies: func 1156 | 1157 | .DESCRIPTION 1158 | 1159 | Add-Win32Type enables you to easily interact with unmanaged (i.e. 1160 | Win32 unmanaged) functions in PowerShell. After providing 1161 | Add-Win32Type with a function signature, a .NET type is created 1162 | using reflection (i.e. csc.exe is never called like with Add-Type). 1163 | 1164 | The 'func' helper function can be used to reduce typing when defining 1165 | multiple function definitions. 1166 | 1167 | .PARAMETER DllName 1168 | 1169 | The name of the DLL. 1170 | 1171 | .PARAMETER FunctionName 1172 | 1173 | The name of the target function. 1174 | 1175 | .PARAMETER ReturnType 1176 | 1177 | The return type of the function. 1178 | 1179 | .PARAMETER ParameterTypes 1180 | 1181 | The function parameters. 1182 | 1183 | .PARAMETER NativeCallingConvention 1184 | 1185 | Specifies the native calling convention of the function. Defaults to 1186 | stdcall. 1187 | 1188 | .PARAMETER Charset 1189 | 1190 | If you need to explicitly call an 'A' or 'W' Win32 function, you can 1191 | specify the character set. 1192 | 1193 | .PARAMETER SetLastError 1194 | 1195 | Indicates whether the callee calls the SetLastError Win32 API 1196 | function before returning from the attributed method. 1197 | 1198 | .PARAMETER Module 1199 | 1200 | The in-memory module that will host the functions. Use 1201 | New-InMemoryModule to define an in-memory module. 1202 | 1203 | .PARAMETER Namespace 1204 | 1205 | An optional namespace to prepend to the type. Add-Win32Type defaults 1206 | to a namespace consisting only of the name of the DLL. 1207 | 1208 | .EXAMPLE 1209 | 1210 | $Mod = New-InMemoryModule -ModuleName Win32 1211 | 1212 | $FunctionDefinitions = @( 1213 | (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError), 1214 | (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError), 1215 | (func ntdll RtlGetCurrentPeb ([IntPtr]) @()) 1216 | ) 1217 | 1218 | $Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32' 1219 | $Kernel32 = $Types['kernel32'] 1220 | $Ntdll = $Types['ntdll'] 1221 | $Ntdll::RtlGetCurrentPeb() 1222 | $ntdllbase = $Kernel32::GetModuleHandle('ntdll') 1223 | $Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb') 1224 | 1225 | .NOTES 1226 | 1227 | Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189 1228 | 1229 | When defining multiple function prototypes, it is ideal to provide 1230 | Add-Win32Type with an array of function signatures. That way, they 1231 | are all incorporated into the same in-memory module. 1232 | #> 1233 | [OutputType([Hashtable])] 1234 | Param( 1235 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1236 | [String] 1237 | $DllName, 1238 | 1239 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1240 | [String] 1241 | $FunctionName, 1242 | 1243 | [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] 1244 | [Type] 1245 | $ReturnType, 1246 | 1247 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1248 | [Type[]] 1249 | $ParameterTypes, 1250 | 1251 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1252 | [Runtime.InteropServices.CallingConvention] 1253 | $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall, 1254 | 1255 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1256 | [Runtime.InteropServices.CharSet] 1257 | $Charset = [Runtime.InteropServices.CharSet]::Auto, 1258 | 1259 | [Parameter(ValueFromPipelineByPropertyName = $true)] 1260 | [Switch] 1261 | $SetLastError, 1262 | 1263 | [Parameter(Mandatory = $true)] 1264 | [Reflection.Emit.ModuleBuilder] 1265 | $Module, 1266 | 1267 | [ValidateNotNull()] 1268 | [String] 1269 | $Namespace = '' 1270 | ) 1271 | 1272 | BEGIN 1273 | { 1274 | $TypeHash = @{} 1275 | } 1276 | 1277 | PROCESS 1278 | { 1279 | # Define one type for each DLL 1280 | if (!$TypeHash.ContainsKey($DllName)) 1281 | { 1282 | if ($Namespace) 1283 | { 1284 | $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit') 1285 | } 1286 | else 1287 | { 1288 | $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit') 1289 | } 1290 | } 1291 | 1292 | $Method = $TypeHash[$DllName].DefineMethod( 1293 | $FunctionName, 1294 | 'Public,Static,PinvokeImpl', 1295 | $ReturnType, 1296 | $ParameterTypes) 1297 | 1298 | # Make each ByRef parameter an Out parameter 1299 | $i = 1 1300 | foreach($Parameter in $ParameterTypes) 1301 | { 1302 | if ($Parameter.IsByRef) 1303 | { 1304 | [void] $Method.DefineParameter($i, 'Out', $null) 1305 | } 1306 | 1307 | $i++ 1308 | } 1309 | 1310 | $DllImport = [Runtime.InteropServices.DllImportAttribute] 1311 | $SetLastErrorField = $DllImport.GetField('SetLastError') 1312 | $CallingConventionField = $DllImport.GetField('CallingConvention') 1313 | $CharsetField = $DllImport.GetField('CharSet') 1314 | if ($SetLastError) 1315 | { 1316 | $SLEValue = $true 1317 | } 1318 | else 1319 | { 1320 | $SLEValue = $false 1321 | } 1322 | 1323 | # Equivalent to C# version of [DllImport(DllName)] 1324 | $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String]) 1325 | $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor, 1326 | $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(), 1327 | [Reflection.FieldInfo[]] @($SetLastErrorField, $CallingConventionField, $CharsetField), 1328 | [Object[]] @($SLEValue, ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention), ([Runtime.InteropServices.CharSet] $Charset))) 1329 | 1330 | $Method.SetCustomAttribute($DllImportAttribute) 1331 | } 1332 | 1333 | END 1334 | { 1335 | $ReturnTypes = @{} 1336 | 1337 | foreach ($Key in $TypeHash.Keys) 1338 | { 1339 | $Type = $TypeHash[$Key].CreateType() 1340 | 1341 | $ReturnTypes[$Key] = $Type 1342 | } 1343 | 1344 | return $ReturnTypes 1345 | } 1346 | } 1347 | 1348 | 1349 | # /////////////////////////////////////// 1350 | # Get wmi provider information 1351 | # /////////////////////////////////////// 1352 | function Get-Providers 1353 | { 1354 | # Get provider information 1355 | Get-WmiObject -NameSpace $ns -Class __Win32Provider | select Name,__PATH, __NAMESPACE, CLSID, AssemblyPath, ImpersonationLevel | 1356 | ForEach-Object { 1357 | 1358 | # Create required PS drive 1359 | New-PSDrive -PSProvider registry -Root HKEY_CLASSES_ROOT -Name HKCR -ErrorAction SilentlyContinue | Out-Null 1360 | 1361 | # Get dll path 1362 | $CLSID = $_.CLSID 1363 | if($CLSID){ 1364 | $CLISD_KEY = "HKCR:\CLSID\$CLSID\InprocServer32\" 1365 | $CLSID_DLL = Get-ItemProperty "HKCR:\CLSID\$CLSID\InprocServer32\" -ErrorAction SilentlyContinue | Select-Object "(default)" -ExpandProperty "(default)" 1366 | } 1367 | 1368 | # Grab PE info 1369 | $PEConfig = Get-PESecurity -File $CLSID_DLL 1370 | $ARCH = $PEConfig.ARCH 1371 | $ASLR = $PEConfig.ASLR 1372 | $Authenticode = $PEConfig.Authenticode 1373 | $ControlFlowGuard = $PEConfig.ControlFlowGuard 1374 | $DEP = $PEConfig.DEP 1375 | $DotNET = $PEConfig.DotNET 1376 | $HighentropyVA = $PEConfig.HighentropyVA 1377 | $SafeSEH = $PEConfig.SafeSEH 1378 | $StrongNaming = $PEConfig.StrongNaming 1379 | 1380 | # Grab file meta data info 1381 | if($CLSID_DLL){ 1382 | $FileInfo = Get-Item $CLSID_DLL 1383 | $FileOwner = $FileInfo.GetAccessControl().Owner 1384 | $FileCreationTime = $FileInfo.CreationTime 1385 | $FileLastWriteTime = $FileInfo.LastWriteTime 1386 | $FileLastAccessTime = $FileInfo.LastAccessTime 1387 | } 1388 | 1389 | $Object = New-Object PSObject 1390 | $Object | add-member Noteproperty Name $_.Name 1391 | $Object | add-member Noteproperty __PATH $_.__PATH 1392 | $Object | add-member Noteproperty __NAMESPACE $_.__NAMESPACE 1393 | $Object | add-member Noteproperty CLSID $_.CLSID 1394 | $Object | add-member Noteproperty CLSID_Key $CLISD_KEY 1395 | $Object | add-member Noteproperty CLSID_DLL $CLSID_DLL 1396 | $Object | add-member Noteproperty AssemblyPath $_.AssemblyPath 1397 | $Object | add-member Noteproperty ImpersonationLevel $_.ImpersonationLevel 1398 | $Object | add-member FileName $CLSID_DLL 1399 | $Object | add-member FileOwner $FileOwner 1400 | $Object | add-member FileCreationTime $FileCreationTime 1401 | $Object | add-member FileLastWriteTime $FileLastWriteTime 1402 | $Object | add-member FileLastAccessTime $FileLastAccessTime 1403 | $Object | add-member ARCH $ARCH 1404 | $Object | add-member ASLR $ASLR 1405 | $Object | add-member Authenticode $Authenticode 1406 | $Object | add-member ControlFlowGuard $ControlFlowGuard 1407 | $Object | add-member DEP $DEP 1408 | $Object | add-member DotNET $DotNET 1409 | $Object | add-member HighentropyVA $HighentropyVA 1410 | $Object | add-member SafeSEH $SafeSEH 1411 | $Object | add-member StrongNaming $StrongNaming 1412 | 1413 | $Object 1414 | } 1415 | } 1416 | 1417 | # Get providers 1418 | Get-Providers 1419 | -------------------------------------------------------------------------------- /windows/modules/lists/list-default-users.txt: -------------------------------------------------------------------------------- 1 | LocalSystem 2 | LocalService 3 | NetworkService 4 | TrustedInstaller 5 | BUILTIN\Administrators -------------------------------------------------------------------------------- /windows/modules/lists/list-lolbas.txt: -------------------------------------------------------------------------------- 1 | te.exe 2 | cmd.exe 3 | powershell.exe 4 | wmic.exe 5 | cscript.exe 6 | wscript.exe 7 | msbuild.exe 8 | installutil.exe 9 | certutil.exe 10 | rundll32.exe 11 | sc.exe 12 | bitsadmin.exe 13 | regasm.exe 14 | regsvcs.exe 15 | csc.exe 16 | java.exe 17 | reg.exe 18 | remote.exe 19 | cscript.exe 20 | netsh.exe 21 | mshta.exe 22 | shell32.exe 23 | msconfig.exe 24 | -------------------------------------------------------------------------------- /windows/modules/lists/list-loldrivers.txt: -------------------------------------------------------------------------------- 1 | 1.sys 2 | 2.sys 3 | 4.sys 4 | 7.sys 5 | 80.sys 6 | 81.sys 7 | ADV64DRV.sys 8 | Agent64.sys 9 | Air_SYSTEM10.sys 10 | ALSysIO64.sys 11 | AMDPowerProfiler.sys 12 | AMDRyzenMasterDriver.sys 13 | amifldrv64.sys 14 | amp.sys 15 | AsIO.sys 16 | ASIO32.sys 17 | AsIO64.sys 18 | asmmap64.sys 19 | AsrAutoChkUpdDrv.sys 20 | AsrDrv10.sys 21 | AsrDrv101.sys 22 | AsrDrv102.sys 23 | AsrDrv103.sys 24 | asrdrv104.sys 25 | AsrDrv106.sys 26 | AsrIbDrv.sys 27 | AsrOmgDrv.sys 28 | AsrRapidStartDrv.sys 29 | AsrSetupDrv103.sys 30 | AsrSmartConnectDrv.sys 31 | AsUpIO.sys 32 | AsUpIO64.sys 33 | aswArPot.sys 34 | aswVmm.sys 35 | atillk64.sys 36 | ATSZIO.sys 37 | ATSZIO64.sys 38 | b.sys 39 | b1.sys 40 | b3.sys 41 | b4.sys 42 | bandai.sys 43 | Black.sys 44 | BlackBoneDrv10.sys 45 | blacklotus_driver.sys 46 | Bs_Def.sys 47 | BS_Def64.sys 48 | BS_Flash64.sys 49 | BS_HWMIo64.sys 50 | BS_HWMIO64_W10.sys 51 | BS_I2c64.sys 52 | BS_I2cIo.sys 53 | BS_RCIO.sys 54 | BS_RCIO64.sys 55 | BSMEMx64.sys 56 | BSMI.sys 57 | BSMIx64.sys 58 | BSMIXP64.sys 59 | bw.sys 60 | bwrs.sys 61 | bwrsh.sys 62 | c.sys 63 | capcom.sys 64 | CITMDRV_AMD64.sys 65 | CITMDRV_IA64.sys 66 | CorsairLLAccess64.sys 67 | cpupress.sys 68 | cpuz.sys 69 | cpuz_x64.sys 70 | cpuz141.sys 71 | d.sys 72 | d2.sys 73 | d3.sys 74 | d4.sys 75 | daxin_blank.sys 76 | daxin_blank1.sys 77 | daxin_blank2.sys 78 | daxin_blank3.sys 79 | daxin_blank4.sys 80 | daxin_blank5.sys 81 | daxin_blank6.sys 82 | dbk64.sys 83 | dbutil.sys 84 | dbutil_2_3.sys 85 | DBUtilDrv2.sys 86 | Dh_Kernel.sys 87 | Dh_Kernel_10.sys 88 | DirectIo.sys 89 | driver7-x64.sys 90 | driver7-x86.sys 91 | driver7-x86-withoutdbg.sys 92 | elbycdio.sys 93 | elrawdsk.sys 94 | EneIo64.sys 95 | EneTechIo64.sys 96 | FairplayKD.sys 97 | fiddrv.sys 98 | fiddrv64.sys 99 | fidpcidrv.sys 100 | fidpcidrv64.sys 101 | full.sys 102 | gameink.sys 103 | GameTerSafe.sys 104 | gdrv.sys 105 | gftkyj64.sys 106 | GLCKIO2.sys 107 | goad.sys 108 | GVCIDrv64.sys 109 | HOSTNT.sys 110 | HpPortIox64.sys 111 | hw_sys 112 | HwOs2Ec10x64.sys 113 | HwOs2Ec7x64.sys 114 | HwRwDrv.sys 115 | inpoutx64.sys 116 | IObitUnlocker.sys 117 | IOMap64.sys 118 | iomem64.sys 119 | iqvw64e.sys 120 | kbdcap64.sys 121 | kEvP64.sys 122 | kprocesshacker.sys 123 | krpocesshacker.sys 124 | LcTkA.sys 125 | LenovoDiagnosticsDriver.sys 126 | LgDCatcher.sys 127 | LHA.sys 128 | libnicm.sys 129 | Lurker.sys 130 | Lv561av.sys 131 | magdrvamd64.sys 132 | mhyprot.sys 133 | Mhyprot2.sys 134 | mhyprot3.sys 135 | Monitor_win10_x64.sys 136 | MsIo32.sys 137 | MsIo64.sys 138 | msrhook.sys 139 | mtcBSv64.sys 140 | My.sys 141 | mydrivers.sys 142 | NalDrv.sys 143 | NBIOLib_X64.sys 144 | NCHGBIOS2x64.SYS 145 | ncpl.sys 146 | ndislan.sys 147 | netfilterdrv.sys 148 | NetFlt.sys 149 | NetProxyDriver.sys 150 | ni.sys 151 | nicm.sys 152 | NodeDriver.sys 153 | nscm.sys 154 | nstr.sys 155 | nstrwsk.sys 156 | nt2.sys 157 | nt3.sys 158 | nt4.sys 159 | nt5.sys 160 | nt6.sys 161 | ntbios.sys 162 | ntbios_2.sys 163 | NTIOLib.sys 164 | NTIOLib_X64.sys 165 | nvflash.sys 166 | nvflsh64.sys 167 | OpenLibSys.sys 168 | otipcibus.sys 169 | PanIO.sys 170 | PanIOx64.sys 171 | PanMonFlt.sys 172 | PanMonFltX64.sys 173 | PCHunter.sys 174 | PcieCubed.sys 175 | PhlashNT.sys 176 | phymem64.sys 177 | Phymemx64.sys 178 | physmem.sys 179 | piddrv.sys 180 | piddrv64.sys 181 | POORTRY.sys 182 | POORTRY1.sys 183 | POORTRY2.sys 184 | procexp.Sys 185 | ProtectS.sys 186 | Proxy32.sys 187 | Proxy64.sys 188 | RTCore64.sys 189 | rtkio.sys 190 | rtkio64.sys 191 | rtkiow10x64.sys 192 | rtkiow8x64.sys 193 | rwdrv.sys 194 | rzpnk.sys 195 | sandra.sys 196 | Se64a.sys 197 | segwindrvx64.sys 198 | semav6msr.sys 199 | semav6msr64.sys 200 | Sense5Ext.sys 201 | smep_capcom.sys 202 | smep_namco.sys 203 | speedfan.sys 204 | superbmc.sys 205 | SysInfo.sys 206 | t.sys 207 | t3.sys 208 | t7.sys 209 | t8.sys 210 | TestBone.sys 211 | TGSafe.sys 212 | TmComm.sys 213 | UCOREW64.SYS 214 | vboxdrv.sys 215 | viraglt64.sys 216 | viragt.sys 217 | viragt64.sys 218 | vmdrv.sys 219 | VProEventMonitor.sys 220 | wantd.sys 221 | wantd_2.sys 222 | wantd_3.sys 223 | wantd_4.sys 224 | wantd_5.sys 225 | wantd_6.sys 226 | WCPU.sys 227 | windows7-32.sys 228 | windows8-10-32.sys 229 | windows-xp-64.sys 230 | WinFlash64.sys 231 | WinIO32.sys 232 | WinIO32A.sys 233 | WinIO32B.sys 234 | winio64.sys 235 | WinIo64A.sys 236 | WinIo64B.sys 237 | WinIo64C.sys 238 | WINIODrv.sys 239 | WinRing0.sys 240 | WinRing0x64.sys 241 | WiseUnlo.sys 242 | WYProxy32.sys 243 | WYProxy64.sys 244 | zam64.sys 245 | zamguard64.sys 246 | -------------------------------------------------------------------------------- /windows/modules/lists/list-mgmt-strings.txt: -------------------------------------------------------------------------------- 1 | action1 2 | ammyy 3 | atera 4 | Anydesk 5 | ASG 6 | Basecamp 7 | BeAnywhere 8 | ConnectWise 9 | csexecsvc 10 | dameware 11 | Domotz 12 | dwrcc 13 | DWservice 14 | Fixme 15 | Fleetdeck 16 | GetScreen 17 | glavsoft 18 | gotomypc 19 | idrive 20 | Itarian 21 | Level.io 22 | LogMeIn 23 | ManageEngine 24 | N-Able 25 | netsupport 26 | Ngrok 27 | netsupport 28 | PowerAutomate 29 | Pulseway 30 | PSEXESVC 31 | RattyRat 32 | RemComSvc 33 | remote utilities 34 | Rport 35 | Rsocx 36 | RustDesk 37 | RustScan 38 | ScreenConnect 39 | simplehelp 40 | Sorillus 41 | Splashtop 42 | SSH 43 | Tactical 44 | Tailscale 45 | teams 46 | TeamViewer 47 | TightVNC 48 | tmate 49 | TNTRemote 50 | VNC 51 | Xeox 52 | ZeroTier 53 | ZohoAssist 54 | -------------------------------------------------------------------------------- /windows/modules/lists/list-offsec-software.txt: -------------------------------------------------------------------------------- 1 | wireshark 2 | winpcap 3 | cain 4 | nmap 5 | metasploit 6 | cobaltstrike 7 | miner 8 | -------------------------------------------------------------------------------- /windows/modules/lists/list-rmm.csv: -------------------------------------------------------------------------------- 1 | "Hunting KeyWords","URL","Vendor","Product","Default Ports","Call Back URLS","service","processes","schedule task" 2 | "action1","https://www.action1.com/" 3 | "ammyy","https://www.ammyy.com/" 4 | "atera","https://www.atera.com/" 5 | "Anydesk"," https://anydesk.com/" 6 | "Basecamp","https://basecamp.com/" 7 | "BeAnywhere"."https://beanywhere.en.uptodown.com/" 8 | "ConnectWise","https://connectwise.com/" 9 | "csexecsvc","https://github.com/malcomvetter/CSExec" 10 | "dameware","https://www.solarwinds.com/dameware" 11 | "Domotz","https://www.domotz.com/" 12 | "dwrcc","https://www.solarwinds.com/dameware" 13 | "DWservice","https://www.solarwinds.com/dameware" 14 | "Fixme","https://fixme.it/" 15 | "Fleetdeck","https://fleetdeck.io/" 16 | "glavsoft","https://glavsoft.com/" 17 | "gotomypc","https://get.gotomypc.com/" 18 | "idrive","https://www.remotepc.com/" 19 | "Itarian","https://www.itarian.com/" 20 | "Level.io","https://level.io/" 21 | "LogMeIn","https://www.logmein.com/" 22 | "ManageEngine","https://www.manageengine.com/" 23 | "N-Able","https://www.n-able.com/" 24 | "netsupport","https://www.netsupportsoftware.com/" 25 | "Ngrok","https://ngrok.com/" 26 | "netsupport","https://www.netsupportsoftware.com/" 27 | "PowerAutomate","https://www.microsoft.com/en-us/power-platform/products/power-automate" 28 | "Pulseway","https://www.pulseway.com/" 29 | "PSEXESVC","https://learn.microsoft.com/en-us/sysinternals/downloads/psexec" 30 | "RemComSvc","https://www.manageengine.com/" 31 | "remote utilities","https://www.remoteutilities.com/" 32 | "Rport","https://blog.rport.io/" 33 | "Rsocx","https://github.com/b23r0/rsocx" 34 | "ScreenConnect","https://screenconnect.connectwise.com/" 35 | "simplehelp","https://simple-help.com/" 36 | "Sorillus","https://sorillus.com/" 37 | "Splashtop","https://www.splashtop.com/" 38 | "Tactical","https://github.com/amidaware/tacticalrmm" 39 | "Tailscale","https://tailscale.com/" 40 | "teams","https://www.microsoft.com/en-us/microsoft-teams/group-chat-software" 41 | "TeamViewer","https://www.teamviewer.com/" 42 | "tmate","https://tmate.io/" 43 | "TNTRemote" 44 | "vnc","https://www.realvnc.com/en/" 45 | "tight vnc","https://www.tightvnc.com/" 46 | "ultra vnc","https://www.uvnc.com/" 47 | "ZeroTier","https://www.zerotier.com/" 48 | --------------------------------------------------------------------------------