Update PowerHuntShares.psm1

Added cisco startup / running config parser, and type7 encoder/decoder.
This commit is contained in:
Scott Sutherland 2024-10-06 10:28:15 -05:00 committed by GitHub
parent 7071e5ec49
commit 3e7217c280
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -4,7 +4,7 @@
#--------------------------------------
# Author: Scott Sutherland, 2024 NetSPI
# License: 3-clause BSD
# Version: v1.143
# Version: v1.144
# References: This script includes custom code and code taken and modified from the open source projects PowerView, Invoke-Ping, and Invoke-Parrell.
function Invoke-HuntSMBShares
{
@ -1539,6 +1539,8 @@ function Invoke-HuntSMBShares
$FileNamePatternsAll.Rows.Add("jboss-logmanager.properties*","","None.","Secret","") | Out-Null
$FileNamePatternsAll.Rows.Add("jenkins.model.JenkinsLocationConfiguration.*","","None.","Secret","") | Out-Null
$FileNamePatternsAll.Rows.Add("machine.config*","","None.","Secret","Get-PwMachineConfig") | Out-Null
$FileNamePatternsAll.Rows.Add("startup*","","None.","Secret","Get-PwCiscoConfig") | Out-Null
$FileNamePatternsAll.Rows.Add("running*","","None.","Secret","Get-PwCiscoConfig") | Out-Null
$FileNamePatternsAll.Rows.Add("my.*","","None.","Secret","Get-PwMySQLConfig") | Out-Null
$FileNamePatternsAll.Rows.Add("mysql.user*","","None.","Secret","") | Out-Null
$FileNamePatternsAll.Rows.Add("nginx.conf*","","None.","Secret","") | Out-Null
@ -26271,3 +26273,236 @@ function Get-PrivateKeyFilePath {
return $result
}
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Intended input: cisco configurations files (startup/run)
function Get-PwCiscoConfig {
param (
[string]$ComputerName = $null, # Optional
[string]$ShareName = $null, # Optional
[string]$UncFilePath = $null, # Optional
[string]$FileName = $null, # Optional
[string]$FilePath # Required
)
# Cisco Type 7 encryption key
$xlat = @(
0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64,
0x4a, 0x4b, 0x44, 0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39, 0x38, 0x33, 0x34, 0x6e, 0x63,
0x78, 0x76, 0x39, 0x38, 0x37, 0x33, 0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37
)
# Cisco Type 7 Password Decoder
function Decode-Type7 {
param (
[string]$EncodedPassword
)
# Initialize decoded password
$decodedPassword = ''
# Extract the seed and the encrypted portion
$seed = [convert]::ToInt32($EncodedPassword.Substring(0, 2)) # The first two characters as the seed
$encryptedPart = $EncodedPassword.Substring(2)
# Loop through the encrypted part and decrypt each byte
for ($i = 0; $i -lt $encryptedPart.Length; $i += 2) {
$currentByte = HexToInt $encryptedPart.Substring($i, 2)
$decodedChar = [char]($currentByte -bxor $xlat[$seed])
$decodedPassword += $decodedChar
$seed = ($seed + 1) % $xlat.Length # Reset seed if it reaches 51
}
return $decodedPassword
}
# Read the file content
$fileContent = Get-Content -Path $FilePath
# Regex patterns for different password types and usernames
$regexEnablePassword = '(?<=enable password\s)(\d*)\s*([^\s]+)' # Matches enable password (cleartext or encoded)
$regexEnableSecret = '(?<=enable secret\s5\s)([^\s]+)' # Matches enable secret 5 (encrypted password)
$regexUsernamePassword = 'username\s([^\s]+)\s(?:password|secret)\s(\d)\s([^\s]+)' # Matches username passwords (cleartext, encrypted, or encoded)
$regexGeneralPassword = '(?<=password\s)(\d*)\s*([^\s]+)' # Matches generic password lines, including ones without type indicator
$regexConsolePassword = '(?<=line con 0\s+password\s)(\d*)\s*([^\s]+)' # Matches console passwords
$regexSnmpCommunity = 'snmp-server community\s([^\s]+)\s(RO|RW)' # Matches SNMP community strings
$regexWpaPsk = 'wpa-psk ascii 0\s([^\s]+)' # Matches WPA PSK Wi-Fi passwords
# Array to store the parsed objects
$parsedPasswords = @()
foreach ($line in $fileContent) {
$object = [PSCustomObject]@{
ComputerName = $ComputerName
ShareName = $ShareName
UncFilePath = $UncFilePath
FileName = $FileName
Section = "NA"
ObjectName = 'Secret'
TargetURL = "NA"
TargetServer = "NA"
TargetPort = "NA"
Database = "NA"
Domain = "NA"
Username = "NA"
Password = "NA"
PasswordEnc = "NA"
KeyFilePath = "NA"
}
# Check for Enable secret 5 (encrypted, non-decodable)
if ($line -match $regexEnableSecret) {
$object.PasswordEnc = $matches[1].Trim()
$object.ObjectName = "EnableSecret (MD5 Encrypted)"
$parsedPasswords += $object
}
# Check for Enable password (cleartext or Type 7)
if ($line -match $regexEnablePassword) {
if ($matches[1] -eq "0" -or !$matches[1]) { # Handle both cleartext and cases without type indicator
$object.Password = $matches[2].Trim()
$object.ObjectName = "EnablePassword (Cleartext)"
}
elseif ($matches[1] -eq "7") {
$encodedPassword = $matches[2].Trim()
$decodedPassword = Decode-Type7 -EncodedPassword $encodedPassword
$object.Password = $decodedPassword
$object.PasswordEnc = $encodedPassword
$object.ObjectName = "EnablePassword (Type 7 Decrypted)"
}
$parsedPasswords += $object
}
# Check for Username passwords (cleartext, Type 7, or secret 5/MD5)
if ($line -match $regexUsernamePassword) {
$object.Username = $matches[1].Trim()
if ($matches[2] -eq "0") {
$object.Password = $matches[3].Trim()
$object.ObjectName = "Username Password (Cleartext)"
}
elseif ($matches[2] -eq "7") {
$encodedPassword = $matches[3].Trim()
$decodedPassword = Decode-Type7 -EncodedPassword $encodedPassword
$object.Password = $decodedPassword
$object.PasswordEnc = $encodedPassword
$object.ObjectName = "Username Password (Type 7 Decrypted)"
}
elseif ($matches[2] -eq "5") {
# MD5 encrypted password (not decodable)
$object.PasswordEnc = $matches[3].Trim()
$object.ObjectName = "Username Password (MD5 Encrypted)"
}
$parsedPasswords += $object
}
# Check for General password lines (cleartext or Type 7)
if ($line -match $regexGeneralPassword) {
if ($matches[1] -eq "0" -or !$matches[1]) { # Handle both cleartext and cases without type indicator
$object.Password = $matches[2].Trim()
$object.ObjectName = "Password (Cleartext)"
}
elseif ($matches[1] -eq "7") {
$encodedPassword = $matches[2].Trim()
$decodedPassword = Decode-Type7 -EncodedPassword $encodedPassword
$object.Password = $decodedPassword
$object.PasswordEnc = $encodedPassword
$object.ObjectName = "Password (Type 7 Decrypted)"
}
$parsedPasswords += $object
}
# Check for Console password (cleartext or Type 7)
if ($line -match $regexConsolePassword) {
if ($matches[1] -eq "0" -or !$matches[1]) { # Handle both cleartext and cases without type indicator
$object.Password = $matches[2].Trim()
$object.ObjectName = "ConsolePassword (Cleartext)"
}
elseif ($matches[1] -eq "7") {
$encodedPassword = $matches[2].Trim()
$decodedPassword = Decode-Type7 -EncodedPassword $encodedPassword
$object.Password = $decodedPassword
$object.PasswordEnc = $encodedPassword
$object.ObjectName = "ConsolePassword (Type 7 Decrypted)"
}
$parsedPasswords += $object
}
# Check for SNMP community strings (public/private with RO/RW)
if ($line -match $regexSnmpCommunity) {
$object.Password = $matches[1].Trim()
$object.ObjectName = "SNMP Community String ($($matches[2]))"
$parsedPasswords += $object
}
# Check for WPA PSK Wi-Fi passwords (cleartext)
if ($line -match $regexWpaPsk) {
$object.Password = $matches[1].Trim()
$object.ObjectName = "Wi-Fi WPA Pre-Shared Key (Cleartext)"
$parsedPasswords += $object
}
}
# Output the results
return $parsedPasswords
}
<# Cisco Configuration Bonus Functions - PowerShell Type 7 Encoder/Decoder
# Cisco Type 7 encryption key
$xlat = @(
0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64,
0x4a, 0x4b, 0x44, 0x48, 0x53, 0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36, 0x39, 0x38, 0x33, 0x34, 0x6e, 0x63,
0x78, 0x76, 0x39, 0x38, 0x37, 0x33, 0x32, 0x35, 0x34, 0x6b, 0x3b, 0x66, 0x67, 0x38, 0x37
)
# Helper function to convert hex string to int
function HexToInt($hexStr) {
return [convert]::ToInt32($hexStr, 16)
}
# Cisco Type 7 Password Decoder
function Decode-Type7 {
param (
[string]$EncodedPassword
)
# Initialize decoded password
$decodedPassword = ''
# Extract the seed and the encrypted portion
$seed = [convert]::ToInt32($EncodedPassword.Substring(0, 2)) # The first two characters as the seed
$encryptedPart = $EncodedPassword.Substring(2)
# Loop through the encrypted part and decrypt each byte
for ($i = 0; $i -lt $encryptedPart.Length; $i += 2) {
$currentByte = HexToInt $encryptedPart.Substring($i, 2)
$decodedChar = [char]($currentByte -bxor $xlat[$seed])
$decodedPassword += $decodedChar
$seed = ($seed + 1) % $xlat.Length # Reset seed if it reaches 51
}
return $decodedPassword
}
# Cisco Type 7 Password Encoder
function Encode-Type7 {
param (
[string]$PlainPassword
)
# Generate random seed between 0 and 15
$seed = Get-Random -Minimum 0 -Maximum 15
$encodedPassword = "{0:D2}" -f $seed # Append seed in two-digit format
# Encrypt each character
for ($i = 0; $i -lt $PlainPassword.Length; $i++) {
$charValue = [byte][char]$PlainPassword[$i]
$encodedByte = $charValue -bxor $xlat[$seed]
$encodedPassword += "{0:X2}" -f $encodedByte
$seed = ($seed + 1) % $xlat.Length # Reset seed if it reaches 51
}
return $encodedPassword
}
#>