When you make your house secure, you might want to do the
obvious things such as putting good locks on the doors, and fasteners on the
windows, but you are still interested on peeping through the curtains to watch
for suspicious activity in the street. If people in balaclavas are carrying
ladders and eyeing up the side of the house, or checking sight-lines, you’d want
to know about it, surely.
Why take a different attitude when you put a website out
there, particularly if it is a trading site with lots of confidential
information? Wouldn’t you want to see what the villains are up to? A couple of
years ago, I did just that. I felt like the little pig that had the house of
brick. Although I was confident that I’d done enough to prevent the big bad wolf
from blowing the site over, I wanted to know if he was eyeing up the chimney
with a view to a sneaky entrance, especially if I could light a fire when he’s
descending.
It was a fascinating and salutary experience. I was not
aware of the extent of the activity that bombards a site to try to break it. It
is a constant stream.
Some attacks are so simple,
yet seem to be still worthwhile for the hacker. Surely there aren't sites
around still with this sort of vulnerability? Just as an example, there was a
continuous stream of 404s (returning a 404 error to the requester to tell them
the file was not found), resulting from people trying to find the location of
the admin site. Hmm. Up to no good here. The combinations were endless.
Responding to 404s is dumb, as it allows an automaton to go through a very long
list; login.asp, login.php, index.asp, admin.php, maint.aspx, and so on until
they get a successful request. As an experiment I made a lot of completely bogus
admin pages to react to these sorts of requests. It caused a temporary rush of
excitement to some east European somewhere. Here, I discovered, is one of the
few ways that the long-suffering site-maintainer can fight back, and laugh like
a drain as a human being attempts to hack into your bogus site-admin console.
There is a delicious pleasure from constructing a completely bogus database,
using SQL Data Generator, and watching the hackers break in, but be careful, as
you don't want to provoke a retaliatory DOS attack. The payback is that you get
to see the whole process of an attack.
I had great fun seeing the ingenuity of
these attempts to log in as the administrator of my dummy site admin screen.
Mostly, they use a shared script, probably a Perl script, though there are
plenty of applications that will do a brute-force attack. There is no shortage of
places on the internet that you can download these tools. You don't have to be
clever to use them, just to think them up in the first place. Although a few
were completely unintelligible to me, most are simple.
This is the way they do it. They get the
Admin login screen. They check the form, and see what the variables are, just by
looking at the <form> block. They see if it is a POST or a GET. When they know
how to send login data to the database they are away. They rely on a very
elementary mistake. It is anticipating that user input
is either incorrectly filtered for string literal escape characters such as '', or user input
that has not been checked for correctness. It relies on SQL statements being
constructed on the fly, and executed, rather than parameterized.
The hacker determines, from the FORM
block, the name of the script file, ASPX or PHP, perhaps, to log in to the site.
Imagine that the parameters represent user ID and password. The <FORM> block
will tell the hacker all he/she needs to know.
The hacker passes any UserID he wants,
let’s use the example ‘DAVE’, and passes, as the password the string ‘’’ or 1=1
-- (there are around fifty combinations of Magic strings, which are variations
on this.) This will sometimes get him logged in as administrator. Game over.
Even today, there is a chance that the
ASP file will not check to see if there are single quotes in the password. It
will just take the GET or POST variable and stuff it into a SQL query, hoping it
will look like this....
SELECT USER_Identity FROM MyUsers WHERE userid='DAVE' AND password='secret'
…and will expect to return a non-zero recordset if the userid and password were correct. Instead, the query will look
like this!
SELECT USER_Identity FROM MyUsers WHERE USER='DAVE' AND password='''' OR 1=1 --'
Our password value,
which is one of the many ‘Magic Strings’ …
''' OR 1=1
--
… has had delimiters added and the resulting code had
returned every row. Try it.
--just to demonstrate the technique
--we build a bogus list of users and their passwords
CREATE TABLE MyUsers (User_Identity INT IDENTITY(1,1),
UserID VARCHAR(20),
Password VARCHAR(30))
INSERT INTO MyUsers(UserID, Password)
SELECT 'Dave', 'voluble12'
INSERT INTO MyUsers(UserID, Password)
SELECT 'Tony', 'cockeyed3546'
INSERT INTO MyUsers(UserID, Password)
SELECT 'Robyn', 'workinghard408354'
INSERT INTO MyUsers(UserID, Password)
SELECT 'Bob', 'MyPasswordIsSecure2396845'
--This is the SQL Statement the programmer wanted to construct
SELECT USER_Identity FROM MyUsers WHERE userID='dave' AND password='voluble12'
--this is the string that the hacker likes to inject
SELECT USER_Identity FROM MyUsers WHERE USER='DAVE' AND password='''' OR 1=1 --'
GO
--although the 'dynamic SQL crimes are generally committed in ASP, here is
--a stored procedure that commits the crime.
ALTER PROCEDURE spLogin (@userID VARCHAR(80), @Password VARCHAR(80))
AS
EXECUTE ('Select USER_Identity from MyUsers where userID='''
+@UserID
+''' and password='''+@Password+'''')
GO
--innocent procedure call
EXECUTE spLogin 'dave', 'voluble12'
--U BIN HAKKED!!!
EXECUTE spLogin 'THE HAKKER', ''''''' or 1=1 --'
Now, you wouldn’t believe that anyone is
dumb enough to keep an exploit like this open would you? The rookie programmer
scoops up the name of the userID, and the password and does no sanity checks.
He/She then constructs the SQL on the fly rather than using parameters or,
better, calling stored procedures. He doesn't look at the contents of the result that is handed back to him, even to see how many rows there are.
Notice that if getting the admin login
to your website isn’t enough for you, you can always do more extreme things such
as delete the user table
EXECUTE spLogin 'THE DESTROYER', ''''''' drop table MyUsers --'
--Or look for backup files with a view to FTPing them to you
EXECUTE spLogin 'THE CURIOUS', ''''''' execute xp_cmdshell ''dir c:\windows'' --'
This is just the start, of course. You
don’t have to be able to access the Admin screen to get the information from a
database. As long as the programmer has forgotten to parameterize his queries,
forgotten to check for escape characters, or has failed to check for the
validity of the input, in just one of the scripts that call the database, then
your database is at the mercy of the hacker.
The hacker can use a technique such as
blind SQL injection or inference SQL injection. This essentially does a binary
chop to read strings character-by-character so as to get from the database a
whole realm of interesting information. All that the hacker needs is an
indication of when a query returns rows and when it doesn’t. Time is on his side, as the website probably has no alerts for unusual activity. (a binary chop for character string causes a spike)
Some of the easiest hacks have been
possible because the result of a query is always rendered on the browser. It is
so tempting to create a single generic routine for rendering all data returned
from the database as an HTML table, or list.
Of course, if the database users are set
up properly, none of this is possible as the login from the website only has
access to the Interface stored procedures, and you don’t use dynamic SQL in
these. You have to assume that the hacker is somehow going to be able to
pick up the login credentials from the site, and you must plan accordingly. I
use the extra precaution of a time-limited, and revokeable, authorization
key issued from the database. You can then relax as you study the amazing complexity of the attempts to
get at your data. When I say ‘relax’ I’m only referring to ‘as relaxed as the
third little pig whilst the big bad fox paces around the brick house, huffing
and puffing’. You can’t predict in advance what the hacker will try. I always
create a log that stores all accesses to the interface, along with the
parameters passed. It really takes no extra time to do this. I read the weblogs
into the database as well, to check for unusual spikes of activity. It’s always
best to know what attacks are being made to your websites.