mirror of
https://github.com/cyberark/PipeViewer
synced 2026-06-06 15:34:28 +00:00
b6b7d7f12d
Or exporting the names pipes to a Json file suitable for PipeViewer tool.
233 lines
9.0 KiB
PowerShell
233 lines
9.0 KiB
PowerShell
# 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'"
|
|
}
|
|
} |