SANS Penetration Testing

TDS, MSSQL, and Python... Oh My!

[Editor's Note: Mark Baggett has been writing some awesome articles for this blog lately about how to use Python modules for all kinds of powerful penetration testing activities. This article is no exception — in it, Mark details how to use the Impacket suite from Core Security to interact with Microsoft SQLServer databases. The article culminates with Mark creating a password guessing tool to go after the database... and the best part is that the conceptual model of his tool can be adapted to any kind of authenticating module you might have for Python. Nice work, Mark! -Ed.]

By Mark Baggett

Well, Alberto Solino and the good folks over at Core Security have released another update to the Python Impacket Module. The new update resolves an installation issue and makes the sample scripts even easier to use. To install it, simply download the latest tar ball from here:

Extract the contents using the command "tar -zxf impacket-0.9.10.tar.gx". Then "cd" into the new impacket-0.9.10 directory and run "python install". WARNING: At this point, it is essential to prepare for a rocking good time.

The installer script places the sample scripts including and in your path in the /usr/local/bin directory. If you had any trouble getting some of my previous posts on the Impacket module working, you can find those posts here and try them again using this fantastic version update:

This Impacket code update includes several improvements, one of which is the tds module, named after the Tabular Data Stream protocol used to access databases. In particular, the tds module is used to interface with Microsoft SQL servers, for fun, mayhem, and pwnage. The update also includes a tool called to demonstrate the power of the tds module. The python script "" will give you a SQL shell on a target, provided that you have some way of authenticating to the host. Oh, the chocolatey goodness.

The script supports SQL authentication and NT authentication with either a password or the password hash (you gotta love pass-the-hash attacks). In other words, if you need to pass the hash to a SQL database, this tool will do that for you. Alternatively, if I know the password and want to login to my SQL server at with a username of "sa" and a password of "password", I can type the following:

At the SQL> prompt, I can issue valid SQL statements and see the results. Very cool! But this is a python module, so I can import all this functionality into my own scripts and quickly use all the capabilities of the tds module. For example, an import and a for loop is all that is needed to take this module and turn it into a password guessing utility. I'll show you how, not only for this specific technique, but also to indicate how we can change any authenticating tool into something that can do password guessing, all via the magic of Python!

Logging into a SQL database requires 3 steps:

1) Create a new TDS Microsoft SQL object.

The tds.MSSQL() method takes two parameters. The first parameter is a string containing an IP address and the second parameter is the port for the SQL server. Here we connect to the server at the IP "" and the default SQL port of 1433:

tdsobject=tds.MSSQL("", 1433)

2) Call the TDS object's "connect()" method.

Next we call the tdsobjects connect() method. This parameter doesn't require any parameters so you can just call "tdsobject.connect()".

3) Call the TDS object's "login()" method.

Finally, you call the .login method. The .login method will accept several parameters. To look at the complete list of parameters, we can use the simply lovely Python introspection feature (where Python teaches you how to use its modules) and type "help(tdsobject.login)". The following screen appears:

Each of the options with an equals sign after it has a default value. They are "optional" parameters that don't have to be passed if you are happy with that default. The "self" parameter also doesn't have to be included. It is automatically included by Python any time you execute a class method. To call the login method, you simply have to supply a database name and a username. We want to try several passwords in a list, so we will include the third parameter (password) as well. If your username and password are correct, the login method will return "True". If you fail to login successfully, it will return "False". If the login fails, we can see why by calling the printReplies() method.

Now, lets put all this together and write a simple MSSQL password guesser. We can wrap our call to .login() in a for loop that tries every password in the john the ripper password list (handily called "password.lst", containing a little more than 3,000 passwords), like so:

Here is a sample run of the program.

Here is the script itself:

from impacket import tds
import sys

tdsobject=tds.MSSQL("", 1433)

for pw in passwords:
done=tdsobject.login("master",targetuser, pw.strip())
if done:
print "password is ",pw
print tdsobject.printReplies()

The nicest thing about the script above is its reusability. Whenever you have an authentication capability supported by a Python object, you can use the base concepts and structure above to turn it into a password-guessing tool! I'm sure our readers will find all kinds of great use cases for this. If you have some nifty ideas, please feel free to share in the comments below.

Would you like more information about how you can create your own Python powered penetration testing tools? Join me for my brand-new SANS class, SEC573 Python for Penetration Testers.

Thank you!

-Mark Baggett

Follow me on twitter @MarkBaggett




Posted May 22, 2013 at 12:01 PM | Permalink | Reply


Hi and thanks for this great post. I'll surely test this new release.
I'm waiting for each new post on python from Mark Baggett.
''" Why not publishing a sort of commandlinekungfu (resp/pythonpentestingkungfu) to gather all posts from Mark ?
''" I see that the .login method has a ''hashes' parameter / (rewt dance ?) : I plan to use it laterrally to find a valid auth with a previously found hash.
Thanks again.

Posted May 22, 2013 at 12:02 PM | Permalink | Reply


Hi and thanks for this great post. I'll surely test this new release.I'm waiting for each new post on python from Mark Baggett.- Why not publishing a sort of commandlinekungfu (resp/pythonpentestingkungfu) to gather all posts from Mark ?- I see that the .login method has a ''hashes' parameter / (rewt dance ?) : I plan to use it laterrally to find a valid auth with a previously found hash.Thanks again.R.

Posted May 23, 2013 at 11:40 AM | Permalink | Reply

Ed Skoudis

Mark's stuff is indeed fantastic. You can get to all of his blogs on Python on this site (and any other Python-related material we'll have in the future) by going to the following URL:
Hope this helps!

Posted May 28, 2013 at 4:46 PM | Permalink | Reply


Nicely explained.
I missed your other posts, but will go back and view them. I've been wanting to learn python anyway, and have been "poking" around it.
Actually that course you mentioned might be a good way to do that. Is it offered via vlive or onDemand? (Those are the only training methods that are practical to me.)
I'll book mark the link mentioned by Ed. The posts should be helpful to me.

Post a Comment


* Indicates a required field.