Add files via upload

This commit is contained in:
Scott Sutherland 2024-09-23 10:35:53 -05:00 committed by GitHub
parent 17af4fbf30
commit a17ceeb6aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 4559 additions and 0 deletions

View File

@ -0,0 +1,695 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# This is for parsing group policy preference files and should support groups.xml, datasources.xml, drives.xml, printers.xml, scheduletasks.xml, and services.xml
function Get-GPPPasswordMod {
<#
.SYNOPSIS
Retrieves plaintext passwords from specified Group Policy XML files and provides functionality to encrypt passwords.
.DESCRIPTION
This function processes specified GPP XML files and retrieves plaintext passwords for accounts pushed through Group Policy Preferences.
It also provides a method to encrypt passwords for use in XML files.
.EXAMPLE
PS C:\> Get-GPPPasswordMod -InputFilePath "\\192.168.1.1\sysvol\demo.com\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\USER\Preferences"
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[string]$InputFilePath
)
# ----------------------------------------------------------------
# Function to decrypt cpassword
# ----------------------------------------------------------------
function Get-DecryptedCpassword {
[CmdletBinding()]
Param (
[string] $Cpassword
)
try {
# Append padding
$Mod = ($Cpassword.length % 4)
switch ($Mod) {
'1' { $Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1) }
'2' { $Cpassword += ('=' * (4 - $Mod)) }
'3' { $Cpassword += ('=' * (4 - $Mod)) }
}
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$DecryptorObject = $AesObject.CreateDecryptor()
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
} catch { Write-Error $Error[0] }
}
# ----------------------------------------------------------------
# Setup data table to store GPP Information
# ----------------------------------------------------------------
if ($InputFilePath) {
$TableGPPPasswords = New-Object System.Data.DataTable
$TableGPPPasswords.Columns.Add('NewName') | Out-Null
$TableGPPPasswords.Columns.Add('Changed') | Out-Null
$TableGPPPasswords.Columns.Add('UserName') | Out-Null
$TableGPPPasswords.Columns.Add('CPassword') | Out-Null
$TableGPPPasswords.Columns.Add('Password') | Out-Null
$TableGPPPasswords.Columns.Add('File') | Out-Null
# ----------------------------------------------------------------
# Find, parse, decrypt, and display results from XML files
# ----------------------------------------------------------------
$XmlFiles = Get-ChildItem -Path $InputFilePath -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','ScheduledTasks.xml','DataSources.xml','Printers.xml','Drives.xml'
# Parse GPP config files
$XmlFiles | ForEach-Object {
$FileFullName = $_.FullName
$FileName = $_.Name
# Read the file content as a string
$fileContentString = Get-Content -Path "$FileFullName" -Raw
try {
# Attempt to load the XML content
[xml]$FileContent = [xml]$fileContentString
} catch {
Write-Error "Failed to parse XML in file '$FileFullName'. Error: $_"
return
}
# Process Drives.xml
if ($FileName -eq "Drives.xml") {
$FileContent.Drives.Drive | ForEach-Object {
[string]$Username = $_.Properties.username
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = ""
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
# Process Groups.xml
if ($FileName -eq "Groups.xml") {
$FileContent.Groups.User | ForEach-Object {
[string]$Username = $_.Properties.username
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = $_.Properties.newname
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
# Process Services.xml
if ($FileName -eq "Services.xml") {
$FileContent.NTServices.NTService | ForEach-Object {
[string]$Username = $_.Properties.accountname
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = ""
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
# Process ScheduledTasks.xml
if ($FileName -eq "ScheduledTasks.xml") {
$FileContent.ScheduledTasks.Task | ForEach-Object {
[string]$Username = $_.Properties.runas
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = ""
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
# Process DataSources.xml
if ($FileName -eq "DataSources.xml") {
$FileContent.DataSources.DataSource | ForEach-Object {
[string]$Username = $_.Properties.username
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = ""
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
# Process Printers.xml
if ($FileName -eq "Printers.xml") {
$FileContent.Printers.SharedPrinter | ForEach-Object {
[string]$Username = $_.Properties.username
[string]$CPassword = $_.Properties.cpassword
[string]$Password = Get-DecryptedCpassword $CPassword
[datetime]$Changed = $_.Changed
[string]$NewName = ""
$TableGPPPasswords.Rows.Add($NewName, $Changed, $Username, $CPassword, $Password, $FileFullName) | Out-Null
}
}
}
# Check if anything was found
if (-not $XmlFiles) {
throw 'No preference files found.'
return
}
# Display results
$TableGPPPasswords
}
# Allow users to encrypt passwords
function Set-EncryptedCpassword {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Password
)
# Create a new AES .NET Crypto Object
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$EncryptorObject = $AesObject.CreateEncryptor()
# Convert password to byte array and encrypt
[Byte[]] $InputBytes = [System.Text.Encoding]::Unicode.GetBytes($Password)
[Byte[]] $EncryptedBytes = $EncryptorObject.TransformFinalBlock($InputBytes, 0, $InputBytes.Length)
$EncryptedCpassword = [Convert]::ToBase64String($EncryptedBytes)
return $EncryptedCpassword
}
}
# Example path to the directory containing the GPP XML files
$pathToGPPFiles = "c:\temp\configs\ScheduledTasks.xml"
# Call the function
$gppPasswords = Get-GPPPasswordMod -InputFilePath $pathToGPPFiles
# Display the results
$gppPasswords
<# Bonus function for encrypting password
# ----------------------------------------------------------------
# Function to encrypt a password
# ----------------------------------------------------------------
function Set-EncryptedCpassword {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Password
)
# Create a new AES .NET Crypto Object
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
$AesIV = New-Object Byte[]($AesObject.IV.Length)
$AesObject.IV = $AesIV
$AesObject.Key = $AesKey
$EncryptorObject = $AesObject.CreateEncryptor()
# Convert password to byte array and encrypt
[Byte[]] $InputBytes = [System.Text.Encoding]::Unicode.GetBytes($Password)
[Byte[]] $EncryptedBytes = $EncryptorObject.TransformFinalBlock($InputBytes, 0, $InputBytes.Length)
$EncryptedCpassword = [Convert]::ToBase64String($EncryptedBytes)
return $EncryptedCpassword
}
$plainTextPassword = "MyAwesomePassword!"
$encryptedPassword = Set-EncryptedCpassword -Password $plainTextPassword
Write-Output $encryptedPassword
#>
<# Printers.xml
<?xml version="1.0" encoding="utf-8"?>
<Printers
clsid="{1F577D12-3D1B-471e-A1B7-060317597B9C}"
disabled="1">
<SharedPrinter
clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}"
name="b35-1053-a" status="b35-1053-a"
image="2"
changed="2007-07-06 20:49:50"
uid="{D954AF72-DDFC-498D-A185-A569A0D02FC4}">
<Properties
action="U"
comment=""
path="\\PRN-CORP1\b35-1053-a"
location=""
default="1"
skipLocal="1"
deleteAll="0"
persistent="0"
deleteMaps="0"
cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3"
port=""/>
</SharedPrinter>
<PortPrinter
clsid="{C3A739D2-4A44-401e-9F9D-88E5E77DFB3E}"
name="10.10.10.10"
status="10.10.10.10"
image="2"
changed="2007-07-06 20:50:43"
uid="{6A331F02-C488-44B6-988C-0730C2C1E374}">
<Properties
ipAddress="10.10.10.10"
action="U"
location="1st Floor"
localName="Lexmark 1150S"
comment="Only for use by graphics"
default="1"
skipLocal="1"
useDNS="0"
path="Lexmark 1150S (Color)"
deleteAll="0"
lprQueue=""
snmpCommunity="Local"
protocol="PROTOCOL_RAWTCP_TYPE"
portNumber="9100"
doubleSpool="0"
snmpEnabled="1"
snmpDevIndex="1"/>
</PortPrinter>
<LocalPrinter
clsid="{F08996D5-568B-45f5-BB7A-D3FB1E370B0A}"
name="Epsom DotMatrix"
status="1st Floor Copy Room"
image="2"
changed="2007-07-06 20:51:47"
uid="{65D3663D-BC4E-45D2-8EA8-1DB3AC7158CB}">
<Properties
action="U"
name="Epsom DotMatrix"
port="LPT1:"
path="EpsomDots"
default="1"
deleteAll="0"
location="1st Floor Copy Room"
comment="Old printer. Don't use."/>
</LocalPrinter>
</Printers>
#>
<# ScheduledTasks.xml
<?xml version="1.0" encoding="utf-8"?>
<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"
disabled="1">
<Task clsid="{2DEECB1C-261F-4e13-9B21-16FB83BC03BD}"
name="Cleanup"
image="2"
changed="2007-07-06 20:54:40"
uid="{96C2DBEF-ECAE-4BD4-B1C7-0CD71116595C}">
<Filters>
<FilterOs hidden="1"
not="1"
bool="AND"
class="NT"
version="VISTA"
type="NE"
edition="NE"
sp="NE"/>
</Filters>
<Properties action="U"
name="Cleanup"
appName="\\scratch\filecleanup.exe"
args="-all"
startIn="c:\"
comment="Runs for almost 4 hours"
enabled="1"
deleteWhenDone="0"
startOnlyIfIdle="0"
stopOnIdleEnd="0"
noStartIfOnBatteries="1"
stopIfGoingOnBatteries="1"
cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3"
systemRequired="0">
<Triggers>
<Trigger type="DAILY"
startHour="10"
startMinutes="0"
beginYear="2007"
beginMonth="7"
beginDay="6"
hasEndDate="0"
repeatTask="0"
interval="1"/>
</Triggers>
</Properties>
</Task>
<ImmediateTask clsid="{9F030D12-DDA3-4C26-8548-B7CE9151166A}"
name="PingCorporate"
changed="2007-07-06 20:55:15"
uid="{3D15BAA9-E05A-470C-9298-FA4C0B701695}">
<Filters>
<FilterOs hidden="1"
not="1"
bool="AND"
class="NT"
version="VISTA"
type="NE"
edition="NE"
sp="NE"/>
</Filters>
<Properties name="PingCorporate"
appName="c:\ping.exe"
args="-ip 10.10.10.10"
startIn=""
comment=""
maxRunTime="259200000"
startOnlyIfIdle="1"
idleMinutes="10"
deadlineMinutes="60"
stopOnIdleEnd="0"
noStartIfOnBatteries="1"
stopIfGoingOnBatteries="1"
systemRequired="0"/>
</ImmediateTask>
<TaskV2 clsid="{D8896631-B747-47a7-84A6-C155337F3BC8}"
name="Demo"
image="2"
changed="2008-05-28 21:07:40"
uid="{BA81EFFF-E567-4CB8-8708-6C17A5950B0A}"
bypassErrors="0"
userContext="0" removePolicy="0"
desc="This is a test of the system.">
<Properties action="U"
name="Demo"
runAs="%LogonDomain%\%LogonUser%"
logonType="InteractiveToken">
<Task version="1.2">
<RegistrationInfo>
<Author>WIN-P3LTV7KC6IO\Administrator</Author>
<Description>Demo</Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<UserId>%LogonDomain%\%LogonUser</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>LeastPrivilege</RunLevel>
</Principal>
</Principals>
<Settings>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>true</RestartOnIdle>
</IdleSettings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>true</RunOnlyIfIdle>
<WakeToRun>true</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Triggers>
<TimeTrigger>
<StartBoundary>2008-05-28T14:06:04</StartBoundary>
<Enabled>true</Enabled>
</TimeTrigger>
<CalendarTrigger>
<StartBoundary>2008-05-28T14:06:08</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
<CalendarTrigger>
<StartBoundary>2008-05-28T14:06:11</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByWeek>
<WeeksInterval>1</WeeksInterval>
<DaysOfWeek>
<Sunday/>
<Thursday/>
</DaysOfWeek>
</ScheduleByWeek>
</CalendarTrigger>
<CalendarTrigger>
<StartBoundary>2008-05-28T14:06:16</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByMonth>
<DaysOfMonth>
<Day>1</Day>
</DaysOfMonth>
<Months>
<January/>
</Months>
</ScheduleByMonth>
</CalendarTrigger>
<LogonTrigger>
<Enabled>true</Enabled>
</LogonTrigger>
<BootTrigger>
<Enabled>true</Enabled>
</BootTrigger>
<IdleTrigger>
<Enabled>true</Enabled>
</IdleTrigger>
<RegistrationTrigger>
<Enabled>true</Enabled>
</RegistrationTrigger>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>RemoteConnect</StateChange>
</SessionStateChangeTrigger>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>RemoteConnect</StateChange>
</SessionStateChangeTrigger>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>SessionLock</StateChange>
</SessionStateChangeTrigger>
<SessionStateChangeTrigger>
<Enabled>true</Enabled>
<StateChange>SessionUnlock</StateChange>
</SessionStateChangeTrigger>
</Triggers>
<Actions>
<Exec>
<Command>a</Command>
<Arguments>b</Arguments>
<WorkingDirectory>c</WorkingDirectory>
</Exec>
<SendEmail>
<From>a</From>
<To>b</To>
<Subject>c</Subject>
<Body>d</Body>
<HeaderFields/>
<Attachments>
<File>e</File>
</Attachments>
<Server>f</Server>
</SendEmail>
<ShowMessage>
<Title>aa</Title>
<Body>bb</Body>
</ShowMessage>
</Actions>
</Task>
</Properties>
</TaskV2>
<ImmediateTaskV2 clsid="{9756B581-76EC-4169-9AFC-0CA8D43ADB5F}"
name="ImdTask"
image="2"
changed="2008-05-27 03:49:21"
uid="{541F1F1E-CAD4-447C-B26F-5D1EAD6965AA}">
<Filters>
<FilterOs hidden="1" not="0" bool="AND" class="NT" version="Vista" type="NE" edition="NE" sp="NE"/>
<FilterOs hidden="1" not="0" bool="OR" class="NT" version="2K8" type="NE" edition="NE" sp="NE"/>
<FilterOs hidden="1" not="0" bool="OR" class="NT" version="WIN7" type="NE" edition="NE" sp="NE"/>
</Filters>
<Properties action="U"
name="ImdTask"
runAs="%LogonDomain%\%LogonUser%"
logonType="InteractiveToken">
<Task version="1.2">
<RegistrationInfo>
<Author>WIN-P3LTV7KC6IO\Administrator</Author>
<Description>Demo ImdTask </Description>
</RegistrationInfo>
<Principals>
<Principal id="Author">
<UserId>%LogonDomain%\%LogonUser</UserId>
<LogonType>InteractiveToken</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<IdleSettings>
<Duration>PT10M</Duration>
<WaitTimeout>PT1H</WaitTimeout>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>false</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions>
<Exec><Command>calc.exe</Command>
</Exec>
</Actions>
</Task>
</Properties>
</ImmediateTaskV2>
</ScheduledTasks>
#>
<# Services.xml
<?xml version="1.0" encoding="utf-8"?>
<NTServices clsid="{2CFB484A-4E96-4b5d-A0B6-093D2F91E6AE}">
<NTService
clsid="{AB6F0B67-341F-4e51-92F9-005FBFBA1A43}"
name="Computer Browser"
image="0"
changed="2007-07-10 22:52:45"
uid="{8A3CC7D5-89F1-44DB-8D41-80F6471E17BF}">
<Properties
startupType="NOCHANGE"
serviceName="Computer Browser"
timeout="30"
accountName="LocalSystem"
interact="1"
firstFailure="NOACTION"
secondFailure="NOACTION"
thirdFailure="RESTART"
resetFailCountDelay="0"
cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3"
restartServiceDelay="900000"/>
</NTService>
</NTServices>
#>
<# Drives.xml
<?xml version="1.0" encoding="utf-8"?>
<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}"
disabled="1">
<Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}"
name="S:"
status="S:"
image="2"
changed="2007-07-06 20:57:37"
uid="{4DA4A7E3-F1D8-4FB1-874F-D2F7D16F7065}">
<Properties action="U"
thisDrive="NOCHANGE"
allDrives="NOCHANGE"
userName="test"
cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3"
path="\\scratch"
label="SCRATCH"
persistent="1"
useLetter="1"
letter="S"/>
</Drive>
</Drives>
#>
<# Groups.xml
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{D4A3F943-1B57-4B98-B5E4-1E9C7A84B292}">
<User clsid="{A7D5F186-71E5-4A24-8B2A-C3BDE98BA2D2}"
name="example.com\IT_Dept"
image="2"
changed="2023-09-23 12:00:00"
uid="{B8C7DA29-6F69-4530-B99E-B9B5B88B215B}">
<Properties action="U"
newName=""
fullName="IT Department"
description="Group for IT department staff"
cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3"
changeLogon="0"
noChange="0"
neverExpires="0"
acctDisabled="0"
userName="example.com\IT_Dept"/>
</User>
</Groups>
#>
<# DataSources.xml
<?xml version="1.0" encoding="utf-8"?>
<DataSources clsid="{380F820F-F21B-41ac-A3CC-24D4F80F067B}" disabled="0">
<DataSource clsid="{5C209626-D820-4d69-8D50-1FACD6214488}" name="LocalContacts"
image="1" bypassErrors="0" userContext="1" removePolicy="1"
desc="This is a local database on the local machine."
changed="2007-07-06 20:33:47" uid="{5AA6C3F8-B6D3-4FE1-8925-FEBE6F15310A}">
<Properties action="R" userDSN="1" dsn="LocalContacts"
driver="Microsoft Access (*.mdb)" description="Local Access Database"
username="test" cpassword="5gn5fUqMaeGJkLEPgl3iH9UfLATVxRAHE8GvAvekwnicLYf2Pynj7ifihvajBRA3">
<Attributes>
<Attribute name="DSN" value="C:\USERS\DEMO.MDB"/>
</Attributes>
</Properties>
</DataSource>
<DataSource clsid="{5C209626-D820-4d69-8D50-1FACD6214488}" name="SystemNodes"
image="2" bypassErrors="0" userContext="1" removePolicy="0"
changed="2007-07-06 20:35:31" uid="{F2174147-A906-4977-AE6F-019C427979D8}">
<Properties action="U" userDSN="0" dsn="SystemNodes"
driver="Microsoft Access (*.mdb)" description="All system nodes."
username="test23" cpassword="j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw">
<Attributes>
<Attribute name="DSN" value="c:\nodelist.mdb"/>
</Attributes>
</Properties>
<Filters>
<FilterRunOnce hidden="1" not="0" bool="AND"
id="{8F7D51B0-F798-4C5F-972B-36FCD0399A33}"/>
</Filters>
</DataSource>
</DataSources>
#>

View File

@ -0,0 +1,74 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-PgPassCredentials {
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Ensure the file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the .pgpass file
$pgpassEntries = Get-Content -Path $FilePath
# Array to store the extracted credentials
$credentialsList = @()
# Loop through each line in the .pgpass file
foreach ($entry in $pgpassEntries) {
# Skip comments and empty lines
if ($entry -match '^\s*#' -or $entry -match '^\s*$') {
continue
}
# Split the line by colon, expecting the format: hostname:port:database:username:password
$fields = $entry -split ':'
if ($fields.Length -eq 5) {
# Create a custom object for each entry
$credential = [PSCustomObject]@{
Hostname = $fields[0]
Port = $fields[1]
Database = $fields[2]
Username = $fields[3]
Password = $fields[4]
}
# Add the credential object to the list
$credentialsList += $credential
}
else {
Write-Warning "Invalid format in entry: $entry"
}
}
# Output the results as a PowerShell object
return $credentialsList
}
# Example usage:
$pgpassCredentials = Get-PgPassCredentials -FilePath "c:\temp\configs\.pgpass"
$pgpassCredentials
<# .pgpass file - used for postgres
# Format: hostname:port:database:username:password
# Local database connection
localhost:5432:mydatabase:myuser:mypassword
# Remote database connection
remote.server.com:5432:anotherdb:anotheruser:anotherpassword
# Default connection for any database on localhost
localhost:*:*:defaultuser:defaultpassword
# Wildcard example: Any database and any user connecting to localhost
localhost:*:*:*:supersecretpassword
#>

View File

@ -0,0 +1,111 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to check if a string is a valid base64-encoded string
function IsBase64String {
param ([string]$string)
if ($string -match '^[a-zA-Z0-9\+/]*={0,2}$' -and ($string.Length % 4 -eq 0)) {
return $true
}
return $false
}
# Function to process the SiteManager.xml file and extract server information
function Get-SiteManagerServerInfo {
param (
[string]$xmlFilePath
)
# Check if the file exists
if (-not (Test-Path $xmlFilePath)) {
Write-Error "File not found: $xmlFilePath"
return
}
# Load the XML file
$xml = [xml](Get-Content $xmlFilePath)
# Iterate through each server entry and extract relevant information
$xml.FileZilla3.Servers.Server | ForEach-Object {
$decodedPassword = "Invalid or not present"
# Access the Pass element's inner text, ensuring it's properly treated as a string
[string]$base64Pass = $_.Pass.InnerText
# Check if the password is a valid base64 string before decoding
if ($base64Pass) {
try {
# Trim any extra whitespace from the base64 string
$cleanPass = $base64Pass.Trim()
$decodedPassword = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($cleanPass))
} catch {
$decodedPassword = "Error decoding password: $_"
}
}
# Output the server details
[pscustomobject]@{
Server = $_.Host
Port = $_.Port
Username = $_.User
Password = $decodedPassword
}
}
}
# Example usage
$xmlFilePath = "c:\temp\configs\SiteManager.xml"
Get-SiteManagerServerInfo -xmlFilePath $xmlFilePath
<# SiteManager.xml
<?xml version="1.0" encoding="UTF-8"?>
<FileZilla3>
<Servers>
<Server>
<Host>ftp.example.com</Host>
<Port>21</Port>
<Protocol>0</Protocol> <!-- 0 for FTP, 1 for SFTP -->
<Type>0</Type> <!-- 0 for normal FTP, 1 for FTP over TLS/SSL -->
<User>username</User>
<Pass encoding="base64">SGVsbG9QYXNzd29yZA==</Pass> <!-- Password encoded in base64 -->
<Logontype>1</Logontype> <!-- 0 for anonymous, 1 for normal -->
<TimezoneOffset>0</TimezoneOffset>
<PasvMode>MODE_DEFAULT</PasvMode> <!-- Default is passive mode -->
<MaximumMultipleConnections>0</MaximumMultipleConnections>
<EncodingType>Auto</EncodingType>
<BypassProxy>0</BypassProxy>
<Name>My FTP Site</Name>
<Comments>Sample FTP site for demonstration</Comments>
<LocalDir/>
<RemoteDir/>
<SyncBrowsing>0</SyncBrowsing>
<DirectoryComparison>0</DirectoryComparison>
</Server>
<Server>
<Host>sftp.example.com</Host>
<Port>22</Port>
<Protocol>1</Protocol> <!-- 1 for SFTP -->
<Type>1</Type> <!-- 1 for explicit FTP over TLS -->
<User>sftpuser</User>
<Pass encoding="base64">SGVsbG9QYXNzd29yZA==</Pass>
<Logontype>1</Logontype>
<TimezoneOffset>0</TimezoneOffset>
<PasvMode>MODE_DEFAULT</PasvMode>
<MaximumMultipleConnections>1</MaximumMultipleConnections>
<EncodingType>Auto</EncodingType>
<BypassProxy>0</BypassProxy>
<Name>My SFTP Site</Name>
<Comments>Sample SFTP site</Comments>
<LocalDir/>
<RemoteDir/>
<SyncBrowsing>0</SyncBrowsing>
<DirectoryComparison>0</DirectoryComparison>
</Server>
</Servers>
</FileZilla3>
#>

View File

@ -0,0 +1,288 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to parse configuration files for credentials
function Get-CredentialsFromConfigFile {
param (
[string]$configFilePath
)
# Load the config file as XML
[xml]$configXml = Get-Content $configFilePath
# Initialize a DataTable to store results
$dtCredentials = New-Object System.Data.DataTable
$null = $dtCredentials.Columns.Add("Name", [string])
$null = $dtCredentials.Columns.Add("Section", [string])
$null = $dtCredentials.Columns.Add("URL", [string])
$null = $dtCredentials.Columns.Add("Server", [string])
$null = $dtCredentials.Columns.Add("Port", [string])
$null = $dtCredentials.Columns.Add("UserName", [string])
$null = $dtCredentials.Columns.Add("Password", [string])
# Helper function to add rows to DataTable
function Add-CredentialsToDataTable {
param (
[string]$name,
[string]$section,
[string]$url,
[string]$server,
[string]$port,
[string]$username,
[string]$password
)
$null = $dtCredentials.Rows.Add($name, $section, $url, $server, $port, $username, $password)
}
# Dictionary to temporarily store related credentials
$credentialPairs = @{}
# Function to store credentials in temporary dictionary
function Add-CredentialPair {
param (
[string]$name,
[string]$section,
[string]$key,
[string]$value
)
if ($credentialPairs[$name]) {
$credentialPairs[$name][$key] = $value
} else {
$credentialPairs[$name] = @{}
$credentialPairs[$name][$key] = $value
$credentialPairs[$name]["Section"] = $section
}
# If both username and password are available, add them to the DataTable
if ($credentialPairs[$name]["UserName"] -and $credentialPairs[$name]["Password"]) {
Add-CredentialsToDataTable -name $name -section $credentialPairs[$name]["Section"] `
-url $credentialPairs[$name]["URL"] -server $credentialPairs[$name]["Server"] `
-port $credentialPairs[$name]["Port"] -username $credentialPairs[$name]["UserName"] `
-password $credentialPairs[$name]["Password"]
# Clear the stored credential after adding it to the table
$credentialPairs.Remove($name)
}
}
# Parse all instances of appSettings for OAuth, WebClient, API, and other credentials
if ($configXml.SelectNodes('//appSettings')) {
foreach ($appSettings in $configXml.SelectNodes('//appSettings')) {
foreach ($setting in $appSettings.add) {
$key = $setting.key
$value = $setting.value
$section = "AppSettings"
# Handle specific cases for OAuth, API, and WebClient settings
switch ($key) {
"OAuthServiceUrl" { Add-CredentialPair -name "OAuth" -section $section -key "URL" -value $value }
"ClientId" { Add-CredentialPair -name "OAuth" -section $section -key "UserName" -value $value }
"ClientSecret" { Add-CredentialPair -name "OAuth" -section $section -key "Password" -value $value }
"ServiceUrl" { Add-CredentialPair -name "WebClient" -section $section -key "URL" -value $value }
"ServiceUserName" { Add-CredentialPair -name "WebClient" -section $section -key "UserName" -value $value }
"ServicePassword" { Add-CredentialPair -name "WebClient" -section $section -key "Password" -value $value }
"ApiEndpoint" { Add-CredentialPair -name "API" -section $section -key "URL" -value $value }
"ApiUserName" { Add-CredentialPair -name "API" -section $section -key "UserName" -value $value }
"ApiPassword" { Add-CredentialPair -name "API" -section $section -key "Password" -value $value }
"ApplicationUsername" { Add-CredentialPair -name "Application" -section $section -key "UserName" -value $value }
"ApplicationPassword" { Add-CredentialPair -name "Application" -section $section -key "Password" -value $value }
}
}
}
}
# Parse custom serviceCredentials section
if ($configXml.configuration.serviceCredentials) {
foreach ($setting in $configXml.configuration.serviceCredentials.add) {
$key = $setting.key
$value = $setting.value
$section = "ServiceCredentials"
# Handle specific cases for custom service credentials
switch ($key) {
"ServiceUrl" { Add-CredentialPair -name "CustomService" -section $section -key "URL" -value $value }
"UserName" { Add-CredentialPair -name "CustomService" -section $section -key "UserName" -value $value }
"Password" { Add-CredentialPair -name "CustomService" -section $section -key "Password" -value $value }
}
}
}
# Parse connectionStrings for server, port, username, and password
if ($configXml.configuration.connectionStrings) {
foreach ($connection in $configXml.configuration.connectionStrings.add) {
$connectionString = $connection.connectionString
$providerName = $connection.providerName
$name = $connection.name
# Initialize variables for potential data
$server = $null
$port = $null
$user = $null
$password = $null
$url = $null
# Parse connection strings
if ($connectionString -match "Host\s*=\s*([^;]+).*?Port\s*=\s*(\d+).*?Username\s*=\s*([^;]+).*?Password\s*=\s*([^;]+)") {
$server = $matches[1]
$port = $matches[2]
$user = $matches[3]
$password = $matches[4]
$url = "Host=$server;Port=$port"
} elseif ($connectionString -match "(Server|Data Source)\s*=\s*([^;,]+)(?:,(\d+))?") {
$server = $matches[2]
if ($matches[3]) { $port = $matches[3] }
$url = "Server=$server"
}
if ($connectionString -match "User\s*Id\s*=\s*([^;]+)") {
$user = $matches[1]
}
if ($connectionString -match "Password\s*=\s*([^;]+)") {
$password = $matches[1]
}
# Add row to the DataTable if username and password exist
if ($user -and $password) {
Add-CredentialsToDataTable -name $name -section "ConnectionStrings ($providerName)" -url $url -server $server -port $port -username $user -password $password
}
}
}
# Parse system.net/mailSettings for SMTP credentials and URLs
if ($configXml.configuration.'system.net'.mailSettings) {
foreach ($smtp in $configXml.configuration.'system.net'.mailSettings.smtp) {
$smtpServer = $smtp.network.host
$smtpPort = $smtp.network.port
$smtpUser = $smtp.network.userName
$smtpPass = $smtp.network.password
$url = "smtp://${smtpServer}:${smtpPort}"
if ($smtpUser -and $smtpPass) {
Add-CredentialsToDataTable -name "SMTP Configuration" -section "SMTP" -url $url -server $smtpServer -port $smtpPort -username $smtpUser -password $smtpPass
}
}
}
# Output the parsed credentials using the DataTable
if ($dtCredentials.Rows.Count -eq 0) {
Write-Host "No credentials found." -ForegroundColor Red
} else {
$dtCredentials | select Name, Section, URL, Server, Port, UserName, Password
}
}
# Example of calling the function with a file path
Get-CredentialsFromConfigFile -configFilePath "c:\temp\configs\app.config"
<# app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- Section handlers for custom service credentials -->
<section name="serviceCredentials" type="System.Configuration.NameValueSectionHandler" />
<sectionGroup name="system.net">
<section name="settings" type="System.Net.Configuration.SettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</sectionGroup>
</configSections>
<!-- Application-specific settings -->
<appSettings>
<add key="ApplicationUsername" value="myAppUser" />
<add key="ApplicationPassword" value="myAppPassword" />
<add key="OAuthServiceUrl" value="https://oauth.example.com/token" />
<add key="ClientId" value="myClientId" />
<add key="ClientSecret" value="myClientSecret" />
<add key="ServiceUrl" value="https://service.example.com/api" />
<add key="ServiceUserName" value="serviceUser" />
<add key="ServicePassword" value="servicePassword" />
<add key="ApiEndpoint" value="https://api.example.com/endpoint" />
<add key="ApiUserName" value="apiUser" />
<add key="ApiPassword" value="apiPassword" />
</appSettings>
<!-- Custom service credentials -->
<serviceCredentials>
<add key="ServiceUrl" value="https://customservice.example.com" />
<add key="UserName" value="customUser" />
<add key="Password" value="customPassword" />
</serviceCredentials>
<!-- Connection strings for various databases -->
<connectionStrings>
<add name="SqlServerConnection"
connectionString="Data Source=localhost;Initial Catalog=myDB;User ID=myUser;Password=myPass;"
providerName="System.Data.SqlClient" />
<add name="SqlServerIntegratedSecurity"
connectionString="Data Source=localhost;Initial Catalog=myDB;Integrated Security=True;"
providerName="System.Data.SqlClient" />
<add name="MySqlConnection"
connectionString="Server=localhost;Database=myDB;User=myUser;Password=myPass;"
providerName="MySql.Data.MySqlClient" />
<add name="PostgreSqlConnection"
connectionString="Host=localhost;Port=5432;Database=myDB;Username=myUser;Password=myPass;"
providerName="Npgsql" />
<add name="OracleConnection"
connectionString="Data Source=MyOracleDB;User Id=oracleUser;Password=oraclePass;"
providerName="Oracle.ManagedDataAccess.Client" />
</connectionStrings>
<!-- Web-specific settings -->
<system.web>
<compilation debug="true" />
<authentication mode="Forms">
<forms loginUrl="login.aspx" timeout="30">
<credentials passwordFormat="Clear">
<user name="user1" password="password1" />
<user name="user2" password="password2" />
</credentials>
</forms>
</authentication>
<customErrors mode="Off" />
</system.web>
<!-- Email (SMTP) configuration -->
<system.net>
<mailSettings>
<smtp from="you@example.com">
<network host="smtp.example.com" port="587"
userName="smtpUser"
password="smtpPassword"
defaultCredentials="false" />
</smtp>
</mailSettings>
</system.net>
<!-- WCF Service configuration -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://example.com/service"
binding="basicHttpBinding"
bindingConfiguration="MyBinding"
contract="IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<userName userName="serviceUser" password="servicePassword" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
#>

View File

@ -0,0 +1,79 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-BootstrapConfig {
param (
[string]$FilePath
)
# Read all lines from the provided file path
$iniContent = Get-Content -Path $FilePath
# Initialize a hash table to store key-value pairs
$fields = @{
Username = $null
Password = $null
Public = $null
Private = $null
Key = $null
Secret = $null
}
# Loop through each line and look for the required fields
foreach ($line in $iniContent) {
if ($line -match 'username\s*=\s*(.*)') {
$fields['Username'] = $matches[1].Trim()
}
if ($line -match 'password\s*=\s*(.*)') {
$fields['Password'] = $matches[1].Trim()
}
if ($line -match 'public\s*=\s*(.*)') {
$fields['Public'] = $matches[1].Trim()
}
if ($line -match 'private\s*=\s*(.*)') {
$fields['Private'] = $matches[1].Trim()
}
if ($line -match 'key\s*=\s*(.*)') {
$fields['Key'] = $matches[1].Trim()
}
if ($line -match 'secret\s*=\s*(.*)') {
$fields['Secret'] = $matches[1].Trim()
}
}
# Convert the hash table into a custom PowerShell object
$configObject = [PSCustomObject]$fields
# Output the custom object
return $configObject
}
# Example call using the example file path
$bootstrapIniPath = "c:\temp\configs\bootstrap.ini"
$config = Get-BootstrapConfig -FilePath $bootstrapIniPath
# Output the result
$config
<# bootstrap.ini
[GeneralSettings]
username=adminUser
password=P@ssw0rd123
timeout=30
loglevel=info
public=public
private=mysecret
secret=mysecret
key=mykey
[DatabaseSettings]
db_name=my_database
db_host=localhost
db_port=3306
[NetworkSettings]
protocol=http
port=8080
#>

View File

@ -0,0 +1,60 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-JenkinsUserCredentials {
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Ensure the file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the XML content as plain text
$xmlText = Get-Content -Path $FilePath -Raw
# Replace XML version 1.1 with 1.0
$xmlText = $xmlText -replace "version='1.1'", "version='1.0'"
# Now parse the XML
[xml]$xmlContent = [xml]$xmlText
# Extract the full name (username)
$fullName = $xmlContent.user.fullName
# Extract the password hash
$passwordHash = $xmlContent.user.properties.'hudson.security.HudsonPrivateSecurityRealm_-Details'.passwordHash
# Create and return the result as a PowerShell object
$result = [PSCustomObject]@{
Username = $fullName
PasswordHash = $passwordHash
}
return $result
}
# Example usage:
$userCredentials = Get-JenkinsUserCredentials -FilePath "c:\temp\configs\config.xml"
$userCredentials
<# config.xml - jenkins - hudson.security.HudsonPrivateSecurityRealm - stored in $JENKINS_HOME/users/username/config.xml
$JENKINS_HOME/users/username/config.xml
<?xml version='1.1' encoding='UTF-8'?>
<user>
<fullName>John Doe</fullName>
<properties>
<hudson.security.HudsonPrivateSecurityRealm_-Details>
<!-- Hashed password using bcrypt -->
<passwordHash>#jbcrypt:$2a$10$D6wVozrLhk.TIq.jBBKZluIh/EqzpjCUJFT/mWUnyAO4EYmxk5.aK</passwordHash>
</hudson.security.HudsonPrivateSecurityRealm_-Details>
</properties>
</user>
#>

View File

@ -0,0 +1,53 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to extract credentials from a given context.xml file
function Get-CredentialsFromContextXml {
param (
[string]$contextXmlPath
)
# Check if the file exists
if (-Not (Test-Path $contextXmlPath)) {
Write-Host "File not found: $contextXmlPath"
return
}
# Load the XML file
[xml]$xml = Get-Content $contextXmlPath
# Extract username and password from the Resource element
$username = $xml.Context.Resource | Where-Object { $_.name -eq 'jdbc/MyDB' } | Select-Object -ExpandProperty username
$password = $xml.Context.Resource | Where-Object { $_.name -eq 'jdbc/MyDB' } | Select-Object -ExpandProperty password
# Create a PowerShell object to hold the extracted information
$credentials = [PSCustomObject]@{
Username = $username
Password = $password
}
# Return the credentials object
return $credentials
}
# Example usage of the function
$exampleFilePath = "c:\temp\configs\context.xml"
$credentials = Get-CredentialsFromContextXml -contextXmlPath $exampleFilePath
# Display the credentials
$credentials
<# context.xml
<Context>
<Resource name="jdbc/MyDB"
auth="Container"
type="javax.sql.DataSource"
maxTotal="100"
maxIdle="30"
maxWaitMillis="10000"
username="dbuser"
password="dbpassword"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/mydb"/>
</Context>
#>

View File

@ -0,0 +1,376 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to extract credentials from the file
function Get-CredentialsFromConfig {
param (
[string]$filePath
)
# Check if the file exists
if (-Not (Test-Path $filePath)) {
Write-Host "File not found: $filePath"
return
}
# Read the content of the file
$fileContent = Get-Content -Path $filePath
# Create an array to hold the results
$credentials = @()
# Initialize variables for the current section and credentials
$currentSection = ""
$currentUsername = ""
$currentPassword = ""
# Loop through each line of the file
foreach ($line in $fileContent) {
# Check if the line indicates a new section (e.g., [DB2], [MySQL])
if ($line -match '^\[.*\]$') {
# If we have collected both a username and password, store the credentials
if ($currentUsername -and $currentPassword) {
$credentials += [PSCustomObject]@{
Section = $currentSection
Username = $currentUsername
Password = $currentPassword
}
}
# Start a new section
$currentSection = $line.Trim('[]')
$currentUsername = ""
$currentPassword = ""
}
# Check if the line contains a User_Name field
if ($line -match '^User_Name=(.*)$') {
$currentUsername = $matches[1].Trim()
}
# Check if the line contains a Password field
if ($line -match '^Password=(.*)$') {
$currentPassword = $matches[1].Trim()
}
}
# If the last section contains credentials, add them to the array
if ($currentUsername -and $currentPassword) {
$credentials += [PSCustomObject]@{
Section = $currentSection
Username = $currentUsername
Password = $currentPassword
}
}
# Return the results
return $credentials
}
# Example call to the function with a sample file path
$filePath = "c:\temp\configs\dbxdrivers.ini"
$credentials = Get-CredentialsFromConfig -filePath $filePath
# Display the results
$credentials | Format-Table -AutoSize
<# dbxdrivers.ini
[Installed Drivers]
DB2=1
Interbase=1
MySQL=1
Oracle=1
Informix=1
MSSQL=1
UIB Interbase6=1
UIB Interbase65=1
UIB Interbase7=1
UIB Interbase71=1
UIB FireBird102=1
UIB FireBird103=1
UIB FireBird15=1
UIB Yaffil=1
[DB2]
GetDriverFunc=getSQLDriverDB2
LibraryName=dbexpdb2.dll
VendorLib=db2cli.dll
Database=DBNAME
User_Name=user
Password=password
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
DB2 TransIsolation=ReadCommited
[Interbase]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpint.dll
VendorLib=gds32.dll
Database=database.gdb
RoleName=RoleName
User_Name=sysdba
Password=masterkey
ServerCharSet=
SQLDialect=1
BlobSize=-1
CommitRetain=False
WaitOnLocks=True
ErrorResourceFile=
LocaleCode=0000
Interbase TransIsolation=ReadCommited
Trim Char=False
[MySQL]
GetDriverFunc=getSQLDriverMYSQL
LibraryName=dbexpmysql.dll
VendorLib=libmysql.dll
HostName=localhost
Database=DBNAME
User_Name=root
Password=
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
[Oracle]
GetDriverFunc=getSQLDriverORACLE
LibraryName=dbexpora.dll
VendorLib=oci.dll
DataBase=Database Name
User_Name=user
Password=password
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
Oracle TransIsolation=ReadCommited
RowsetSize=20
OS Authentication=False
Multiple Transaction=False
Trim Char=False
[Informix]
GetDriverFunc=getSQLDriverINFORMIX
LibraryName=dbexpinf.dll
VendorLib=isqlb09a.dll
HostName=ServerName
DataBase=Database Name
User_Name=user
Password=password
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
Informix TransIsolation=ReadCommited
Trim Char=False
[MSSQL]
GetDriverFunc=getSQLDriverMSSQL
LibraryName=dbexpmss.dll
VendorLib=oledb
HostName=ServerName
DataBase=Database Name
User_Name=user
Password=password
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
MSSQL TransIsolation=ReadCommited
OS Authentication=False
[AutoCommit]
False=0
True=1
[BlockingMode]
False=0
True=1
[WaitOnLocks]
False=1
True=0
[CommitRetain]
False=0
True=1
[OS Authentication]
False=0
True=1
[Multiple Transaction]
False=0
True=1
[Trim Char]
False=0
True=1
[DB2 TransIsolation]
DirtyRead=0
ReadCommited=1
RepeatableRead=2
[Interbase TransIsolation]
ReadCommited=1
RepeatableRead=2
[Oracle TransIsolation]
DirtyRead=0
ReadCommited=1
RepeatableRead=2
[Informix TransIsolation]
DirtyRead=0
ReadCommited=1
RepeatableRead=2
[MSSQL TransIsolation]
DirtyRead=0
ReadCommited=1
RepeatableRead=2
[SQLDialect]
1=0
2=1
3=2
[UIB Interbase6]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBint6.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.ib
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB Interbase65]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBint65.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.ib
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB Interbase7]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBint7.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.ib
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB Interbase71]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBint71.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.ib
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB FireBird102]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBfire102.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.fb
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB FireBird103]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBfire103.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.fb
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB FireBird15]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIBfire15.dll
VendorLib=fbclient.dll
BlobSize=-1
CommitRetain=False
Database=database.fb
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
[UIB Yaffil]
GetDriverFunc=getSQLDriverINTERBASE
LibraryName=dbexpUIByaffil.dll
VendorLib=GDS32.DLL
BlobSize=-1
CommitRetain=False
Database=database.gdb
ErrorResourceFile=
LocaleCode=0000
Password=masterkey
RoleName=RoleName
ServerCharSet=
SQLDialect=3
Interbase TransIsolation=ReadCommited
User_Name=SYSDBA
WaitOnLocks=True
#>

View File

@ -0,0 +1,78 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-RdpCredentials {
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Check if the file exists
if (-not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the RDP file contents
$rdpContent = Get-Content -Path $FilePath
# Initialize variables to store username and password
$username = ""
$encryptedPassword = ""
$decryptedPassword = ""
# Parse the RDP file for username and encrypted password fields
foreach ($line in $rdpContent) {
if ($line -match "^username:s:(.+)$") {
$username = $matches[1]
}
if ($line -match "^password 51:b:(.+)$") {
$encryptedPassword = $matches[1]
}
}
# Attempt to decrypt the password if it exists
if ($encryptedPassword) {
try {
# Convert the encrypted password from Base64 to byte array
$passwordBytes = [Convert]::FromBase64String($encryptedPassword)
# Use DPAPI to decrypt the password
$decryptedPassword = [System.Text.Encoding]::Unicode.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($passwordBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser))
} catch {
Write-Warning "Unable to decrypt password: $_"
$decryptedPassword = "Unable to decrypt"
}
} else {
$encryptedPassword = "No password found"
$decryptedPassword = "No password found"
}
# Create a PowerShell object to return the results
$result = [PSCustomObject]@{
Username = $username
EncryptedPassword = $encryptedPassword
DecryptedPassword = $decryptedPassword
}
return $result
}
# Example usage:
$credentials = Get-RdpCredentials -FilePath "c:\temp\configs\example.rdp"
$credentials
<# example.rdp - decryption needs to be done on the target system using dpapi
screen mode id:i:2
desktopwidth:i:1920
desktopheight:i:1080
session bpp:i:32
winposstr:s:0,3,0,0,800,600
full address:s:yourserver.com
username:s:YourUsername
password 51:b:encrypted_password_value
#>

View File

@ -0,0 +1,50 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-HtpasswdContent {
param (
[string]$FilePath
)
# Check if the file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "File not found at path: $FilePath"
return
}
# Read the file contents
$lines = Get-Content $FilePath
# Initialize an array to store user objects
$users = @()
# Process each line
foreach ($line in $lines) {
# Split each line into username and hashed password
$parts = $line -split ':', 2
if ($parts.Length -eq 2) {
# Create a custom object for each user
$userObj = [pscustomobject]@{
Username = $parts[0]
PasswordHash = $parts[1]
}
# Add the user object to the array
$users += $userObj
}
}
# Output the results
return $users
}
# Example usage
$result = Get-HtpasswdContent -FilePath "c:\temp\configs\.htpasswd"
$result
<# .htpasswd
user1:$apr1$5lRQ1y3v$pmOQf9/fNVE5dTtQDBl9D1
user2:$apr1$Jd9UE91p$J/H8G9HSvj5l8LKQ2qfd3.
admin:$apr1$GZJoqjNF$wl8IjDhZC84z5Bb4wHOv50
#>

View File

@ -0,0 +1,73 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Define the function to extract username and password from a jboss-cli.xml file and return an object
function Get-JbossCredentials {
param (
[string]$FilePath
)
# Check if the file exists
if (-not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return $null
}
# Load the XML file
[xml]$jbossCliXml = Get-Content -Path $FilePath
# Extract the username and password
$username = $jbossCliXml."jboss-cli".authentication.username
$password = $jbossCliXml."jboss-cli".authentication.password
# Return a PowerShell object with the username and password
return [pscustomobject]@{
Username = $username
Password = $password
}
}
# Example usage
$xmlFilePath = "c:\temp\configs\jboss-cli.xml"
$credentials = Get-JbossCredentials -FilePath $xmlFilePath
# Output the returned object (optional for testing)
$credentials
<# jboss-cli.xml
<jboss-cli xmlns="urn:jboss:cli:1.2">
<!-- The default controller host and port -->
<controller>
<host>127.0.0.1</host> <!-- Specify the host, e.g., localhost or a remote address -->
<port>9990</port> <!-- The management port of JBoss/WildFly, default is 9990 -->
</controller>
<!-- The authentication details for the controller -->
<authentication>
<username>admin</username> <!-- Your management user -->
<password>password</password> <!-- Your management user's password -->
</authentication>
<!-- Optionally enable secure connections using SSL -->
<ssl>
<enabled>false</enabled> <!-- Set to true if using SSL/TLS for the connection -->
<keystore-path></keystore-path>
<keystore-password></keystore-password>
<truststore-path></truststore-path>
<truststore-password></truststore-password>
</ssl>
<!-- Custom properties for the CLI session -->
<properties>
<!-- For example, to disable coloring in the CLI output -->
<property name="jboss.cli.color" value="false"/>
</properties>
<!-- Configuration of command history behavior -->
<history>
<enabled>true</enabled> <!-- Whether to enable CLI command history -->
<max-size>500</max-size> <!-- The maximum number of commands to store in history -->
</history>
</jboss-cli>
#>

View File

@ -0,0 +1,115 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-ConfigCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize a hashtable to store extracted values
$configData = @{
Domain = $null
Server = $null
Username = $null
Password = $null
}
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the configuration file
$configFile = Get-Content -Path $FilePath
# Parse the configuration file line by line
foreach ($line in $configFile) {
# Ignore comment lines and empty lines
if ($line -match '^\s*#' -or $line -match '^\s*$') {
continue
}
# Extract the domain (e.g., default_realm or ad_domain or similar)
if ($line -match 'default_realm\s*=\s*(.+)') {
$configData.Domain = $matches[1].Trim()
}
# Extract the server (e.g., kdc or krb5_server or similar)
if ($line -match 'kdc\s*=\s*(.+)') {
$configData.Server = $matches[1].Trim()
}
# Extract the username (e.g., principal or ldap_default_bind_dn or similar)
if ($line -match 'principal\s*=\s*(.+)') {
$configData.Username = $matches[1].Trim()
}
elseif ($line -match 'ldap_default_bind_dn\s*=\s*(.+)') {
$configData.Username = $matches[1].Trim()
}
# Extract the password (e.g., password or ldap_default_authtok or similar)
if ($line -match 'password\s*=\s*(.+)') {
$configData.Password = $matches[1].Trim()
}
elseif ($line -match 'ldap_default_authtok\s*=\s*(.+)') {
$configData.Password = $matches[1].Trim()
}
}
# Output the extracted configuration as a PowerShell object
[PSCustomObject]@{
Domain = $configData.Domain
Server = $configData.Server
Username = $configData.Username
Password = $configData.Password
}
}
# Example usage:
$config = Get-ConfigCredentials -FilePath "c:\temp\configs\krb5.conf"
$config | Format-List
<# krb5.conf - use for kerberos authention on linux systems
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = true
rdns = false
ticket_lifetime = 24h
forwardable = yes
[realms]
EXAMPLE.COM = {
kdc = ad.example.com
admin_server = ad.example.com
default_domain = example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
# Insecure: Exposing credentials in krb5.conf for automated ticket retrieval (NOT recommended)
[login]
krb5_get_init_creds_keytab = false
# Insecure: Plaintext credentials for AD principal
[appdefaults]
kinit = {
principal = admin@EXAMPLE.COM
password = P@ssw0rd123
}
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
}
#>

View File

@ -0,0 +1,374 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to parse configuration files for credentials
function Get-CredentialsFromConfigFile {
param (
[string]$configFilePath
)
# Load the config file as XML
[xml]$configXml = Get-Content $configFilePath
# Initialize a DataTable to store results
$dtCredentials = New-Object System.Data.DataTable
$null = $dtCredentials.Columns.Add("Name", [string])
$null = $dtCredentials.Columns.Add("Section", [string])
$null = $dtCredentials.Columns.Add("URL", [string])
$null = $dtCredentials.Columns.Add("Server", [string])
$null = $dtCredentials.Columns.Add("Port", [string])
$null = $dtCredentials.Columns.Add("UserName", [string])
$null = $dtCredentials.Columns.Add("Password", [string])
# Helper function to add rows to DataTable
function Add-CredentialsToDataTable {
param (
[string]$name,
[string]$section,
[string]$url,
[string]$server,
[string]$port,
[string]$username,
[string]$password
)
$null = $dtCredentials.Rows.Add($name, $section, $url, $server, $port, $username, $password)
}
# Dictionary to temporarily store related credentials
$credentialPairs = @{}
# Function to store credentials in temporary dictionary
function Add-CredentialPair {
param (
[string]$name,
[string]$section,
[string]$key,
[string]$value
)
if ($credentialPairs[$name]) {
$credentialPairs[$name][$key] = $value
} else {
$credentialPairs[$name] = @{}
$credentialPairs[$name][$key] = $value
$credentialPairs[$name]["Section"] = $section
}
# If both username and password are available, add them to the DataTable
if ($credentialPairs[$name]["UserName"] -and $credentialPairs[$name]["Password"]) {
Add-CredentialsToDataTable -name $name -section $credentialPairs[$name]["Section"] `
-url $credentialPairs[$name]["URL"] -server $credentialPairs[$name]["Server"] `
-port $credentialPairs[$name]["Port"] -username $credentialPairs[$name]["UserName"] `
-password $credentialPairs[$name]["Password"]
# Clear the stored credential after adding it to the table
$credentialPairs.Remove($name)
}
}
# Parse all instances of appSettings for OAuth, WebClient, API, and other credentials
if ($configXml.SelectNodes('//appSettings')) {
foreach ($appSettings in $configXml.SelectNodes('//appSettings')) {
foreach ($setting in $appSettings.add) {
$key = $setting.key
$value = $setting.value
$section = "AppSettings"
# Handle specific cases for OAuth, API, and WebClient settings
switch ($key) {
"OAuthServiceUrl" { Add-CredentialPair -name "OAuth" -section $section -key "URL" -value $value }
"ClientId" { Add-CredentialPair -name "OAuth" -section $section -key "UserName" -value $value }
"ClientSecret" { Add-CredentialPair -name "OAuth" -section $section -key "Password" -value $value }
"ServiceUrl" { Add-CredentialPair -name "WebClient" -section $section -key "URL" -value $value }
"ServiceUserName" { Add-CredentialPair -name "WebClient" -section $section -key "UserName" -value $value }
"ServicePassword" { Add-CredentialPair -name "WebClient" -section $section -key "Password" -value $value }
"ApiEndpoint" { Add-CredentialPair -name "API" -section $section -key "URL" -value $value }
"ApiUserName" { Add-CredentialPair -name "API" -section $section -key "UserName" -value $value }
"ApiPassword" { Add-CredentialPair -name "API" -section $section -key "Password" -value $value }
"ApplicationUsername" { Add-CredentialPair -name "Application" -section $section -key "UserName" -value $value }
"ApplicationPassword" { Add-CredentialPair -name "Application" -section $section -key "Password" -value $value }
}
}
}
}
# Parse custom serviceCredentials section
if ($configXml.configuration.serviceCredentials) {
foreach ($setting in $configXml.configuration.serviceCredentials.add) {
$key = $setting.key
$value = $setting.value
$section = "ServiceCredentials"
# Handle specific cases for custom service credentials
switch ($key) {
"ServiceUrl" { Add-CredentialPair -name "CustomService" -section $section -key "URL" -value $value }
"UserName" { Add-CredentialPair -name "CustomService" -section $section -key "UserName" -value $value }
"Password" { Add-CredentialPair -name "CustomService" -section $section -key "Password" -value $value }
}
}
}
# Parse connectionStrings for server, port, username, and password
if ($configXml.configuration.connectionStrings) {
foreach ($connection in $configXml.configuration.connectionStrings.add) {
$connectionString = $connection.connectionString
$providerName = $connection.providerName
$name = $connection.name
# Initialize variables for potential data
$server = $null
$port = $null
$user = $null
$password = $null
$url = $null
# Parse connection strings
if ($connectionString -match "Host\s*=\s*([^;]+).*?Port\s*=\s*(\d+).*?Username\s*=\s*([^;]+).*?Password\s*=\s*([^;]+)") {
$server = $matches[1]
$port = $matches[2]
$user = $matches[3]
$password = $matches[4]
$url = "Host=$server;Port=$port"
} elseif ($connectionString -match "(Server|Data Source)\s*=\s*([^;,]+)(?:,(\d+))?") {
$server = $matches[2]
if ($matches[3]) { $port = $matches[3] }
$url = "Server=$server"
}
if ($connectionString -match "User\s*Id\s*=\s*([^;]+)") {
$user = $matches[1]
}
if ($connectionString -match "Password\s*=\s*([^;]+)") {
$password = $matches[1]
}
# Add row to the DataTable if username and password exist
if ($user -and $password) {
Add-CredentialsToDataTable -name $name -section "ConnectionStrings ($providerName)" -url $url -server $server -port $port -username $user -password $password
}
}
}
# Parse system.net/mailSettings for SMTP credentials and URLs
if ($configXml.configuration.'system.net'.mailSettings) {
foreach ($smtp in $configXml.configuration.'system.net'.mailSettings.smtp) {
$smtpServer = $smtp.network.host
$smtpPort = $smtp.network.port
$smtpUser = $smtp.network.userName
$smtpPass = $smtp.network.password
$url = "smtp://${smtpServer}:${smtpPort}"
if ($smtpUser -and $smtpPass) {
Add-CredentialsToDataTable -name "SMTP Configuration" -section "SMTP" -url $url -server $smtpServer -port $smtpPort -username $smtpUser -password $smtpPass
}
}
}
# Output the parsed credentials using the DataTable
if ($dtCredentials.Rows.Count -eq 0) {
Write-Host "No credentials found." -ForegroundColor Red
} else {
$dtCredentials | select Name, Section, URL, Server, Port, UserName, Password
}
}
# Example of calling the function with a file path
Get-CredentialsFromConfigFile -configFilePath "c:\temp\configs\machine.config"
<# machine.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- Section handlers for configuration settings -->
<sectionGroup name="system.net">
<section name="settings" type="System.Net.Configuration.SettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</sectionGroup>
</configSections>
<!-- App settings for all .NET applications -->
<appSettings>
<!-- Example of username and password in appSettings -->
<add key="ApplicationUsername" value="myAppUser" />
<add key="ApplicationPassword" value="myAppPassword" />
</appSettings>
<!-- OAuth/Token-Based Service Endpoints -->
<appSettings>
<add key="OAuthServiceUrl" value="https://oauth.example.com/token" />
<add key="ClientId" value="myClientId" />
<add key="ClientSecret" value="myClientSecret" />
</appSettings>
<!-- WebClient or HttpClient Credentials -->
<appSettings>
<add key="ServiceUrl" value="https://service.example.com/api" />
<add key="ServiceUserName" value="serviceUser" />
<add key="ServicePassword" value="servicePassword" />
</appSettings>
<!-- AppSettings Section -->
<appSettings>
<add key="ApiEndpoint" value="https://api.example.com/endpoint" />
<add key="ApiUserName" value="apiUser" />
<add key="ApiPassword" value="apiPassword" />
</appSettings>
<!-- Custom Sections for Service Credentials -->
<configSections>
<section name="serviceCredentials" type="System.Configuration.NameValueSectionHandler" />
</configSections>
<serviceCredentials>
<add key="ServiceUrl" value="https://customservice.example.com" />
<add key="UserName" value="customUser" />
<add key="Password" value="customPassword" />
</serviceCredentials>
<!-- Connection string settings -->
<connectionStrings>
<!-- SQL Server (Standard Authentication) -->
<add name="SqlServerConnection"
connectionString="Data Source=localhost;Initial Catalog=myDB;User ID=myUser;Password=myPass;"
providerName="System.Data.SqlClient" />
<!-- SQL Server (Windows Authentication) -->
<add name="SqlServerIntegratedSecurity"
connectionString="Data Source=localhost;Initial Catalog=myDB;Integrated Security=True;"
providerName="System.Data.SqlClient" />
<!-- SQL Server (Encrypted Connection) -->
<add name="SqlServerEncryptedConnection"
connectionString="Data Source=localhost;Initial Catalog=myDB;User ID=myUser;Password=myPass;Encrypt=True;TrustServerCertificate=False;"
providerName="System.Data.SqlClient" />
<!-- MySQL (Standard Connection) -->
<add name="MySqlConnection"
connectionString="Server=localhost;Database=myDB;User=myUser;Password=myPass;"
providerName="MySql.Data.MySqlClient" />
<!-- MySQL (SSL/Encrypted Connection) -->
<add name="MySqlConnectionWithSSL"
connectionString="Server=localhost;Database=myDB;User=myUser;Password=myPass;SslMode=Required;"
providerName="MySql.Data.MySqlClient" />
<!-- PostgreSQL (Standard Connection) -->
<add name="PostgreSqlConnection"
connectionString="Host=localhost;Port=5432;Database=myDB;Username=myUser;Password=myPass;"
providerName="Npgsql" />
<!-- Oracle (Standard Connection) -->
<add name="OracleConnection"
connectionString="Data Source=MyOracleDB;User Id=oracleUser;Password=oraclePass;"
providerName="System.Data.OracleClient" />
<!-- Oracle (TNS Connection) -->
<add name="OracleTNSConnection"
connectionString="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=myHost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=myService)));User Id=oracleUser;Password=oraclePass;"
providerName="Oracle.ManagedDataAccess.Client" />
<!-- SQLite (No Authentication Required) -->
<add name="SQLiteConnection"
connectionString="Data Source=myDatabase.db;"
providerName="System.Data.SQLite" />
<!-- Microsoft Access (OLEDB with username and password) -->
<add name="AccessConnection"
connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myAccessFile.accdb;User Id=admin;Password=myPass;"
providerName="System.Data.OleDb" />
<!-- Azure SQL (Standard SQL Authentication) -->
<add name="AzureSqlConnection"
connectionString="Server=tcp:myserver.database.windows.net,1433;Initial Catalog=myDB;Persist Security Info=False;User ID=myUser;Password=myPass;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<!-- Compilation settings for applications -->
<system.web>
<compilation debug="false" />
<authentication mode="Forms">
<!-- Forms authentication with username and password -->
<forms loginUrl="login.aspx" timeout="30">
<credentials passwordFormat="Clear">
<user name="user1" password="password1" />
<user name="user2" password="password2" />
</credentials>
</forms>
</authentication>
<customErrors mode="Off" />
</system.web>
<!-- Machine-wide database settings -->
<system.data>
<DbProviderFactories>
<add name="Microsoft SQL Server Compact Data Provider"
invariant="System.Data.SqlServerCe.4.0"
description=".NET Framework Data Provider for Microsoft SQL Server Compact"
type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
</DbProviderFactories>
</system.data>
<!-- Credentials for SMTP (system.net) -->
<system.net>
<mailSettings>
<smtp from="you@example.com">
<network host="smtp.example.com" port="587"
userName="smtpUser"
password="smtpPassword"
defaultCredentials="false" />
</smtp>
</mailSettings>
</system.net>
<!-- Global assembly cache settings -->
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<!-- Logging and tracing settings -->
<system.diagnostics>
<sources>
<source name="System.Net" switchValue="Verbose">
<listeners>
<add name="consoleListener" type="System.Diagnostics.ConsoleTraceListener" />
</listeners>
</source>
</sources>
</system.diagnostics>
<!-- WCF (Windows Communication Foundation) Service Bindings -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://example.com/service"
binding="basicHttpBinding"
bindingConfiguration="MyBinding"
contract="IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<userName userName="serviceUser" password="servicePassword" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
#>

View File

@ -0,0 +1,89 @@

# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-MySQLCredentials {
param (
[string]$FilePath
)
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return $null
}
# Read the file content
$fileContent = Get-Content -Path $FilePath
# Initialize variables to store username and password
$username = $null
$password = $null
# Parse the file content
foreach ($line in $fileContent) {
if ($line -match '^\s*user\s*=\s*(.+)$') {
$username = $matches[1].Trim()
}
elseif ($line -match '^\s*password\s*=\s*(.+)$') {
$password = $matches[1].Trim()
}
}
# Check if both username and password are found
if ($username -and $password) {
# Create a custom PowerShell object to return the credentials
$credentials = [PSCustomObject]@{
Username = $username
Password = $password
}
return $credentials
} else {
Write-Warning "Username or password not found in the file."
return $null
}
}
# Example usage:
$credentials = Get-MySQLCredentials -FilePath "c:\temp\configs\my.cnf"
$credentials
<# my.cnf
[client]
# Client configuration options
user=yourusername
password=yourpassword
port=3306
socket=/var/run/mysqld/mysqld.sock
[mysqld]
# MySQL server configuration
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
port=3306
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
log-error=/var/log/mysql/error.log
bind-address=127.0.0.1
max_connections=100
skip-external-locking
# Buffer pool size for InnoDB
innodb_buffer_pool_size=256M
# Other MySQL server settings
max_allowed_packet=16M
query_cache_limit=1M
query_cache_size=16M
log_bin=/var/log/mysql/mysql-bin.log
[mysql]
# Client-specific settings for the MySQL command-line tool
user=yourusername
password=yourpassword
no-auto-rehash
#>

View File

@ -0,0 +1,86 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-PhpIniCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize a hashtable to store extracted values
$configData = @{
Username = $null
Password = $null
}
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the configuration file
$configFile = Get-Content -Path $FilePath
# Parse the configuration file line by line
foreach ($line in $configFile) {
# Ignore comment lines and empty lines
if ($line -match '^\s*;' -or $line -match '^\s*$') {
continue
}
# Extract the username (e.g., mysql.default_user)
if ($line -match '^\s*mysql\.default_user\s*=\s*"(.+)"') {
$configData.Username = $matches[1].Trim()
}
# Extract the password (e.g., mysql.default_password)
if ($line -match '^\s*mysql\.default_password\s*=\s*"(.+)"') {
$configData.Password = $matches[1].Trim()
}
}
# Output the extracted configuration as a PowerShell object
[PSCustomObject]@{
Username = $configData.Username
Password = $configData.Password
}
}
# Example usage:
$credentials = Get-PhpIniCredentials -FilePath "c:\temp\configs\php.ini"
$credentials | Format-List
<# php.ini - storing mysql credentials
[PHP]
; Basic PHP settings
; Maximum size of POST data allowed
post_max_size = 8M
; Maximum allowed size for uploaded files
upload_max_filesize = 2M
; INSECURE: Storing database credentials in php.ini (not recommended)
; This exposes credentials to anyone with access to php.ini or via phpinfo() if not secured.
mysql.default_user = "dbuser"
mysql.default_password = "P@ssw0rd123"
mysql.default_host = "localhost"
mysql.default_database = "example_db"
; Log errors to a file
log_errors = On
error_log = /var/log/php_errors.log
; Ensure that this option is Off to avoid disclosing sensitive configuration details
expose_php = Off
; Ensure that phpinfo() is secured or disabled to prevent exposure of configuration data
disable_functions = phpinfo
#>

View File

@ -0,0 +1,59 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-PureFtpCredentials {
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Check if the file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "The file at path $FilePath does not exist."
return
}
# Initialize an array to store user credentials
$credentials = @()
# Read the file line by line
Get-Content $FilePath | ForEach-Object {
# Skip empty lines
if ($_ -match '^\s*$') { return }
# Split the line into components using ':' as delimiter
$fields = $_ -split ':'
# Check if we have at least the username and password fields
if ($fields.Length -ge 2) {
$username = $fields[0]
$passwordHash = $fields[1]
# Create a custom object for each user
$credentialObject = [PSCustomObject]@{
Username = $username
PasswordHash = $passwordHash
}
# Add the object to the credentials array
$credentials += $credentialObject
} else {
Write-Error "The line '$_' does not contain enough fields."
}
}
# Output the results as a PowerShell object array
return $credentials
}
$ftpCredentials = Get-PureFtpCredentials -FilePath "c:\temp\configs\pureftpd.passwd"
$ftpCredentials | Format-Table
<# pureftpd.passwd - used by pureftpd, passwords stored as MD5 or SHA-1 hash
username:$1$X9p2ER8W$M7P5CxX5CHPxuAiB5BBJq/:1001:1001::/home/ftp/username:/bin/false::
user2:$1$XYz3ERzW$G9P7CxF6CPxxuAiB6BBJq/:1002:1002::/home/ftp/user2:/bin/false::
#>

View File

@ -0,0 +1,135 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Putty.reg does not store passwords, but can point to private keys
function Parse-PuttyRegFile {
param (
[string]$filePath
)
# Check if the file exists
if (-not (Test-Path $filePath)) {
Write-Host "File not found: $filePath"
return
}
# Read the contents of the .reg file
$regContent = Get-Content -Path $filePath
# Create a list to store extracted session details
$sessionDetails = @()
# Variables to hold extracted data for each session
$currentSession = ""
$hostName = ""
$portNumber = ""
$userName = ""
$privateKeyPath = ""
# Iterate through the lines of the file
foreach ($line in $regContent) {
# Detect session headers (e.g., "[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\My%20SSH%20Session]")
if ($line -match '^\[HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions\\(.+?)\]') {
# If we're processing a new session, save the previous one
if ($currentSession -ne "") {
$sessionDetails += [pscustomobject]@{
Session = $currentSession
HostName = $hostName
Port = [int]$portNumber
UserName = $userName
PrivateKeyPath = $privateKeyPath
}
}
# Reset variables for the new session
$currentSession = $matches[1]
$hostName = ""
$portNumber = ""
$userName = ""
$privateKeyPath = ""
}
# Extract HostName
if ($line -match '"HostName"="(.+?)"') {
$hostName = $matches[1]
}
# Extract PortNumber (convert hex to decimal)
if ($line -match '"PortNumber"=dword:(\w{8})') {
$portNumber = [convert]::ToInt32($matches[1], 16)
}
# Extract UserName
if ($line -match '"UserName"="(.+?)"') {
$userName = $matches[1]
}
# Extract PrivateKeyFile (path to the private key)
if ($line -match '"PublicKeyFile"="(.+?)"') {
$privateKeyPath = $matches[1]
}
}
# After the loop, add the last session if it exists
if ($currentSession -ne "") {
$sessionDetails += [pscustomobject]@{
Session = $currentSession
HostName = $hostName
Port = [int]$portNumber
UserName = $userName
PrivateKeyPath = $privateKeyPath
}
}
# Return the session details
return $sessionDetails
}
# Example usage:
$puttySessions = Parse-PuttyRegFile -filePath "c:\temp\configs\putty.reg"
# Display the results
$puttySessions | Format-Table -AutoSize
<# putty.reg
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY]
"TermWidth"=dword:00000050
"TermHeight"=dword:00000018
"WinTitle"="PuTTY"
[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\Default%20Settings]
"HostName"=""
"PortNumber"=dword:00000016
"Protocol"="ssh"
"TerminalType"="xterm"
"Font"="Courier New"
"FontHeight"=dword:0000000a
"WinHeight"=dword:00000018
"WinWidth"=dword:00000050
"ConnectionSharing"=dword:00000001
[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\My%20SSH%20Session]
"HostName"="192.168.1.100"
"PortNumber"=dword:00000016
"Protocol"="ssh"
"TerminalType"="xterm"
"Font"="Courier New"
"FontHeight"=dword:0000000a
"WinHeight"=dword:00000018
"WinWidth"=dword:00000050
"Compression"=dword:00000001
"ConnectionSharing"=dword:00000001
"PublicKeyFile"="C:\\Users\\YourUsername\\.ssh\\id_rsa.ppk"
"LogFileName"="C:\\putty_logs\\my_session.log"
"LogType"=dword:00000001
"LogFileClash"=dword:00000001
"LogFlush"=dword:00000001
"LogOmitPasswords"=dword:00000001
"LogOmitData"=dword:00000000
"UserName"="myusername" ; Username stored here
#>

View File

@ -0,0 +1,179 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Parse-UserPasswordFromXML {
param (
[string]$filePath
)
# Load the XML file
[xml]$xmlContent = Get-Content -Path $filePath
# Define an array to store the user credentials
$credentials = @()
# Parse basicRegistry user credentials
$xmlContent.server.basicRegistry.user | ForEach-Object {
$credentials += [pscustomobject]@{
User = $_.name
Password = $_.password
Source = 'basicRegistry'
}
}
# Parse variable-based credentials (DB_USER and DB_PASS)
$dbUser = $xmlContent.server.variable | Where-Object { $_.name -eq "DB_USER" }
$dbPass = $xmlContent.server.variable | Where-Object { $_.name -eq "DB_PASS" }
if ($dbUser -and $dbPass) {
$credentials += [pscustomobject]@{
User = $dbUser.value
Password = $dbPass.value
Source = 'variable'
}
}
# Parse containerAuthData credentials
$xmlContent.server.dataSource.containerAuthData | ForEach-Object {
$credentials += [pscustomobject]@{
User = $_.user
Password = $_.password
Source = 'containerAuthData'
}
}
# Parse authData credentials
$xmlContent.server.authData | ForEach-Object {
$credentials += [pscustomobject]@{
User = $_.user
Password = $_.password
Source = 'authData'
}
}
# Return the collected credentials as an array of objects
return $credentials
}
# Example usage:
$parsedCredentials = Parse-UserPasswordFromXML -filePath "c:\temp\configs\server.xml"
# Display the results
$parsedCredentials | Format-Table -AutoSize
<# server.xml
<!--
Copyright (c) 2017,2023 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
-->
<server>
<include location="../fatTestPorts.xml" />
<featureManager>
<feature>componenttest-1.0</feature>
<feature>restConnector-2.0</feature>
<feature>jdbc-4.2</feature>
<feature>mpOpenApi-1.0</feature>
</featureManager>
<variable name="onError" value="FAIL"/>
<keyStore id="defaultKeyStore" password="Liberty"/>
<basicRegistry>
<user name="adminuser" password="adminpwd" />
<user name="reader" password="readerpwd" />
<user name="user" password="userpwd" />
</basicRegistry>
<administrator-role>
<user>adminuser</user>
</administrator-role>
<reader-role>
<user>reader</user>
</reader-role>
<library id="Derby">
<file name="${shared.resource.dir}/derby/derby.jar"/>
</library>
<variable name="DB_USER" value="dbuser"/>
<variable name="DB_PASS" value="dbpass"/>
<dataSource id="DataSourceWithoutJDBCDriver" jndiName="jdbc/withoutJDBCDriver" connectionSharing="MatchCurrentState" transactional="false">
<containerAuthData id="dbuser-auth" user="dbuser" password="{xor}Oz0vPiws"/>
<properties.derby.embedded databaseName="memory:withoutJDBCDriver"/>
</dataSource>
<dataSource id="DefaultDataSource" isolationLevel="TRANSACTION_READ_COMMITTED">
<jdbcDriver libraryRef="Derby"/>
<!-- user/password settings defined in bootstrap.properties -->
<properties.derby.embedded databaseName="memory:defaultdb" createDatabase="create"
user="${DB_USER}" password="${DB_PASS}"/>
</dataSource>
<dataSource id="jdbc/nonexistentdb" jndiName="${id}">
<connectionManager id="NestedConPool" agedTimeout="1h2m3s" connectionTimeout="0s" maxIdleTime="40m" reapTime="2m30s"/>
<jdbcDriver libraryRef="Derby"/>
<properties.derby.embedded databaseName="memory:doesNotExist"/>
</dataSource>
<transaction enableHADBPeerLocking="false">
<dataSource transactional="false" containerAuthDataRef="auth1">
<connectionManager maxPoolSize="5" connectionTimeout="0s"/>
<jdbcDriver libraryRef="Derby"/>
<properties.derby.embedded databaseName="memory:recoverydb" createDatabase="create"/>
</dataSource>
</transaction>
<!-- ejbLite and batch features are intentionally disabled -->
<databaseStore id="unavailableDBStore">
<dataSource id="unavailableDS">
<jdbcDriver libraryRef="Derby"/>
<properties.derby.embedded databaseName="memory:unavailabledb"/>
</dataSource>
</databaseStore>
<!-- mongo feature intentionally disabled, so it doesn't matter that we are using an incorrect library -->
<mongo id="mongo" libraryRef="DerbyLib"/>
<mongoDB id="MongoDBNotEnabled" jndiName="mongo/db" mongoRef="mongo" databaseName="db-test" />
<authData id="auth1" user="dbuser" password="dbpass"/>
<authData id="auth2" user="dbuser" password="wrong_password"/>
<dataSource jndiName="jdbc/defaultauth" containerAuthDataRef="auth1"> <!-- id omitted for testing -->
<connectionManager enableSharingForDirectLookups="false"/>
<jdbcDriver id="NestedDerbyDriver" libraryRef="Derby"
javax.sql.DataSource="org.apache.derby.jdbc.EmbeddedDataSource"
javax.sql.ConnectionPoolDataSource="org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource"
javax.sql.XADataSource="org.apache.derby.jdbc.EmbeddedXADataSource"/>
<onConnect>SET CURRENT SCHEMA = APP</onConnect>
<onConnect>SET CURRENT SQLID = APP</onConnect>
<properties.derby.embedded databaseName="memory:defaultdb" createDatabase="create"/>
</dataSource>
<dataSource id="WrongDefaultAuth" jndiName="jdbc/wrongdefaultauth"
connectionManagerRef="pool1" containerAuthDataRef="auth2" commitOrRollbackOnCleanup="rollback"
invalidProperty="The property's value." jdbcDriverRef="DerbyDriver" queryTimeout="2m10s"
recoveryAuthDataRef="auth2" statementCacheSize="15" validationTimeout="20s">
<properties databaseName="memory:defaultdb" createDatabase="create"/>
</dataSource>
<connectionManager id="pool1" maxPoolSize="10" purgePolicy="ValidateAllConnections"/>
<jdbcDriver id="DerbyDriver" libraryRef="Derby"/>
<javaPermission codebase="${shared.resource.dir}/derby/derby.jar" className="java.security.AllPermission"/>
</server>
#>

View File

@ -0,0 +1,105 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-IniCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize an array to store the credentials
$credentials = @()
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the INI file content
$iniFile = Get-Content -Path $FilePath
# Initialize variables to track current section and credentials
$currentSection = ""
$username = $null
$password = $null
# Parse the INI file line by line
foreach ($line in $iniFile) {
# Ignore comment lines and empty lines
if ($line -match '^\s*;' -or $line -match '^\s*$') {
continue
}
# Detect section headers (e.g., [DatabaseSettings])
if ($line -match '^\s*\[(.+)\]\s*$') {
# If we have collected username and password, store them before moving to the next section
if ($username -and $password) {
$credentials += [PSCustomObject]@{
Section = $currentSection
Username = $username
Password = $password
}
}
# Reset username and password for the new section
$username = $null
$password = $null
# Update current section
$currentSection = $matches[1].Trim()
continue
}
# Match username and password in the lines
if ($line -match '^\s*username\s*=\s*(.+)$') {
$username = $matches[1].Trim()
} elseif ($line -match '^\s*password\s*=\s*(.+)$') {
$password = $matches[1].Trim()
} elseif ($line -match '^\s*user\s*=\s*(.+)$') {
$username = $matches[1].Trim()
} elseif ($line -match '^\s*pass\s*=\s*(.+)$') {
$password = $matches[1].Trim()
}
}
# Capture any remaining username/password pair after the last section
if ($username -and $password) {
$credentials += [PSCustomObject]@{
Section = $currentSection
Username = $username
Password = $password
}
}
# Output the credentials as PowerShell objects
return $credentials
}
# Example usage:
$parsedCredentials = Get-IniCredentials -FilePath "c:\temp\configs\setting.ini"
$parsedCredentials | Format-Table -AutoSize
<# setting.ini
[GeneralSettings]
app_name = MyApp
version = 1.0.0
theme = dark
[DatabaseSettings]
host = localhost
port = 3306
username = dbuser
password = dbpass
[CustomSettings]
user = myuser
pass = mypass
[Logging]
log_level = DEBUG
log_file = /var/log/myapp.log
#>

View File

@ -0,0 +1,63 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-ShadowFileCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize an array to store extracted user data
$credentials = @()
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the shadow file
$shadowFile = Get-Content -Path $FilePath
# Parse each line in the shadow file
foreach ($line in $shadowFile) {
# Ignore empty lines or comments (if any)
if ($line -match '^\s*$' -or $line -match '^\s*#') {
continue
}
# Split the line into fields using colon as a delimiter
$fields = $line -split ':'
# Extract username and password hash
$username = $fields[0]
$passwordHash = $fields[1]
# Create an object to store the extracted information
$userObject = [PSCustomObject]@{
Username = $username
PasswordHash = $passwordHash
}
# Add the object to the array
$credentials += $userObject
}
# Output the array of credentials
return $credentials
}
# Example usage:
$shadowData = Get-ShadowFileCredentials -FilePath "c:\temp\configs\shadow"
$shadowData | Format-Table -AutoSize
<# shadow - linux password file
root:$6$examplehash$E5iNRLtC5/j/kCkRhYlOro.Y9PzE0Gv8jlsfLZUNwlEm7HMBZSO9.mUvefOrKT6BjKSO4obQ.EtCZKhQgmgwV0:19000:0:99999:7:::
user1:$6$examplehash$OwhxlyS5hoxfFE4tmtyOR8Hw1k8PLqokP9FYxYP8QMG3wO0u.0Xvd4g/0Udr6BQZilJk4k7XwlxJ6p0RJ2IL5/:19000:0:99999:7:::
nobody:*:19000:0:99999:7:::
daemon:*:19000:0:99999:7:::
#>

View File

@ -0,0 +1,105 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-SmbConfCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize a hashtable to store extracted values
$configData = @{
Username = $null
Password = $null
}
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the configuration file
$configFile = Get-Content -Path $FilePath
# Parse the configuration file line by line
foreach ($line in $configFile) {
# Ignore comment lines and empty lines
if ($line -match '^\s*#' -or $line -match '^\s*$') {
continue
}
# Extract the username
if ($line -match '^\s*username\s*=\s*(.+)') {
$configData.Username = $matches[1].Trim()
}
# Extract the password
if ($line -match '^\s*password\s*=\s*(.+)') {
$configData.Password = $matches[1].Trim()
}
}
# Output the extracted configuration as a PowerShell object
[PSCustomObject]@{
Username = $configData.Username
Password = $configData.Password
}
}
# Example usage:
$credentials = Get-SmbConfCredentials -FilePath "c:\temp\configs\smb.conf"
$credentials | Format-List
<# smb.conf
[global]
# General server settings
workgroup = EXAMPLE
realm = EXAMPLE.COM
server string = Samba Server Version %v
security = ads
encrypt passwords = yes
kerberos method = secrets and keytab
log file = /var/log/samba/log.%m
max log size = 50
# Domain and authentication settings
idmap config * : backend = tdb
idmap config EXAMPLE : backend = rid
idmap config EXAMPLE : range = 10000-20000
template shell = /bin/bash
winbind use default domain = yes
winbind offline logon = yes
winbind enum users = yes
winbind enum groups = yes
# INSECURE: Credentials for binding to Active Directory (avoid plaintext credentials)
# This exposes the AD admin account and password directly in the smb.conf file
username = ad-admin
password = P@ssw0rd123
# Kerberos keytab file location (more secure than plaintext credentials)
dedicated keytab file = /etc/krb5.keytab
kerberos method = secrets and keytab
[homes]
comment = Home Directories
browseable = no
writable = yes
[printers]
comment = All Printers
path = /var/spool/samba
printable = yes
guest ok = no
writable = no
browseable = no
[shared]
path = /srv/samba/shared
browseable = yes
read only = no
valid users = @staff
#>

View File

@ -0,0 +1,133 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-ConfigCredentials {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Initialize a hashtable to store extracted values
$configData = @{
Domain = $null
Server = $null
Username = $null
Password = $null
}
# Check if the file exists
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the configuration file
$configFile = Get-Content -Path $FilePath
# Parse the configuration file line by line
foreach ($line in $configFile) {
# Ignore comment lines and empty lines
if ($line -match '^\s*#' -or $line -match '^\s*$') {
continue
}
# Extract the domain (e.g., ad_domain or similar)
if ($line -match 'ad_domain\s*=\s*(.+)') {
$configData.Domain = $matches[1].Trim()
}
# Extract the server (e.g., krb5_server or similar)
if ($line -match 'krb5_server\s*=\s*(.+)') {
$configData.Server = $matches[1].Trim()
}
# Extract the username (e.g., ldap_default_bind_dn or similar)
if ($line -match 'ldap_default_bind_dn\s*=\s*(.+)') {
$configData.Username = $matches[1].Trim()
}
# Extract the password (e.g., ldap_default_authtok or similar)
if ($line -match 'ldap_default_authtok\s*=\s*(.+)') {
$configData.Password = $matches[1].Trim()
}
}
# Output the extracted configuration as a PowerShell object
[PSCustomObject]@{
Domain = $configData.Domain
Server = $configData.Server
Username = $configData.Username
Password = $configData.Password
}
}
# Example usage:
$config = Get-ConfigCredentials -FilePath "c:\temp\configs\sssd.conf"
$config | Format-List
<# sssd.conf - used to support kerberos authentication in Linux
[sssd]
config_file_version = 2
services = nss, pam, ssh, sudo
domains = example.com
[nss]
filter_groups = root
filter_users = root
[pam]
offline_credentials_expiration = 2
offline_failed_login_attempts = 3
offline_failed_login_delay = 5
[domain/example.com]
# Basic configuration for connecting to Active Directory
id_provider = ad
auth_provider = ad
access_provider = ad
# Enable Kerberos for authentication
krb5_realm = EXAMPLE.COM
krb5_server = ad.example.com
krb5_kpasswd = ad.example.com
# Active Directory server information
ad_domain = example.com
ad_server = ad.example.com
ad_hostname = linuxclient.example.com
# INSECURE PRACTICE: Hardcoding AD username and password in sssd.conf
# These values will expose the username and password in plaintext
ldap_default_bind_dn = cn=admin,cn=users,dc=example,dc=com
ldap_default_authtok = P@ssw0rd123
# Using the above configuration exposes credentials to anyone who can read this file
# User and group filtering (optional)
ldap_id_mapping = true
# Performance optimizations
cache_credentials = true
enumerate = false
use_fully_qualified_names = false
# Access Control (Optional: limit login to users in AD group 'LinuxAdmins')
access_provider = simple
simple_allow_groups = LinuxAdmins
# Security settings
min_id = 1000
fallback_homedir = /home/%u
# Timeout and retry settings for better AD stability
ldap_search_timeout = 10
ldap_connection_expire_timeout = 60
# Debugging options (uncomment for troubleshooting)
# debug_level = 9
#>

View File

@ -0,0 +1,101 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Parse-DataSourceConfig {
param (
[string]$ConfigPath
)
# Load the XML config
[xml]$configXml = Get-Content -Path $ConfigPath
# Define a hashtable to store results
$result = @{}
# Parse the server and port from the connection URL
$connectionUrl = $configXml.server.subsystem.datasources.datasource."connection-url"
if ($connectionUrl -match "jdbc:mysql://([^:/]+)(?::(\d+))?") {
$result.Server = $matches[1]
$result.Port = if ($matches[2]) { $matches[2] } else { "3306" } # Default MySQL port
}
# Get the username
$result.Username = $configXml.server.subsystem.datasources.datasource.security."user-name"
# Get the password
$result.Password = $configXml.server.subsystem.datasources.datasource.security.password
# Get the keystore password from the vault section
$keystorePassword = $configXml.server.security.vault."vault-option" | Where-Object { $_.name -eq "KEYSTORE_PASSWORD" }
$result.KeystorePassword = $keystorePassword.value
# Convert hashtable to PowerShell object
$resultObject = [PSCustomObject]$result
# Output the result object
return $resultObject
}
# Example usage
$parsedConfig = Parse-DataSourceConfig -ConfigPath "c:\temp\configs\standalone.xml"
$parsedConfig
<# standalone.xml used by jboss
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="urn:jboss:domain:11.0">
<extensions>
<extension module="org.jboss.as.connector"/>
<!-- Other extensions -->
</extensions>
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jndi-name="java:/jdbc/MyDS" pool-name="MyDS_Pool" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://localhost:3306/mydatabase</connection-url>
<driver>mysql</driver>
<security>
<user-name>${VAULT::vault::mydbuser}</user-name>
<password>${VAULT::vault::mydbpassword}</password>
</security>
<pool>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
</pool>
<validation>
<valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
<validate-on-match>true</validate-on-match>
<background-validation>true</background-validation>
</validation>
<timeout>
<blocking-timeout-millis>5000</blocking-timeout-millis>
</timeout>
<statement>
<track-statements>false</track-statements>
</statement>
</datasource>
<drivers>
<driver name="mysql" module="com.mysql">
<xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
<security>
<vault>
<vault-option name="KEYSTORE_URL" value="${jboss.server.config.dir}/vault.keystore"/>
<vault-option name="KEYSTORE_PASSWORD" value="password"/>
<vault-option name="VAULT_BLOCK" value="vault"/>
<vault-option name="ATTRIBUTE" value="my_password"/>
</vault>
</security>
<!-- Other subsystems like transactions, deployments, security, etc. -->
</server>
#>

View File

@ -0,0 +1,97 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-SysprepCredentials {
param (
[Parameter(Mandatory=$true)]
[string]$FilePath
)
# Check if file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "File does not exist: $FilePath"
return
}
# Initialize an empty hashtable to store credentials
$credentials = @{
AdminPassword = $null
JoinDomain = $null
DomainAdmin = $null
DomainAdminPassword = $null
}
# Read the sysprep.inf file
$fileContent = Get-Content -Path $FilePath
# Loop through each line and extract relevant credentials
foreach ($line in $fileContent) {
if ($line -match 'AdminPassword\s*=\s*(.+)') {
$credentials['AdminPassword'] = $matches[1].Trim()
}
if ($line -match 'JoinDomain\s*=\s*(.+)') {
$credentials['JoinDomain'] = $matches[1].Trim()
}
if ($line -match 'DomainAdmin\s*=\s*(.+)') {
$credentials['DomainAdmin'] = $matches[1].Trim()
}
if ($line -match 'DomainAdminPassword\s*=\s*(.+)') {
$credentials['DomainAdminPassword'] = $matches[1].Trim()
}
}
# Create and return a PowerShell object
$credObject = [pscustomobject]@{
AdminPassword = $credentials['AdminPassword']
JoinDomain = $credentials['JoinDomain']
DomainAdmin = $credentials['DomainAdmin']
DomainAdminPassword = $credentials['DomainAdminPassword']
}
return $credObject
}
# Example usage:
$result = Get-SysprepCredentials -FilePath "c:\temp\configs\sysprep.inf"
$result
<# sysprep.inf
[Unattended]
OemSkipEula=Yes
InstallFilesPath=C:\sysprep\i386
[GuiUnattended]
AdminPassword=YourAdminPassword
EncryptedAdminPassword=NO
OEMSkipRegional=1
TimeZone=004
OemSkipWelcome=1
[UserData]
ProductKey=XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
FullName="Your Name"
OrgName="Your Organization"
ComputerName=*
[Display]
BitsPerPel=32
Xresolution=1024
YResolution=768
Vrefresh=60
[SetupMgr]
DistFolder=C:\sysprep\i386
DistShare=windist
[Identification]
JoinDomain=YourDomain
DomainAdmin=YourDomainAdmin
DomainAdminPassword=YourDomainAdminPassword
[Networking]
InstallDefaultComponents=Yes
#>

View File

@ -0,0 +1,99 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Extract-OracleCredentials {
param(
[string]$FilePath
)
if (-Not (Test-Path -Path $FilePath)) {
Write-Error "File path does not exist: $FilePath"
return
}
# Initialize an empty array to store the results
$credentialsList = @()
# Read the file contents
$fileContent = Get-Content -Path $FilePath
# Initialize variables to store temporary values
$currentDatabase = $null
$currentUser = $null
$currentPassword = $null
foreach ($line in $fileContent) {
# Trim the line for easier processing
$line = $line.Trim()
# Match a database name (lines that don't start with a '(' and end with '=')
if ($line -match '^\w+\s*=\s*$') {
if ($currentDatabase -and $currentUser -and $currentPassword) {
# Store the previous credentials
$credentialsList += [pscustomobject]@{
Database = $currentDatabase
User = $currentUser
Password = $currentPassword
}
}
# Reset the user and password for the next database entry
$currentDatabase = $line -replace '\s*=\s*$', '' # Remove the equals sign
$currentUser = $null
$currentPassword = $null
}
# Match the USER line
if ($line -match 'USER\s*=\s*(.+)$') {
$currentUser = $matches[1]
}
# Match the PASSWORD line
if ($line -match 'PASSWORD\s*=\s*(.+)$') {
$currentPassword = $matches[1]
}
}
# Capture the last set of credentials
if ($currentDatabase -and $currentUser -and $currentPassword) {
$credentialsList += [pscustomobject]@{
Database = $currentDatabase
User = $currentUser
Password = $currentPassword
}
}
# Output the results as a list of objects
return $credentialsList
}
# Example usage:
$result = Extract-OracleCredentials -FilePath "c:\temp\configs\tnsnames.ora"
$result | Format-Table
<# tnsnames.ora - oracle
MYDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = mydbserver.example.com)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = mydbservice)
)
)
(USER = myusername)
(PASSWORD = mypassword)
MYDB_ALIAS =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = mydbserver.example.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = mydbservice)
)
)
(USER = anotheruser)
(PASSWORD = anotherpassword)
#>

View File

@ -0,0 +1,78 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-TomcatUsers {
param (
[Parameter(Mandatory = $true)]
[string]$TomcatConfigFile
)
# Load the XML file
[xml]$xml = Get-Content -Path $TomcatConfigFile
# Create an array to store the results
$usersList = @()
# Select the user nodes from the XML
$users = $xml.'tomcat-users'.user
# Loop through each user and extract the name and password attributes
foreach ($user in $users) {
# Create a PowerShell object for each user
$userObject = [PSCustomObject]@{
Username = $user.name
Password = $user.password
}
# Add the object to the list
$usersList += $userObject
}
# Display the list of users as a table
return $usersList
}
# Example usage
$tomcatConfigFilePath = "c:\temp\configs\tomcat-users.xml"
Get-TomcatUsers -TomcatConfigFile $tomcatConfigFilePath | Format-Table -AutoSize
<# tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<tomcat-users>
<!--
NOTE: By default, no user is included in the "manager-gui" role required
to operate the "/manager/html" web application. If you wish to use this app,
you must define such a user - the username and password are arbitrary.
-->
<!--
NOTE: The sample user and role entries below are wrapped in a comment
and thus are ignored when reading this file. Do not forget to remove
<!.. ..> that surrounds them.
-->
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-status"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<user name="admin" password="admin" roles="admin-gui,admin-script,manager-gui,manager-status,manager-script,manager-jmx"/>
</tomcat-users>
#>

View File

@ -0,0 +1,143 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Parse-UnattendFile {
param (
[string]$filePath
)
# Load the XML file
[xml]$xmlContent = Get-Content -Path $filePath
# Create an array to store the parsed credentials
$credentials = @()
# Define namespaces used in the XML file
$namespace = @{
"unattend" = "urn:schemas-microsoft-com:unattend"
"wcm" = "http://schemas.microsoft.com/WMIConfig/2002/State"
}
# Function to decode Base64 if password is encoded
function Decode-PasswordIfNeeded {
param (
[string]$passwordValue,
[bool]$isPlainText
)
if ($isPlainText -eq $false) {
try {
# Decode Base64 password
$decodedPassword = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($passwordValue))
return $decodedPassword
} catch {
Write-Host "Error: Unable to decode Base64 string, returning original value."
return $passwordValue
}
}
else {
return $passwordValue
}
}
# Parse AutoLogon credentials
$autoLogon = $xmlContent.unattend.settings.component | Where-Object {
$_.name -eq "Microsoft-Windows-Shell-Setup" -and $_.AutoLogon -ne $null
}
if ($autoLogon) {
$username = $autoLogon.AutoLogon.Username
$password = $autoLogon.AutoLogon.Password.Value
$isPlainText = $autoLogon.AutoLogon.Password.PlainText -eq "true"
# Decode password if necessary
$password = Decode-PasswordIfNeeded -passwordValue $password -isPlainText $isPlainText
$credentials += [pscustomobject]@{
User = $username
Password = $password
Source = "AutoLogon"
}
}
# Parse LocalAccounts credentials
$localAccounts = $xmlContent.unattend.settings.component.UserAccounts.LocalAccounts.LocalAccount | Where-Object { $_ -ne $null }
foreach ($account in $localAccounts) {
$username = $account.Name
$password = $account.Password.Value
$isPlainText = $account.Password.PlainText -eq "true"
# Decode password if necessary
$password = Decode-PasswordIfNeeded -passwordValue $password -isPlainText $isPlainText
$credentials += [pscustomobject]@{
User = $username
Password = $password
Source = "LocalAccount"
}
}
# Return the collected credentials as an array of objects
return $credentials
}
# Example usage:
$parsedCredentials = Parse-UnattendFile -filePath "c:\temp\configs\unattend-base64.xml"
# Display the results
$parsedCredentials | Format-Table -AutoSize
<# unattend.xml
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<ComputerName>*</ComputerName>
<RegisteredOrganization>acme corp.</RegisteredOrganization>
<RegisteredOwner>acme corp.</RegisteredOwner>
<WindowsFeatures>
<ShowInternetExplorer>false</ShowInternetExplorer>
</WindowsFeatures>
<AutoLogon>
<Username>LocalAdmin</Username>
<Enabled>true</Enabled>
<LogonCount>10</LogonCount>
<Password>
<Value>UEBzc3dvcmQxMjMh</Value> <!-- This is Base64 for 'P@ssword123!' -->
<PlainText>false</PlainText>
</Password>
</AutoLogon>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>UEBzc3dvcmQxMjMh</Value> <!-- This is Base64 for 'P@ssword123!' -->
<PlainText>false</PlainText>
</Password>
<Group>Administrators</Group>
<Description>Provisioning Admin</Description>
<DisplayName>LocalAdmin</DisplayName>
<Name>LocalAdmin</Name>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
</component>
</settings>
</unattend>
#>

View File

@ -0,0 +1,110 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-VNCPassword {
param (
[Parameter(Mandatory=$true)]
[string]$VncIniPath
)
# Define the fixed DES key used by VNC
$desKey = [byte[]](0x23, 0x52, 0x6A, 0x3B, 0x58, 0x92, 0x67, 0x34)
# Read the vnc.ini file
if (-Not (Test-Path -Path $VncIniPath)) {
Write-Error "The file path '$VncIniPath' does not exist."
return
}
$vncIniContent = Get-Content -Path $VncIniPath
# Extract the encrypted password from the ini file
$encryptedHex = ($vncIniContent | ForEach-Object {
if ($_ -match '^Password=(.+)$') {
return $matches[1]
}
}).Trim()
if (-not $encryptedHex) {
Write-Output "Password not found in vnc.ini"
return
}
# Convert the hex string to a byte array
$encryptedBytes = for ($i = 0; $i -lt $encryptedHex.Length; $i += 2) {
[Convert]::ToByte($encryptedHex.Substring($i, 2), 16)
}
# Create a DES crypto object and set the key and mode
$des = New-Object System.Security.Cryptography.DESCryptoServiceProvider
$des.Key = $desKey # Assign the key as a byte array
$des.Mode = [System.Security.Cryptography.CipherMode]::ECB
$des.Padding = [System.Security.Cryptography.PaddingMode]::None
# Create a decryptor
$decryptor = $des.CreateDecryptor()
# Decrypt the encrypted password
$decryptedBytes = $decryptor.TransformFinalBlock($encryptedBytes, 0, $encryptedBytes.Length)
# Convert the decrypted byte array to a string, trimming null characters
$decryptedPassword = [System.Text.Encoding]::ASCII.GetString($decryptedBytes).Trim("`0")
# Return the decrypted password as an object
return [pscustomobject]@{
DecryptedPassword = $decryptedPassword
}
}
# Example usage
$path = "c:\temp\configs\vnc.ini"
$passwordObject = Get-VNCPassword -VncIniPath $path
$passwordObject
<# vnc.ini
[Server]
# The port on which the VNC server listens for connections (default: 5900)
Port=5900
# Defines the IP address to bind the VNC server to. Leave blank to bind to all interfaces.
BindTo=0.0.0.0
# Enable or disable authentication. If 1, authentication is enabled.
Authentication=1
# VNC password (encoded or plain text depending on the software)
Password=01d47b4186dfa5a3
# Encryption (optional). Enable or disable encryption for VNC connections.
Encryption=1
# Set the idle timeout for client connections (in seconds)
IdleTimeout=600
# Maximum number of clients that can connect at once
MaxClients=5
[Security]
# Use SSL encryption for communication between VNC clients and server
UseSSL=0
# If SSL is enabled, provide the path to the SSL certificate file.
SSLCertificateFile=C:\path\to\ssl\certificate.pem
# Enable or disable TLS encryption
UseTLS=1
[Logging]
# Enable or disable logging. If 1, logging is enabled.
EnableLogging=1
# Log file location
LogFile=C:\path\to\log\vncserver.log
# Log level (INFO, DEBUG, ERROR, etc.)
LogLevel=INFO
#>

View File

@ -0,0 +1,329 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
# Function to parse configuration files for credentials
function Get-CredentialsFromConfigFile {
param (
[string]$configFilePath
)
# Load the config file as XML
[xml]$configXml = Get-Content $configFilePath
# Initialize a DataTable to store results
$dtCredentials = New-Object System.Data.DataTable
$null = $dtCredentials.Columns.Add("Name", [string])
$null = $dtCredentials.Columns.Add("Section", [string])
$null = $dtCredentials.Columns.Add("URL", [string])
$null = $dtCredentials.Columns.Add("Server", [string])
$null = $dtCredentials.Columns.Add("Port", [string])
$null = $dtCredentials.Columns.Add("UserName", [string])
$null = $dtCredentials.Columns.Add("Password", [string])
# Helper function to add rows to DataTable
function Add-CredentialsToDataTable {
param (
[string]$name,
[string]$section,
[string]$url,
[string]$server,
[string]$port,
[string]$username,
[string]$password
)
$null = $dtCredentials.Rows.Add($name, $section, $url, $server, $port, $username, $password)
}
# Dictionary to temporarily store related credentials
$credentialPairs = @{}
# Function to store credentials in temporary dictionary
function Add-CredentialPair {
param (
[string]$name,
[string]$section,
[string]$key,
[string]$value
)
if ($credentialPairs[$name]) {
$credentialPairs[$name][$key] = $value
} else {
$credentialPairs[$name] = @{}
$credentialPairs[$name][$key] = $value
$credentialPairs[$name]["Section"] = $section
}
# If both username and password are available, add them to the DataTable
if ($credentialPairs[$name]["UserName"] -and $credentialPairs[$name]["Password"]) {
Add-CredentialsToDataTable -name $name -section $credentialPairs[$name]["Section"] `
-url $credentialPairs[$name]["URL"] -server $credentialPairs[$name]["Server"] `
-port $credentialPairs[$name]["Port"] -username $credentialPairs[$name]["UserName"] `
-password $credentialPairs[$name]["Password"]
# Clear the stored credential after adding it to the table
$credentialPairs.Remove($name)
}
}
# Parse all instances of appSettings for OAuth, WebClient, API, and other credentials
if ($configXml.SelectNodes('//appSettings')) {
foreach ($appSettings in $configXml.SelectNodes('//appSettings')) {
foreach ($setting in $appSettings.add) {
$key = $setting.key
$value = $setting.value
$section = "AppSettings"
# Handle specific cases for OAuth, API, and WebClient settings
switch ($key) {
"OAuthServiceUrl" { Add-CredentialPair -name "OAuth" -section $section -key "URL" -value $value }
"ClientId" { Add-CredentialPair -name "OAuth" -section $section -key "UserName" -value $value }
"ClientSecret" { Add-CredentialPair -name "OAuth" -section $section -key "Password" -value $value }
"ServiceUrl" { Add-CredentialPair -name "WebClient" -section $section -key "URL" -value $value }
"ServiceUserName" { Add-CredentialPair -name "WebClient" -section $section -key "UserName" -value $value }
"ServicePassword" { Add-CredentialPair -name "WebClient" -section $section -key "Password" -value $value }
"ApiEndpoint" { Add-CredentialPair -name "API" -section $section -key "URL" -value $value }
"ApiUserName" { Add-CredentialPair -name "API" -section $section -key "UserName" -value $value }
"ApiPassword" { Add-CredentialPair -name "API" -section $section -key "Password" -value $value }
"ApplicationUsername" { Add-CredentialPair -name "Application" -section $section -key "UserName" -value $value }
"ApplicationPassword" { Add-CredentialPair -name "Application" -section $section -key "Password" -value $value }
}
}
}
}
# Parse custom serviceCredentials section
if ($configXml.configuration.serviceCredentials) {
foreach ($setting in $configXml.configuration.serviceCredentials.add) {
$key = $setting.key
$value = $setting.value
$section = "ServiceCredentials"
# Handle specific cases for custom service credentials
switch ($key) {
"ServiceUrl" { Add-CredentialPair -name "CustomService" -section $section -key "URL" -value $value }
"UserName" { Add-CredentialPair -name "CustomService" -section $section -key "UserName" -value $value }
"Password" { Add-CredentialPair -name "CustomService" -section $section -key "Password" -value $value }
}
}
}
# Parse connectionStrings for server, port, username, and password
if ($configXml.configuration.connectionStrings) {
foreach ($connection in $configXml.configuration.connectionStrings.add) {
$connectionString = $connection.connectionString
$providerName = $connection.providerName
$name = $connection.name
# Initialize variables for potential data
$server = $null
$port = $null
$user = $null
$password = $null
$url = $null
# Parse connection strings
if ($connectionString -match "Host\s*=\s*([^;]+).*?Port\s*=\s*(\d+).*?Username\s*=\s*([^;]+).*?Password\s*=\s*([^;]+)") {
$server = $matches[1]
$port = $matches[2]
$user = $matches[3]
$password = $matches[4]
$url = "Host=$server;Port=$port"
} elseif ($connectionString -match "(Server|Data Source)\s*=\s*([^;,]+)(?:,(\d+))?") {
$server = $matches[2]
if ($matches[3]) { $port = $matches[3] }
$url = "Server=$server"
}
if ($connectionString -match "User\s*Id\s*=\s*([^;]+)") {
$user = $matches[1]
}
if ($connectionString -match "Password\s*=\s*([^;]+)") {
$password = $matches[1]
}
# Add row to the DataTable if username and password exist
if ($user -and $password) {
Add-CredentialsToDataTable -name $name -section "ConnectionStrings ($providerName)" -url $url -server $server -port $port -username $user -password $password
}
}
}
# Parse system.net/mailSettings for SMTP credentials and URLs
if ($configXml.configuration.'system.net'.mailSettings) {
foreach ($smtp in $configXml.configuration.'system.net'.mailSettings.smtp) {
$smtpServer = $smtp.network.host
$smtpPort = $smtp.network.port
$smtpUser = $smtp.network.userName
$smtpPass = $smtp.network.password
$url = "smtp://${smtpServer}:${smtpPort}"
if ($smtpUser -and $smtpPass) {
Add-CredentialsToDataTable -name "SMTP Configuration" -section "SMTP" -url $url -server $smtpServer -port $smtpPort -username $smtpUser -password $smtpPass
}
}
}
# Output the parsed credentials using the DataTable
if ($dtCredentials.Rows.Count -eq 0) {
Write-Host "No credentials found." -ForegroundColor Red
} else {
$dtCredentials | select Name, Section, URL, Server, Port, UserName, Password
}
}
# Example of calling the function with a file path
Get-CredentialsFromConfigFile -configFilePath "c:\temp\configs\web.config"
<# web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- Config Sections for Custom Service Credentials -->
<configSections>
<section name="serviceCredentials" type="System.Configuration.NameValueSectionHandler" />
<sectionGroup name="system.net">
<section name="settings" type="System.Net.Configuration.SettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</sectionGroup>
</configSections>
<!-- Application Settings for web application -->
<appSettings>
<add key="ApplicationUsername" value="myAppUser" />
<add key="ApplicationPassword" value="myAppPassword" />
<add key="OAuthServiceUrl" value="https://oauth.example.com/token" />
<add key="ClientId" value="myClientId" />
<add key="ClientSecret" value="myClientSecret" />
<add key="ServiceUrl" value="https://service.example.com/api" />
<add key="ServiceUserName" value="serviceUser" />
<add key="ServicePassword" value="servicePassword" />
<add key="ApiEndpoint" value="https://api.example.com/endpoint" />
<add key="ApiUserName" value="apiUser" />
<add key="ApiPassword" value="apiPassword" />
</appSettings>
<!-- Custom service credentials -->
<serviceCredentials>
<add key="ServiceUrl" value="https://customservice.example.com" />
<add key="UserName" value="customUser" />
<add key="Password" value="customPassword" />
</serviceCredentials>
<!-- Connection strings for various databases -->
<connectionStrings>
<add name="SqlServerConnection"
connectionString="Data Source=localhost;Initial Catalog=myDB;User ID=myUser;Password=myPass;"
providerName="System.Data.SqlClient" />
<add name="SqlServerIntegratedSecurity"
connectionString="Data Source=localhost;Initial Catalog=myDB;Integrated Security=True;"
providerName="System.Data.SqlClient" />
<add name="MySqlConnection"
connectionString="Server=localhost;Database=myDB;User=myUser;Password=myPass;"
providerName="MySql.Data.MySqlClient" />
<add name="PostgreSqlConnection"
connectionString="Host=localhost;Port=5432;Database=myDB;Username=myUser;Password=myPass;"
providerName="Npgsql" />
<add name="OracleConnection"
connectionString="Data Source=MyOracleDB;User Id=oracleUser;Password=oraclePass;"
providerName="Oracle.ManagedDataAccess.Client" />
</connectionStrings>
<!-- Web-specific settings for forms authentication, session state, and errors -->
<system.web>
<!-- Compilation settings -->
<compilation debug="true" targetFramework="4.0" />
<!-- Authentication settings for web applications -->
<authentication mode="Forms">
<forms loginUrl="login.aspx" timeout="30">
<credentials passwordFormat="Clear">
<user name="user1" password="password1" />
<user name="user2" password="password2" />
</credentials>
</forms>
</authentication>
<!-- Authorization settings to allow or deny user access -->
<authorization>
<allow users="*" /> <!-- Allow all users -->
<deny users="?" /> <!-- Deny anonymous users -->
</authorization>
<!-- Custom error pages -->
<customErrors mode="RemoteOnly">
<error statusCode="404" redirect="404.aspx" />
<error statusCode="500" redirect="500.aspx" />
</customErrors>
<!-- Session State settings (optional) -->
<sessionState mode="InProc" timeout="20" />
</system.web>
<!-- SMTP settings for email (relevant for web applications) -->
<system.net>
<mailSettings>
<smtp from="you@example.com">
<network host="smtp.example.com" port="587"
userName="smtpUser"
password="smtpPassword"
defaultCredentials="false" />
</smtp>
</mailSettings>
</system.net>
<!-- WCF (Windows Communication Foundation) Service configuration for web applications -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://example.com/service"
binding="basicHttpBinding"
bindingConfiguration="MyBinding"
contract="IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior>
<clientCredentials>
<userName userName="serviceUser" password="servicePassword" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<!-- IIS-specific settings for URL rewriting and other web server configurations -->
<system.webServer>
<!-- Enable URL rewriting (optional) -->
<rewrite>
<rules>
<rule name="RedirectToHTTPS">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
<!-- Enable static content compression (optional) -->
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>
<!-- HTTP modules and handlers (optional) -->
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
#>

View File

@ -0,0 +1,101 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-WinSCPConfig {
param (
[Parameter(Mandatory = $true)]
[string]$FilePath
)
# Check if file exists
if (-not (Test-Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Read the WinSCP.ini file content
$content = Get-Content -Path $FilePath
# Initialize an empty object for results
$result = [PSCustomObject]@{
HostName = $null
PortNumber = $null
PrivateKeyFile = $null
UserName = $null
Password = $null
}
# Parse the .ini file for relevant information
foreach ($line in $content) {
if ($line -match '^HostName=(.*)') {
$result.HostName = $matches[1]
} elseif ($line -match '^PortNumber=(.*)') {
$result.PortNumber = [int]$matches[1]
} elseif ($line -match '^PrivateKeyFile=(.*)') {
$result.PrivateKeyFile = $matches[1]
} elseif ($line -match '^UserName=(.*)') {
$result.UserName = $matches[1]
} elseif ($line -match '^Password=(.*)') {
$result.Password = $matches[1] # Encrypted password in .ini
}
}
# Return the result object
return $result
}
# Example usage
$winSCPConfig = Get-WinSCPConfig -FilePath "c:\temp\configs\WinSCP.ini"
$winSCPConfig
<# winscp decryption function that uses dpapi below
function ConvertFrom-DPAPI {
param (
[Parameter(Mandatory = $true)]
[string]$EncryptedPassword
)
# Convert the base64 encoded password back to byte array
$passwordBytes = [Convert]::FromBase64String($EncryptedPassword)
# Use the Windows DPAPI to decrypt the password
$decryptedBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($passwordBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
# Convert the decrypted byte array back to a string (UTF-8 encoded)
$decryptedPassword = [System.Text.Encoding]::UTF8.GetString($decryptedBytes)
return $decryptedPassword
}
# Example usage with an encrypted password from WinSCP.ini
$encryptedPassword = "Base64EncryptedPasswordHere"
$decryptedPassword = ConvertFrom-DPAPI -EncryptedPassword $encryptedPassword
Write-Output "Decrypted Password: $decryptedPassword"
#>
<# winscp.ini
[Configuration\Interface]
Random=4074A9829D979781989E96
[Sessions\example]
HostName=ftp.example.com
PortNumber=21
UserName=myuser
Password=0V5aNH+/kT8= ; Encrypted password
LocalDirectory=C:\Users\myuser\Documents
RemoteDirectory=/public_html
FSProtocol=0
PostLoginCommands=
PrivateKeyFile=
[Configuration\Interface\Commander]
LastLocalDirectory=C:\Users\myuser\Documents
LastRemoteDirectory=/public_html
#>

View File

@ -0,0 +1,121 @@
# Author: Scott Sutherland, NetSPI (@_nullbind / nullbind)
function Get-WPConfigCredentials {
param (
[string]$FilePath
)
# Check if the file exists
if (-Not (Test-Path $FilePath)) {
Write-Error "File not found: $FilePath"
return
}
# Initialize variables for username and password
$dbUsername = $null
$dbPassword = $null
# Read the file line by line
Get-Content $FilePath | ForEach-Object {
$line = $_
# Match the DB_USER line and extract the username
if ($line -match "define\(\s*'DB_USER'\s*,\s*'([^']+)'\s*\)") {
$dbUsername = $matches[1]
}
# Match the DB_PASSWORD line and extract the password
if ($line -match "define\(\s*'DB_PASSWORD'\s*,\s*'([^']+)'\s*\)") {
$dbPassword = $matches[1]
}
}
# Check if both username and password were found
if ($dbUsername -and $dbPassword) {
# Return the results as a PowerShell object
[PSCustomObject]@{
Username = $dbUsername
Password = $dbPassword
}
}
else {
Write-Error "Username or Password not found in the configuration file."
}
}
# Example usage
$credentials = Get-WPConfigCredentials -FilePath "c:\temp\configs\wp-config.php"
$credentials
<# wp-config.php
<?php
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'your_database_name' );
/** MySQL database username */
define( 'DB_USER', 'your_database_username' );
/** MySQL database password */
define( 'DB_PASSWORD', 'your_secure_password_here' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the WordPress.org secret-key service
* https://api.wordpress.org/secret-key/1.1/salt/
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*/
define('AUTH_KEY', 'put_your_unique_phrase_here');
define('SECURE_AUTH_KEY', 'put_your_unique_phrase_here');
define('LOGGED_IN_KEY', 'put_your_unique_phrase_here');
define('NONCE_KEY', 'put_your_unique_phrase_here');
define('AUTH_SALT', 'put_your_unique_phrase_here');
define('SECURE_AUTH_SALT', 'put_your_unique_phrase_here');
define('LOGGED_IN_SALT', 'put_your_unique_phrase_here');
define('NONCE_SALT', 'put_your_unique_phrase_here');
/**#@-*/
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each a unique
* prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*/
define( 'WP_DEBUG', false );
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
#>