mirror of
https://github.com/NetSPI/PowerHuntShares.git
synced 2025-05-04 19:28:42 +02:00
Create parser-cisco-config.ps1
This commit is contained in:
parent
fcbc97cd67
commit
abe11cc684
316
Scripts/ConfigParsers/parser-cisco-config.ps1
Normal file
316
Scripts/ConfigParsers/parser-cisco-config.ps1
Normal file
@ -0,0 +1,316 @@
|
||||
# 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
|
||||
)
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# Command Example
|
||||
# Get-PwGrubConfig -FilePath "C:\temp\runing-config" -ComputerName "MyComputer" -ShareName "MyShare" -FileName runing-config
|
||||
|
||||
<# Example startup config
|
||||
|
||||
!
|
||||
! Cisco IOS Software, C3560 Software (C3560-IPBASEK9-M), Version 15.0(2)SE11
|
||||
! Compiled Mon 28-Mar-21 08:55 by prod_rel_team
|
||||
!
|
||||
version 15.0
|
||||
service timestamps debug datetime msec
|
||||
service timestamps log datetime msec
|
||||
no service password-recovery
|
||||
service password-encryption
|
||||
!
|
||||
hostname Router1
|
||||
!
|
||||
enable secret 5 $1$DkGh$XSdDk6LdoqM0eO67V0lJ71
|
||||
enable password mycleartextpassword
|
||||
!
|
||||
no aaa new-model
|
||||
!
|
||||
!
|
||||
username admin privilege 15 password 0 cleartext123
|
||||
username cisco privilege 15 password 7 12140A05171F15142F7C343F
|
||||
username secureadmin secret 5 $1$lpb1$kGc1R/tGbT6aYZEXw5lqa0
|
||||
!
|
||||
ip ssh version 2
|
||||
ip domain-name example.com
|
||||
!
|
||||
interface GigabitEthernet0/0
|
||||
description Uplink to ISP
|
||||
ip address 192.168.1.1 255.255.255.0
|
||||
duplex auto
|
||||
speed auto
|
||||
!
|
||||
interface GigabitEthernet0/1
|
||||
description Internal LAN
|
||||
ip address 192.168.2.1 255.255.255.0
|
||||
duplex auto
|
||||
speed auto
|
||||
!
|
||||
ip route 0.0.0.0 0.0.0.0 192.168.1.254
|
||||
!
|
||||
snmp-server community public RO
|
||||
snmp-server community private RW
|
||||
!
|
||||
line con 0
|
||||
exec-timeout 0 0
|
||||
password consolepassword123
|
||||
logging synchronous
|
||||
login
|
||||
!
|
||||
line vty 0 4
|
||||
password 7 02050D4808091B385C4B5E1A09121319
|
||||
logging synchronous
|
||||
login
|
||||
transport input ssh
|
||||
!
|
||||
interface Vlan1
|
||||
ip address 192.168.3.1 255.255.255.0
|
||||
no shutdown
|
||||
!
|
||||
dot11 ssid MySSID
|
||||
authentication open
|
||||
authentication key-management wpa
|
||||
wpa-psk ascii 0 cleartextkeywifipassword
|
||||
!
|
||||
banner motd ^C
|
||||
***********************************************
|
||||
Unauthorized access is prohibited!
|
||||
***********************************************
|
||||
^C
|
||||
!
|
||||
end
|
||||
|
||||
|
||||
|
||||
#>
|
||||
|
||||
<# 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
|
||||
}
|
||||
#>
|
Loading…
x
Reference in New Issue
Block a user