diff options
Diffstat (limited to 'Recon')
| -rw-r--r-- | Recon/PowerView.ps1 | 204 | 
1 files changed, 198 insertions, 6 deletions
diff --git a/Recon/PowerView.ps1 b/Recon/PowerView.ps1 index 8672e76..5823d18 100644 --- a/Recon/PowerView.ps1 +++ b/Recon/PowerView.ps1 @@ -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  }  |