mirror of
https://github.com/PowerShellMafia/PowerSploit
synced 2026-06-08 12:13:33 +00:00
+198
-6
@@ -5138,13 +5138,13 @@ function Get-DFSshare {
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-DFSshare
|
||||
|
||||
|
||||
Returns all distributed file system shares for the current domain.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-DFSshare -Domain test
|
||||
|
||||
|
||||
Returns all distributed file system shares for the 'test' domain.
|
||||
#>
|
||||
|
||||
@@ -5171,6 +5171,185 @@ function Get-DFSshare {
|
||||
$Credential
|
||||
)
|
||||
|
||||
function Parse-Pkt {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[byte[]]
|
||||
$Pkt
|
||||
)
|
||||
|
||||
$bin = $Pkt
|
||||
$blob_version = [bitconverter]::ToUInt32($bin[0..3],0)
|
||||
$blob_element_count = [bitconverter]::ToUInt32($bin[4..7],0)
|
||||
#Write-Host "Element Count: " $blob_element_count
|
||||
$offset = 8
|
||||
#https://msdn.microsoft.com/en-us/library/cc227147.aspx
|
||||
$object_list = @()
|
||||
for($i=1; $i -le $blob_element_count; $i++){
|
||||
$blob_name_size_start = $offset
|
||||
$blob_name_size_end = $offset + 1
|
||||
$blob_name_size = [bitconverter]::ToUInt16($bin[$blob_name_size_start..$blob_name_size_end],0)
|
||||
#Write-Host "Blob name size: " $blob_name_size
|
||||
$blob_name_start = $blob_name_size_end + 1
|
||||
$blob_name_end = $blob_name_start + $blob_name_size - 1
|
||||
$blob_name = [System.Text.Encoding]::Unicode.GetString($bin[$blob_name_start..$blob_name_end])
|
||||
#Write-Host "Blob Name: " $blob_name
|
||||
$blob_data_size_start = $blob_name_end + 1
|
||||
$blob_data_size_end = $blob_data_size_start + 3
|
||||
$blob_data_size = [bitconverter]::ToUInt32($bin[$blob_data_size_start..$blob_data_size_end],0)
|
||||
#Write-Host "blob data size: " $blob_data_size
|
||||
$blob_data_start = $blob_data_size_end + 1
|
||||
$blob_data_end = $blob_data_start + $blob_data_size - 1
|
||||
$blob_data = $bin[$blob_data_start..$blob_data_end]
|
||||
switch -wildcard ($blob_name) {
|
||||
"\siteroot" { }
|
||||
"\domainroot*" {
|
||||
# Parse DFSNamespaceRootOrLinkBlob object. Starts with variable length DFSRootOrLinkIDBlob which we parse first...
|
||||
# DFSRootOrLinkIDBlob
|
||||
$root_or_link_guid_start = 0
|
||||
$root_or_link_guid_end = 15
|
||||
$root_or_link_guid = [byte[]]$blob_data[$root_or_link_guid_start..$root_or_link_guid_end]
|
||||
$guid = New-Object Guid(,$root_or_link_guid) # should match $guid_str
|
||||
$prefix_size_start = $root_or_link_guid_end + 1
|
||||
$prefix_size_end = $prefix_size_start + 1
|
||||
$prefix_size = [bitconverter]::ToUInt16($blob_data[$prefix_size_start..$prefix_size_end],0)
|
||||
$prefix_start = $prefix_size_end + 1
|
||||
$prefix_end = $prefix_start + $prefix_size - 1
|
||||
$prefix = [System.Text.Encoding]::Unicode.GetString($blob_data[$prefix_start..$prefix_end])
|
||||
#write-host "Prefix: " $prefix
|
||||
$short_prefix_size_start = $prefix_end + 1
|
||||
$short_prefix_size_end = $short_prefix_size_start + 1
|
||||
$short_prefix_size = [bitconverter]::ToUInt16($blob_data[$short_prefix_size_start..$short_prefix_size_end],0)
|
||||
$short_prefix_start = $short_prefix_size_end + 1
|
||||
$short_prefix_end = $short_prefix_start + $short_prefix_size - 1
|
||||
$short_prefix = [System.Text.Encoding]::Unicode.GetString($blob_data[$short_prefix_start..$short_prefix_end])
|
||||
#write-host "Short Prefix: " $short_prefix
|
||||
$type_start = $short_prefix_end + 1
|
||||
$type_end = $type_start + 3
|
||||
$type = [bitconverter]::ToUInt32($blob_data[$type_start..$type_end],0)
|
||||
#write-host $type
|
||||
$state_start = $type_end + 1
|
||||
$state_end = $state_start + 3
|
||||
$state = [bitconverter]::ToUInt32($blob_data[$state_start..$state_end],0)
|
||||
#write-host $state
|
||||
$comment_size_start = $state_end + 1
|
||||
$comment_size_end = $comment_size_start + 1
|
||||
$comment_size = [bitconverter]::ToUInt16($blob_data[$comment_size_start..$comment_size_end],0)
|
||||
$comment_start = $comment_size_end + 1
|
||||
$comment_end = $comment_start + $comment_size - 1
|
||||
if ($comment_size -gt 0) {
|
||||
$comment = [System.Text.Encoding]::Unicode.GetString($blob_data[$comment_start..$comment_end])
|
||||
#Write-Host $comment
|
||||
}
|
||||
$prefix_timestamp_start = $comment_end + 1
|
||||
$prefix_timestamp_end = $prefix_timestamp_start + 7
|
||||
# https://msdn.microsoft.com/en-us/library/cc230324.aspx FILETIME
|
||||
$prefix_timestamp = $blob_data[$prefix_timestamp_start..$prefix_timestamp_end] #dword lowDateTime #dword highdatetime
|
||||
$state_timestamp_start = $prefix_timestamp_end + 1
|
||||
$state_timestamp_end = $state_timestamp_start + 7
|
||||
$state_timestamp = $blob_data[$state_timestamp_start..$state_timestamp_end]
|
||||
$comment_timestamp_start = $state_timestamp_end + 1
|
||||
$comment_timestamp_end = $comment_timestamp_start + 7
|
||||
$comment_timestamp = $blob_data[$comment_timestamp_start..$comment_timestamp_end]
|
||||
$version_start = $comment_timestamp_end + 1
|
||||
$version_end = $version_start + 3
|
||||
$version = [bitconverter]::ToUInt32($blob_data[$version_start..$version_end],0)
|
||||
|
||||
#write-host $version
|
||||
if ($version -ne 3)
|
||||
{
|
||||
#write-host "error"
|
||||
}
|
||||
|
||||
# Parse rest of DFSNamespaceRootOrLinkBlob here
|
||||
$dfs_targetlist_blob_size_start = $version_end + 1
|
||||
$dfs_targetlist_blob_size_end = $dfs_targetlist_blob_size_start + 3
|
||||
$dfs_targetlist_blob_size = [bitconverter]::ToUInt32($blob_data[$dfs_targetlist_blob_size_start..$dfs_targetlist_blob_size_end],0)
|
||||
#write-host $dfs_targetlist_blob_size
|
||||
$dfs_targetlist_blob_start = $dfs_targetlist_blob_size_end + 1
|
||||
$dfs_targetlist_blob_end = $dfs_targetlist_blob_start + $dfs_targetlist_blob_size - 1
|
||||
$dfs_targetlist_blob = $blob_data[$dfs_targetlist_blob_start..$dfs_targetlist_blob_end]
|
||||
$reserved_blob_size_start = $dfs_targetlist_blob_end + 1
|
||||
$reserved_blob_size_end = $reserved_blob_size_start + 3
|
||||
$reserved_blob_size = [bitconverter]::ToUInt32($blob_data[$reserved_blob_size_start..$reserved_blob_size_end],0)
|
||||
#write-host $reserved_blob_size
|
||||
$reserved_blob_start = $reserved_blob_size_end + 1
|
||||
$reserved_blob_end = $reserved_blob_start + $reserved_blob_size - 1
|
||||
$reserved_blob = $blob_data[$reserved_blob_start..$reserved_blob_end]
|
||||
$referral_ttl_start = $reserved_blob_end + 1
|
||||
$referral_ttl_end = $referral_ttl_start + 3
|
||||
$referral_ttl = [bitconverter]::ToUInt32($blob_data[$referral_ttl_start..$referral_ttl_end],0)
|
||||
|
||||
#Parse DFSTargetListBlob
|
||||
$target_count_start = 0
|
||||
$target_count_end = $target_count_start + 3
|
||||
$target_count = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_count_start..$target_count_end],0)
|
||||
$t_offset = $target_count_end + 1
|
||||
#write-host $target_count
|
||||
|
||||
for($j=1; $j -le $target_count; $j++){
|
||||
$target_entry_size_start = $t_offset
|
||||
$target_entry_size_end = $target_entry_size_start + 3
|
||||
$target_entry_size = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_entry_size_start..$target_entry_size_end],0)
|
||||
#write-host $target_entry_size
|
||||
$target_time_stamp_start = $target_entry_size_end + 1
|
||||
$target_time_stamp_end = $target_time_stamp_start + 7
|
||||
# FILETIME again or special if priority rank and priority class 0
|
||||
$target_time_stamp = $dfs_targetlist_blob[$target_time_stamp_start..$target_time_stamp_end]
|
||||
$target_state_start = $target_time_stamp_end + 1
|
||||
$target_state_end = $target_state_start + 3
|
||||
$target_state = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_state_start..$target_state_end],0)
|
||||
#write-host $target_state
|
||||
$target_type_start = $target_state_end + 1
|
||||
$target_type_end = $target_type_start + 3
|
||||
$target_type = [bitconverter]::ToUInt32($dfs_targetlist_blob[$target_type_start..$target_type_end],0)
|
||||
#write-host $target_type
|
||||
$server_name_size_start = $target_type_end + 1
|
||||
$server_name_size_end = $server_name_size_start + 1
|
||||
$server_name_size = [bitconverter]::ToUInt16($dfs_targetlist_blob[$server_name_size_start..$server_name_size_end],0)
|
||||
#write-host $server_name_size
|
||||
$server_name_start = $server_name_size_end + 1
|
||||
$server_name_end = $server_name_start + $server_name_size - 1
|
||||
$server_name = [System.Text.Encoding]::Unicode.GetString($dfs_targetlist_blob[$server_name_start..$server_name_end])
|
||||
#write-host $server_name
|
||||
$share_name_size_start = $server_name_end + 1
|
||||
$share_name_size_end = $share_name_size_start + 1
|
||||
$share_name_size = [bitconverter]::ToUInt16($dfs_targetlist_blob[$share_name_size_start..$share_name_size_end],0)
|
||||
$share_name_start = $share_name_size_end + 1
|
||||
$share_name_end = $share_name_start + $share_name_size - 1
|
||||
$share_name = [System.Text.Encoding]::Unicode.GetString($dfs_targetlist_blob[$share_name_start..$share_name_end])
|
||||
#write-host $share_name
|
||||
$target_list += "\\$server_name\$share_name"
|
||||
$t_offset = $share_name_end + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
$offset = $blob_data_end + 1
|
||||
$dfs_pkt_properties = @{
|
||||
'Name' = $blob_name
|
||||
'Prefix' = $prefix
|
||||
'TargetList' = $target_list
|
||||
}
|
||||
$object_list += New-Object -TypeName PSObject -Property $dfs_pkt_properties
|
||||
$prefix = $null
|
||||
$blob_name = $null
|
||||
$target_list = $null
|
||||
}
|
||||
|
||||
$servers = @()
|
||||
$object_list | ForEach-Object {
|
||||
#write-host $_.Name;
|
||||
#write-host $_.TargetList
|
||||
if ($_.TargetList) {
|
||||
$_.TargetList | ForEach-Object {
|
||||
$servers += $_.split("\")[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$servers
|
||||
}
|
||||
|
||||
function Get-DFSshareV1 {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
@@ -5183,7 +5362,7 @@ function Get-DFSshare {
|
||||
[String]
|
||||
$ADSpath,
|
||||
|
||||
[ValidateRange(1,10000)]
|
||||
[ValidateRange(1,10000)]
|
||||
[Int]
|
||||
$PageSize = 200,
|
||||
|
||||
@@ -5201,6 +5380,7 @@ function Get-DFSshare {
|
||||
$DFSSearcher.FindAll() | Where-Object {$_} | ForEach-Object {
|
||||
$Properties = $_.Properties
|
||||
$RemoteNames = $Properties.remoteservername
|
||||
$Pkt = $Properties.pkt
|
||||
|
||||
$DFSshares += $RemoteNames | ForEach-Object {
|
||||
try {
|
||||
@@ -5213,9 +5393,21 @@ function Get-DFSshare {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$redirects = Parse-Pkt $pkt[0]
|
||||
$redirects | ForEach-Object {
|
||||
# If a folder doesn't have a redirection it will
|
||||
# have a target like
|
||||
# \\null\TestNameSpace\folder\.DFSFolderLink so we
|
||||
# do actually want to match on "null" rather than
|
||||
# $null
|
||||
if ($_ -ne "null") {
|
||||
New-Object -TypeName PSObject -Property @{'Name'=$Properties.name[0];'RemoteServerName'=$_}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Get-DFSshareV2 error : $_"
|
||||
Write-Warning "Get-DFSshareV1 error : $_"
|
||||
}
|
||||
$DFSshares | Sort-Object -Property "RemoteServerName"
|
||||
}
|
||||
@@ -5276,7 +5468,7 @@ function Get-DFSshare {
|
||||
}
|
||||
|
||||
$DFSshares = @()
|
||||
|
||||
|
||||
if ( ($Version -eq "all") -or ($Version.endsWith("1")) ) {
|
||||
$DFSshares += Get-DFSshareV1 -Domain $Domain -DomainController $DomainController -Credential $Credential -ADSpath $ADSpath -PageSize $PageSize
|
||||
}
|
||||
@@ -5284,7 +5476,7 @@ function Get-DFSshare {
|
||||
$DFSshares += Get-DFSshareV2 -Domain $Domain -DomainController $DomainController -Credential $Credential -ADSpath $ADSpath -PageSize $PageSize
|
||||
}
|
||||
|
||||
$DFSshares | Sort-Object -Property "RemoteServerName"
|
||||
$DFSshares | Sort-Object -Property ("RemoteServerName","Name") -Unique
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user