Instance explain SQL injection attacks
SQL injection" is a kind of use not filtered/audit user input method of attack (" buffer overflow "and this is different), means to let the application run should not have run the SQL code.Create the SQL string if an undefended and run them, can cause some unexpected results.
A customer can let us for their employees and customers using the enterprise Intranet penetration test.This is a part of the safety assessment, so even though we had no prior used SQL injection to penetrate into the network, but the concept is quite familiar with.Now finally we have a big success in this task, to review every step of the process, and record it as a case.
We recorded in many false twist after twists and turns, and a more experienced people can have different - even better - this method.But the fact is we know after success, we were not completely misguided.
Other SQL article contains more details, but this article not only shows the process of the exploit, also tells the story of discovered the principle that loophole.
Show in front of our eyes is a complete custom website, we have not seen this website before, also have no right to view its source code: this is a "black box" attack."Spy on" the result shows that this server running on Microsoft iis 6, and is ASP.NET framework.This implies that our database is Microsoft SQL server: we believe that our technique can be used on any web application, no matter what kind of SQL server it USES.
Landing pages have traditional users - password form, but more than a "give my password to my" links;Later, this place is proved to be the key to the fall of the whole system.
When typing the email address, the system assumes that the mail, will email address in the user database, query, and then send some content to this address.But I can't find the email address, so it won't send me anything.
For any form of SQL, the first step in the test, the data is input with a single quotation marks: the purpose is to see if they are to construct the SQL string for filtering.When the single quotes as email after submission, we get a 500 error (server), which means that the "harmful" input is actually is directly used in the SQL statement.It is this!
It might be, I guess the SQL code:
WHERE field = '$EMAIL';
$EMAIL users are from the address of the form is submitted, and a query on the end of the string $EMAIL provides quotes.We don't know the exact name of the field or table, but we understand the nature of them, this will help us make the right guess.
When we firstname.lastname@example.org'- pay attention to this at the end of the quotes - below is the composition of the SQL fields:
WHERE field = 'email@example.com'';
When it began to execute SQL, SQL parser will find redundant quotes then interrupt execution, and grammatical errors is given.This mistake how clear to the user, the expression of internal error recovery procedure based on the application, but are generally not prompt "email address does not exist".The error response into death's door, it tell people the user input is not properly handle, it left an opportunity for application to crack.
The data presented in the WHERE clause, let's try to change to conform to the SQL standard input, and see what happens.Type anything 'OR' x '=' x, the results are as follows: SELECT fieldlist FROM table WHERE field = 'anything' OR 'x'='x';
Because applications can't thinking - only construct input string - we use single quotes the WHERE clause of a single component into the double, 'x' = 'x' clause is constant, no
matter what is the first clause.(there is a better way to ensure that "always true", we will then come into contact with).
But "real" with every time returns only a single data query is different, the above structure must return all of the members database's data.If you want to know what to do in this case application, the only way is to try, try, try again.We got this:
Your login information has been firstname.lastname@example.org.
We assume that the address is the query to the first record.This guy really can he forget the password in this email received, presumably he will be very surprised also leads to his toes.
We now know that can need according to oneself to tamper with the query, while for those who can't see the part is not enough to understand, but we noticed that after several attempts to get the three different response:
; "Your login information has been mailed to the email address"
; "We can't recognize your email address"
; Server error
The first two response is a valid SQL, the final response is invalid SQL: when the speculation that the query structure, the difference is very useful.
Mode field mapping
The first step is to guess the field name: our reasonable speculated that the query contains "email address" and "password", may also have "US Mail address" or "userid" or "phone number" field.We especially want to perform the SHOW TABLE statement, but we don't know the name of the TABLE, there is no obvious way to get the name of the TABLE.
We carried out the next step.In each test, we will use our known part combined with some special tectonic statements.We already know the SQL execution result is email address, so we have to guess the email field name:
SELECT fieldlist FROM table WHERE field = 'x' AND email IS NULL; --';
Purpose is to assume that the query of the field name (email), try to SQL is effective.I don't care about that matches the email address is what (we use a false name 'x'), '-' this symbol starting SQL comments.For removal of the quotation marks at the end of, this is a very effective way, we don't have to care about our block is what.
If we got a server error, means that there is inappropriate, SQL and syntax error will be thrown: is more likely to be the field name is wrong.If we got any effective response, we can guess the field name is right.This is what we get "email unknown" or "password was sent" response process.
We can also use AND conjunctions to replace OR: this is meaningful.In the SQL schema mapping phase, we don't need to guess a specific email address, we don't want to application of random flood send user "is this your password" email - it's not so good, may arouse suspicion.While using the connection email address, AND will become invalid, we can always ensure that the query returns 0, never generated password reminder email.
Submit the above snippet indeed gives us "email address unknown" response, now we know that your email address is stored in the email in the field name.If there is no effect, we can try email_address field name or mail.This process requires considerable speculation.
Next, we guess the name of the other obvious: password, user ID, name, etc.Guess a field at a time, as long as the response is not "server failure", that means we guessed it. SELECT fieldlist FROM table WHERE email = 'x' AND userid IS NULL; --';
In the process, we found a few right field name:
No doubt there is a lot more (there's a clue in the form field name), a mining after found no more.But we still don't know the field name of the table name, where are they found?
In search of a database table
Application of built-in query command has established the name of the table, but we don't know what is: there are several ways to find the name of the table.One of them is rely on subselect (keyword query).
An independent inquiry
SELECT COUNT(*) FROM tabname
Record the number of return list, if the table name is invalid, the query will fail.We can set up their own string to detect the table name:
SELECT email, passwd, login_id, full_name
WHERE email = 'x' AND 1=(SELECT COUNT(*) FROM tabname); --';
We don't care how many records, only care about the name of the table is correct.After repeated speculation, we finally found the members is the effective of this database table
name.But it is used in this query?So we need another test, the use of the table. The field: the actual query part of the work in this table only, not as long as there is table is executed. SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'
AND members.email IS NULL; --';
When return Email unknown ", means that our SQL injection is successful, and we have the correct guess the name of the table.It is very important on the back of the job, but we'll try the other way.
Looking for a user account
Our members table structure has the concept of a local, but we only know a user name: any user can get "Here is your password" email.In retrospect, we never received information itself, if only it were sending address.We need to get a few user name, so you can get more data.
First of all, we are to find it from the company's web site a few people: "About us" or "Contact" page usually provides the company member list.Usually contains the email address, even if they don't provide this list also it doesn't matter, we can according to some clues to use our tools to find them.
The LIKE clause can be user query, allow us to partial match in the database user name or email address, every time to submit if show "We sent your password" information and mail hair, also proved effective.
Warning: do this to the email address, but really can send the email to each other, this is likely to cause suspicion, used with caution.
We can check email name or full name (or speculate out other information), each time in the % wildcards for the following query:
SELECT email, passwd, login_id, full_name
WHERE email = 'x' OR full_name LIKE '%Bob%';
Remember that although may not only a "Bob", but we can only see a message: suggest that refining the LIKE clause.
Brute force password
To be sure, we can be in landing pages to brute force password, but many systems have made monitoring defense even for this.Possible means to have a operation logs, account
lockout, or other can hinder our way of action, but because of unfiltered input, we will be able to bypass the more protection measures.
We include in the structure of the string email name and password for the password test.In our example, we use the email@example.comAnd tried many password set. SELECT email, passwd, login_id, full_name FROM members WHERE email = '
href="mailto:firstname.lastname@example.org">email@example.com' AND passwd
This is a very good SQL statements, we won't get hints of server error, as long as we get "your password has had been mailed to you" message, it shows that we have to get the password.By this time the victim may alert, but who care about him, we have to get the password.
This process can use the perl script automatically, however, we are in the process of writing scripts, found another way to crack the system.
The database is not read-only
So far, we didn't do things outside of querying the database, although the SELECT is read-only, but do not represent SQL can only so.SQL semicolons said over, if there is no correct input filter, there is nothing can prevent us from the instruction after the structure has nothing to do with the query string.
The most drastic example is:
This dose of medicine is this:
SELECT email, passwd, login_id, full_name
WHERE email = 'x'; DROP TABLE members; --'; -- Boom!
The first part we have prepared a fake email address - 'X' - we don't care about what return query result: we just want to get our own structure of SQL commands.The attack to delete the entire members list, it's not very fun.
This suggests that we not only can slice the SQL command, and also can change the database.This is allowed.
Add a new user
We already know about the local structure members list, add a new record to the table depending on is a feasible method: if this is successful, we can simply use our new insert log in to the system.
Don't be too surprised, this SQL is a bit long, our branch shows that in order to understand it, but it is still one statement:
SELECT email, passwd, login_id, full_name
WHERE email = 'x';
INSERT INTO members ('email','passwd','login_id','full_name')
VALUES ('firstname.lastname@example.org','hello','steve','Steve Friedl');--';
Even if we have the right of the field name and the name of the table, but we still have a few things before successful attack need to know:
1. In a web form, we may not have enough space to type so many text
(although can solve with the script, but it's not always easy).
2. Web applications may not have members table INSERT permissions.
3. Undoubtedly, there must be other members list field, some may need
to initial value, otherwise it will cause the INSERT fails.
4. Even if we insert a new record, the application could not run
normally, because we can't provide field names will be
automatically inserted into the NULL value.
5. A correct "member" may well not only need a record of the members
list, and combine other list of information (e.g., access), so only
add a table may not be enough.
In this case, we have met the question # 4 or # 5, we cannot be sure which is it, because with the constructed landed them in time, returned to the server error.Although it is suggested that we don't have any structure of the field is a must, but we have no way to deal with.
A feasible way is to guess the other fields, but it is a process of Labour demanding: although we can guess the other "obvious" field, but it's difficult to get the whole application organization chart.
We finally try the other way.
The password to me
We realize that although we are unable to add new records to the members in the database, but we can modify the already existing, it proved to be feasible.
Learn from the previous email@example.comAccount in this system, we used SQL injection to the records in the database to our email address:
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x';
After running, we naturally got "we didn 't know your email address", but this is as expected, after all, we used a fake email address.The UPDATE operation will not notify the application, so it carried out quietly.
After that, we use the "I lost my password" feature, we just update the email address, a minute later, we received this email:
Subject: Intranet login This email is in response to your request for your
Intranet log in information. Your User ID is: bob Your password is: hello
Now, we need to do is follow the standard login process into the system, this is a high-quality staff, with advanced permissions, it is better than we INSERT the user.
We found the internal site content much more special, even includes a list of all users, we can reasonable launch many network have the same Windows network account, where they can all use the same password.We can easily get any network password, and we found an open on the firewall enterprise the PPTP protocol VPN port, the login test easier.
We picked a few account test is not successful, we don't know if "password error" or "the enterprise internal account is different from Windows account name".But we think that the automation tool will make the job easier.
In the specific permeability, we have enough permissions, we don't need any more, but there are other methods.We haven't enough to try but we now think of common method.
We realize that not all method has nothing to do with the database, we can try.
Microsoft used to support stored procedures or have permission to perform any operating system instructions.If this feature allow web users to use, the webserver is penetration is inevitable.
So far, we do are limited in the web application and database in the environment, but if we can perform any operating system command, again the server could not help but severe infiltration.Or is usually only a handful of the administrator account can use, but it may also be authorized to lower-level users.
Create the database structure
After the login on application provides rich function, has no need to do a deeper mining, but in other restrictions more environment may not be enough.
To visible map database structure of system, a table and their field structure, may not directly help.But the penetration for the web site provides a Lin Meng avenue.
Other aspects from the website to collect more information about the data structure (for example, "message board" page? "help BBS" and so on?).But the applications rely on strong, but also have to rely on your accurate guess.
We believe that web application developers often don't consider the harmful "input", but security personnel should consider (including the bad guys), so there are three methods can be used.
The input filter
Filtering input is very important to ensure that the input does not contain dangerous codes, whether the SQL server or the HTM itself."Bad character" first thought is peeled off, like quotes, semicolon, or escape sign, but it is a way of not very good.Although it is easy to find some dangerous characters but hard to find them all.
Web language itself is full of special characters and strange markup (including those who express the same character of alternative character), so I want to try to identify all the characters "malice" is unlikely to succeed.
In other words, instead of "remove known malicious data", as to remove the "good" all the data: the distinction is important.In our example, the email address can only contain the following characters:
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 @.-_+
Allow the incorrect characters input is of no benefit, should refuse them early - there may be some error message - not only can prevent SQL injection, also can capture some input error rather than put them in the database.
A particular email address will make validation program in trouble, because everyone in the definition of "effective".Due to the email address you is rejected, without considering the characters of that was embarrassing.
Is the real authorityRFC 2822(more than RFC822 content), it permits the use of the contents of the "" made the definition of a specification.Specification of this more academic hope can accept & and * (and more) as a valid email address, but other people - including author - were happy to use a reasonable subset to include more email addresses.
Those who adopt more limit method should be fully aware of does not contain the address of the consequences, especially the restrictions had better technology (precompiled/execution, stored procedures) to avoid the "strange" characters of security issues.
Realize "filter input" does not mean merely "remove quotes", because even though a "normal" character may cause problems.In the example below, an integer ID value is compared to the user's input comparison (digital PIN) :
SELECT fieldlist FROM table WHERE id = 23 OR 1=1; -- Boom! Always matches!
In practice, however this method has limitations, because to be able to completely eliminate all risks is quite a small field of the characters.For the "date" or "email address" or "integer", the above method is valuable, but for the real environment, we inevitably to use other ways to mitigate the hazards.
Input item code/escaped
Can now filter the phone number and email address, but you cannot use the same method to deal with "name" field, or we may rule out Bill O 'reilly name: to this field, the quote here is legal input.
Someone will think of filtering to the single quotes, plus a quote, it was no problem, but something would happen so dry!
Pretreatment of each string to replace single quotation marks:
WHERE name = 'Bill O''Reilly'; -- works OK