diff --git a/PoshNmap/Formats/PoshNmapHost.Format.ps1xml b/PoshNmap/Formats/PoshNmapHost.Format.ps1xml new file mode 100644 index 0000000..1f09d60 --- /dev/null +++ b/PoshNmap/Formats/PoshNmapHost.Format.ps1xml @@ -0,0 +1,63 @@ + + + + + PoshNmapHost + + PoshNmapHost + + + + + + 15 + + + + + 6 + + + 5 + + + + + + + + + + IPv4 + + + FQDN + + + Status + + + OpenPorts + + + + $ports = @() + foreach ($portItem in $PSItem.ports) { + if ($portItem.Services.Name -ne 'unknown') {$ports += $portItem.Services.Name} + else {$ports += $portItem.protocol,$portItem.port -join '/'} + } + $ports -join ', ' + + + + + + + + + + \ No newline at end of file diff --git a/PoshNmap/PoshNmap.psd1 b/PoshNmap/PoshNmap.psd1 index 462751e..b6e6b1d 100644 --- a/PoshNmap/PoshNmap.psd1 +++ b/PoshNmap/PoshNmap.psd1 @@ -63,7 +63,7 @@ PowerShellVersion = '5.1' # TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module -# FormatsToProcess = @() +FormatsToProcess = @('.\Formats\*.Format.ps1xml') # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # NestedModules = @() diff --git a/PoshNmap/Private/ConvertFromCPE.ps1 b/PoshNmap/Private/ConvertFromCPE.ps1 new file mode 100644 index 0000000..0a50e38 --- /dev/null +++ b/PoshNmap/Private/ConvertFromCPE.ps1 @@ -0,0 +1,40 @@ +function ConvertFromCPE { +<# +.SYNOPSIS +Converts a common platform enumeration string into a powershell object +.LINK +https://nmap.org/book/output-formats-cpe.html +#> + [CmdletBinding()] + param ( + [Parameter(Mandatory,ValueFromPipeline)][String]$CPE + ) + + process { + if ($CPE -notlike 'cpe:/*') {write-error "$CPE is not a valid CPE string";return} + + $CPEParts = $CPE -split ':' + + [PSCustomObject]@{ + PSTypeName = 'PoshNmapCommonPlatformEnumeration' + Type = switch ($CPEParts[1]) { + '/a' { + 'Application' + } + '/h' { + 'Hardware' + } + '/o' { + 'OS' + } + } + Product = $CPEParts[2] + Version = $CPEParts[3] + Update = $CPEParts[4] + Edition = $CPEParts[5] + Language = $CPEParts[6] + } + } + + +} \ No newline at end of file diff --git a/PoshNmap/Private/FormatPoshNmapHost.ps1 b/PoshNmap/Private/FormatPoshNmapHost.ps1 index abdc5c6..ef89f56 100644 --- a/PoshNmap/Private/FormatPoshNmapHost.ps1 +++ b/PoshNmap/Private/FormatPoshNmapHost.ps1 @@ -1,5 +1,4 @@ using namespace Management.Automation -Update-TypeData -TypeName PoshNmapHost -DefaultDisplayPropertySet IPv4,FQDN,Status,OpenPorts -Force function FormatPoshNmapHost { [CmdletBinding()] param ( @@ -19,7 +18,6 @@ function FormatPoshNmapHost { Hostname = $null Status = ($hostnode.status.state.Trim() | where length -ge 2) FQDNs = $hostnode.hostnames.hostname.name | select -Unique - FDQN = $null IPv4 = $null IPv6 = $null MAC = $null @@ -27,7 +25,7 @@ function FormatPoshNmapHost { Ports = New-Object Collections.ArrayList OpenPorts = $hostnode.ports.port | measure | % count } - $entry.FQDN = $entry.FQDNs | select -first 1 + $entry.FQDN = if ($hostnode.hostnames.hostname | where type -eq 'user') {$hostnode.hostnames.hostname | where type -eq 'user' | % name} else {$entry.FQDNs | select -first 1} $entry.Hostname = $entry.FQDN -replace '^(\w+)\..*$','$1' FormatStringOut -InputObject $entry.Ports {$this.ports | measure | % count} @@ -49,21 +47,10 @@ function FormatPoshNmapHost { State=$_.state ScriptResult = @{} } - $portResult | FormatStringOut -scriptblock {$this.protocol,$this.port -join ':'} + $portResult | FormatStringOut -scriptblock {$this.services.name -join ','} $portResult.State | FormatStringOut -scriptblock {$this.state} $portResult.Services | FormatStringOut -scriptblock {($this.name,$this.product -join ':') + " ($([int]($this.conf) * 10)%)"} - #TODO: Refactor this now that I'm better at Powershell :) - # Build Services property. What a mess...but exclude non-open/non-open|filtered ports and blank service info, and exclude servicefp too for the sake of tidiness. - if ($_.state.state -like "open*" -and ($_.service.tunnel.length -gt 2 -or $_.service.product.length -gt 2 -or $_.service.proto.length -gt 2)) { - $OutputDelimiter = ', ' - $entry.Services += ($_.protocol,$_.portid,$service -join ':')+ - ':'+ - ($_.service.product,$_.service.version,$_.service.tunnel,$_.service.proto,$_.service.rpcnum -join " ").Trim() + - " <" + - ([Int] $_.service.conf * 10) + "%-confidence>$OutputDelimiter" - } - #Port Script Result Processing foreach ($scriptItem in $_.script) { $scriptResultEntry = [ordered]@{ @@ -97,6 +84,9 @@ function FormatPoshNmapHost { $entry.OSGuesses = $hostnode.os.osmatch if (@($entry.OSGuesses).count -lt 1) { $entry.OS = $null } + $entry.Inventory = $hostnode.ports.port.service.cpe | select -unique | ConvertFromCpe + + #TODO: Refactor this if ($hostnode.hostscript -ne $null) { $hostnode.hostscript.script | foreach-object { $entry.Script += '' + $OutputDelimiter + ($_.output.replace("`n","$OutputDelimiter")) + "$OutputDelimiter $OutputDelimiter $OutputDelimiter"