-
Notifications
You must be signed in to change notification settings - Fork 45
/
PipeViewerShellV1.0.ps1
233 lines (209 loc) · 9.01 KB
/
PipeViewerShellV1.0.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# Installing the Module - Do it before your first run.
#Install-Module -Name NtObjectManager -RequiredVersion 1.1.32
# To allow the execution of local scripts and scripts signed by a trusted publisher.
#Set-ExecutionPolicy RemoteSigned
function Invoke-PipeViewer {
<#
.SYNOPSIS
A PowerShell script to gather detailed information about named pipes on the system and export it to JSON format.
.DESCRIPTION
This script uses the NtObjectManager module to create a JSON file that can be imported into the PipeViewer, a CyberArk open source tool,
to display detailed information about named pipes.
.AUTHOR
Noam Regev
.COMPANY
CyberArk Software Ltd.
https://github.com/cyberark/pipeviewer
#>
param (
[switch]$Print, # Switch to control output display
[switch]$Export, # Switch to control exporting to JSON
[string]$fileName = "NamedPipes.json", # Optional filename, default name - NamedPipes.json
[switch]$Help # Switch to display help information
)
# Check if no switches are provided
if ($PSBoundParameters.Count -eq 0) {
$Help = $true
}
# Display usage information if -Help switch is used
if ($Help) {
$helpText = @"
_____ _ __ ___
| __ (_) \ \ / (_)
| |__) | _ __ __\ \ / / _ _____ _____ _ __
| ___/ | '_ \ / _ \ \/ / | |/ _ \ \ /\ / / _ \ '__|
| | | | |_) | __/\ / | | __/\ V V / __/ |
|_| |_| .__/_\___| \/ |_|\___| \_/\_/ \___|_|
| | / ____| | | | |
|_|| (___ | |__ ___| | |
\___ \| '_ \ / _ \ | |
____) | | | | __/ | |
|_____/|_| |_|\___|_|_| v1.0
Author: Noam Regev
Version: 1.0
Company: CyberArk Software Ltd.
Contributors: Eviatar Gerzi
vvv PipeViewer GUI Version GitHub Link vvv
GitHub: https://github.com/cyberark/pipeviewer
Usage:
Invoke-PipeViewer -Help
Display this help information.
Invoke-PipeViewer -Print
Print the output to the console.
Invoke-PipeViewer -Export [FileName]
Export the output to JSON file with the specified name or 'NamedPipes.json' by default,
the json file can be imported by the PipeViewer non-shell version.
Examples:
# Print the named pipes details to the console.
Invoke-PipeViewer -Print
# Export the named pipes details to the given path with the name provided as a JSON file.
Invoke-PipeViewer -Export "C:\Path\To\CustomName2.json"
# Print the named pipes and export it to current directory.
Invoke-PipeViewer -Print -Export "CustomName1.json"
"@
Write-Host $helpText
return
}
# Import the required module
Import-Module NtObjectManager
function ConvertAccessMaskToSimplePermissions {
param (
[Parameter(Mandatory=$true)]
$AccessMask
)
switch ($AccessMask) {
2032127 { return "Full" } # 001F01FF
1245631 { return "RWX" } # 001301BF
1180095 { return "RWX" } # 001201BF
1180063 { return "RW" } # 0012019F
1048854 { return "W" } # 00100116
1179817 { return "RX" } # 001200A9
1180059 { return "R" } # 0012019B
default { return "(special)" }
}
}
function ConvertSidToName {
param (
[string]$sid
)
try {
$account = New-Object System.Security.Principal.SecurityIdentifier($sid)
$account.Translate([System.Security.Principal.NTAccount]).Value
} catch {
$sid # Return SID if translation fails
}
}
$processPIDsDictionary = @{}
function ProcessNameWithProcessPIDs {
param (
[NtApiDotNet.NtNamedPipeFileBase]$PipeObj
)
$processIds = $PipeObj.GetUsingProcessIds()
$processNames = @()
foreach ($curPid in $processIds) {
if ($processPIDsDictionary.ContainsKey($curPid)) {
$processNames += "$($processPIDsDictionary[$curPid]) ($curPid)"
} else {
try {
$process = [System.Diagnostics.Process]::GetProcessById($curPid)
$processPIDsDictionary[$curPid] = $process.ProcessName
$processNames += "$($process.ProcessName) ($curPid)"
} catch {
$processPIDsDictionary[$curPid] = "<no_process>"
$processNames += "<no_process> ($curPid)"
}
}
}
return $processNames -join "; "
}
# Define the Get-NamedPipeDetails function
function Get-NamedPipeDetails {
param (
[string]$PipeName
)
try {
$pipeObj = Get-NtFile -Path $PipeName -Win32Path
$owner = ConvertSidToName $pipeObj.SecurityDescriptor.Owner.Sid
$integrityLevel = $pipeObj.SecurityDescriptor.MandatoryLabel.IntegrityLevel
$clientPID = ProcessNameWithProcessPIDs -PipeObj $pipeObj
$pipeType = $pipeObj.PipeType.ToString()
$configuration = $pipeObj.Configuration.ToString()
$readMode = $pipeObj.ReadMode.ToString()
$numberOfLinks = $pipeObj.NumberOfLinks
$directoryGrantedAccess = $pipeObj.DirectoryGrantedAccess.ToString() #Getting More Information then We Get From the PipeViewer!
$grantedAccessString = $pipeObj.GrantedAccess.ToString() #Getting More Information then We Get in the PipeViewer!
$grantedAccessGeneric = $pipeObj.GrantedAccessGeneric.ToString() #Getting More Information then We Get in the PipeViewer!
$endpointType = $pipeObj.EndPointType.ToString()
$creationTime = $pipeObj.CreationTime.ToString("o")
$handle = $pipeObj.Handle.ToString()
# Format the permissions
$permissionsFormatted = ($pipeObj.SecurityDescriptor.Dacl | ForEach-Object {
$trusteeName = ConvertSidToName -sid $_.Sid
$permissionString = ConvertAccessMaskToSimplePermissions -AccessMask $_.Mask
"Allowed $permissionString $trusteeName"
}) -join "; `n"
$details = [PSCustomObject]@{
Name = $PipeName
IntegrityLevel = $integrityLevel
Permissions = $permissionsFormatted
ClientPID = $clientPID
PipeType = $pipeType
Configuration = $configuration
ReadMode = $readMode
NumberOfLinks = $numberOfLinks
DirectoryGrantedAccess = $directoryGrantedAccess
GrantedAccess = $grantedAccessString
GrantedAccessGeneric = $grantedAccessGeneric
CreationTime = $creationTime
OwnerName = $owner
EndPointType = $endpointType
Handle = $handle
}
return $details
} catch {
# When there is no Access add the Pipe with null arguments.
return [PSCustomObject]@{
Name = $PipeName
IntegrityLevel = $null
Permissions = $null
ClientPID = $null
PipeType = $null
Configuration = $null
ReadMode = $null
NumberOfLinks = $null
DirectoryGrantedAccess = $null
GrantedAccess = $null
GrantedAccessGeneric = $null
CreationTime = $null
OwnerName = $null
EndPointType = $null
Handle = $null
}
}
}
function Get-NamedPipes {
[System.IO.Directory]::GetFiles("\\.\pipe\")
}
# Main execution block
$namedPipes = Get-NamedPipes
$pipeDetailsList = @()
foreach ($pipe in $namedPipes) {
try {
$pipeDetails = Get-NamedPipeDetails -PipeName $pipe
if ($pipeDetails -ne $null) {
$pipeDetailsList += $pipeDetails
}
} catch {
Write-Error "Skipping pipe $pipe due to error: $_"
}
}
if ($Print) {
$pipeDetailsList | Format-List
}
if ($Export) {
$fileName = if ($FileName -eq "NamedPipes.json" -and $Export -ne $true) { $Export } else { $FileName }
$outputPath = if ($fileName.Contains("\") -or $fileName.Contains("/")) { $fileName } else { Join-Path -Path (Get-Location) -ChildPath $fileName }
$pipeDetailsList | ConvertTo-Json | Out-File -FilePath $outputPath
Write-Host "Details exported to '$outputPath'"
}
}