├── 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 |
--------------------------------------------------------------------------------