The whole process of SQL injection and site directional blasting in ASP website

Source: Internet
Author: User
Tags chr md5 encryption sql injection sql parameterized query try catch

The author of the Boring, see the company near a service agency site, ASP language, built in the IIS server. At first I did not notice that the site has SQL injection vulnerabilities, conveniently in a news.asp?id=52 URL entered a single quotation mark, then the server reported 500 errors, and gave the error of the SQL information (Khan, server-related error message must not leak out, But it seems that I did not look at the station did not notice the exception of the problem, the page to get the ID parameters should have mandatory int, so the current page constructs a few requests have not found the injection point, I defy the stubborn donkey strength immediately came out.

Bitter find no fruit, the author registered the site's members, and landed on, to see if there is no new injection port. The author after landing grab bag found in the clear text of the information stored in the member, such as the member login name, so the author changed the cookie, but also simple add a single quote, the result ... The server is also 500 and gives an error message. But this time the error message is different, the error message in the display program directly using cookies, did not do any filtering, like

SELECT * from xxx where username= ' $_cookie[' username '] '

So ... Then, the injection point appears.

So the author sent a message to the webmaster, told the website member system has SQL injection loophole, hope that the website in the service function before the official online repair it.


The author after work, Curiosity killed the cat, continue to see how broken.

(1) The author first guessed his backstage management system landing address for www.xxx.com/admin, sure enough, guessed right.

(2) The author again guessed his administrator login table called Admin, injected into the SQL ' exists (SELECT * from Admin) ', the results page 200, also guessed right.

(3) I guess his admin table admin should have a field name username, a field name password, the result has been 500, did not guess right

(4) So the author to see the next login page HTML source code, hoping to find clues from inside. The first step of the author is to see the landing form, found that the landing table Single-name for admin, login password table single-name for UserPassword, so the author based on the previous page of the error information to guess this program ape has the parameter name and database design mapping consistent habits, Then guess the admin table has a field is admin, there is a field name is UserPassword ... Sure enough, the author injected sql ' (select top 1 [admin] from Admin) >0′, also successful, the corresponding UserPassword also exist ... Well, this ...

(5) The author began to guess the length of the background login username and password, continue to inject SQL ' (select top 1 len (admin) =n '), so that N has been incremented, found its website first login username length is 5, password length is 16.

(6) Got the field name, length, next, I guess the two should be letters, numbers combination. The author sequentially injects SQL ' (select top 1 ASC (admin,n,1)) =m ', for user name n->[1,5],m->[0,128], password n->[1,16],m->[0,128], In turn, the user name and password each bit of the ASCII code ... The result is that the username is admin and the password is an encrypted 16-bit string

(7) I guess this is MD5 encryption password, so I found a website reverse decryption this string, get xxxxxxxxxx

(8) The author runs to the website landing page www.xxxx.com/admin, enters the crack user name and the password, the result ... Landed in their backstage!!!.


Walk through these steps, has basically completed the process of invasion, but I do not intend to go further down, directly shut down the machine to sleep.

Writing this article is not to teach you how to invade a website, but, through the intrusion of ideas, to summarize the site system security construction common pit, in the work can be appropriate to avoid.

(1) exception information, to remember try catch, and then the external shielding

(2) Information such as forms, do not have a strong association with the database field, preferably to do a mapping

(3) Do not believe any input from the client, including forms, URL parameters, cookies, when needed, must be safe to filter

(4) If you want to use cookies, do not rely on the important path of cookies, there is no way, please encrypt your cookies

(5) If the website has backstage, do not expose the entrance easily, do not use the commonly used name entrance name, do not expose too much information in the form

(6) Do not give users too detailed information even if they are not system-level error prompts.

(7) If there is a password, you can add other information in the encryption string, the reverse decryption plus interference ~


So how do you prevent injection?

First, using ASP to prevent injection

The method of completely sealing dead injection in ASP:

1. Digital type:

The code is as follows Copy Code

Dim TMP
TMP = Request ("Test")
IF Len (TMP) > 9 Then
Response.Write "Fuck you!"
Response.End
ElseIF isnumber (TMP) = False Then
Response.Write "Fuck you!"
Response.End
ElseIF Instr (TMP, "+") > 0 Then
Response.Write "Fuck you!"
Response.End
ElseIF Instr (TMP, "-") > 0 Then
Response.Write "Fuck you!"
Response.End
ElseIF Instr (TMP, ".") > 0 Then
Response.Write "Fuck you!"
Response.End
Else
Response.Write "Ok!"
End IF

2, Character type:

The code is as follows Copy Code

Dim TMP, I
TMP = Request ("Test")
TMP = Replace (tmp, "'", "'")
TMP = Replace (tmp, "" "," "" "")
TMP = REPLACE (tmp, CHR (10), "")
TMP = REPLACE (TMP, CHR (13), "")
Response.Write "Ok!"


one, SQL parameterized query


Then we'll analyze why stitching SQL strings can lead to SQL injection risk?

First create a table of users:

The code is as follows Copy Code

CREATE TABLE [dbo]. [Users] (

[Id] [uniqueidentifier] not NULL,

[UserId] [INT] Not NULL,

[UserName] [varchar] (m) NULL,

[Password] [varchar] () not NULL,

CONSTRAINT [pk_users] PRIMARY KEY CLUSTERED

(

[Id] ASC

With (Pad_index = off, Statistics_norecompute = off, Ignore_dup_key = off, Allow_row_locks = on, Allow_page_locks = O N) on [PRIMARY]

) on [PRIMARY]

Insert some data:

The code is as follows Copy Code

INSERT into [Test]. [dbo]. [Users] ([Id],[userid],[username],[password]) VALUES (NEWID (), 1, ' name1 ', ' pwd1 ');
INSERT into [Test]. [dbo]. [Users] ([Id],[userid],[username],[password]) VALUES (NEWID (), 2, ' name2 ', ' pwd2 ');
INSERT into [Test]. [dbo]. [Users] ([Id],[userid],[username],[password]) VALUES (NEWID (), 3, ' Name3 ', ' pwd3 ');
INSERT into [Test]. [dbo]. [Users] ([Id],[userid],[username],[password]) VALUES (NEWID (), 4, ' name4 ', ' pwd4 ');
INSERT into [Test]. [dbo]. [Users] ([Id],[userid],[username],[password]) VALUES (NEWID (), 5, ' name5 ', ' pwd5 ');

Let's say we have a user login page with the following code:

Verify that the user logs on to SQL as follows:

The code is as follows Copy Code
Select COUNT (*) from Users where Password = ' a ' and UserName = ' B '

This code returns the number of users matching password and username, if greater than 1, then represents the user.

This article does not discuss password policies in SQL or code specifications, mainly about why you can prevent SQL injection, and ask some students not to tangle with some code, or a topic unrelated to SQL injection.

You can see the results of the execution:

This is the SQL statement that SQL profile traces.

The injected code is as follows:

The code is as follows Copy Code

Select COUNT (*) from Users where Password = ' a ' and UserName = ' B ' or 1=1-' there is someone who sets the UserName to "B" or 1=1–.

The actual execution of SQL becomes the following:

It's obvious that the SQL injection was successful.

Many people know that parameterized queries can avoid the injection problems that appear above, such as the following code:

The code is as follows Copy Code

Class Program
{
private static string connectionString = "Data source=.;i Nitial catalog=test;integrated security=true ";

static void Main (string[] args)
{
Login ("B", "a");
Login ("B ' or 1=1--", "a");
}

private static void Login (string userName, string password)
{
using (SqlConnection conn = new SqlConnection (connectionString))
{
Conn. Open ();
SqlCommand comm = new SqlCommand ();
Comm. Connection = conn;
Add a parameter to each piece of data
Comm.commandtext = "Select COUNT (*) from the Users where Password = @Password and UserName = @UserName";
Comm. Parameters.addrange (
New sqlparameter[]{
New SqlParameter ("@Password", SqlDbType.VarChar) {Value = Password},
New SqlParameter ("@UserName", SqlDbType.VarChar) {Value = UserName},
});

Comm. ExecuteNonQuery ();
}
}
}

The actual execution of SQL is as follows:

The code is as follows Copy Code
EXEC sp_executesql N ' select COUNT (*) from Users where Password = @Password and UserName = @UserName ', n ' @Password varchar (1 ), @UserName varchar (1) ', @Password = ' a ', @UserName = ' B ' exec sp_executesql N ' select COUNT (*) from Users where Password = @ Password and UserName = @UserName ', N ' @Password varchar (1), @UserName varchar ', @Password = ' a ', @UserName = ' B ' or 1=1-'

You can see that parameterized queries do these things primarily:

1: Parameter filtering, you can see @UserName = ' B ' or 1=1-' 2: Execution plan reuse

Because the execution plan is reused, SQL injection can be prevented.

First, analyze the nature of SQL injection,

The user wrote a section of SQL used to indicate that the lookup password is a, and the user name is the number of all users of B.

By injecting SQL, this SQL now represents the lookup (the password is a and the username is B) or the number of all users 1=1.

You can see that the semantics of SQL has changed, why has it changed? Because the previous execution plan was not reused because the injected SQL statement was compiled again because the parsing of the syntax was performed again. So to make sure that the SQL semantics is the same, that I want to express SQL is what I want to express, not other injected meaning, should reuse the execution plan.

If the execution plan cannot be reused, there is a risk of SQL injection because the semantics of SQL may change and the query expressed may change.

Query execution plans in SQL Server can use the following script:

The code is as follows Copy Code

DBCC Freeproccache

Select Total_elapsed_time/execution_count Average time, total_logical_reads/execution_count logical Read,
Usecounts Reuse times, SUBSTRING (D.text, (STATEMENT_START_OFFSET/2) + 1,
          (case statement_end_offset
          WHEN-1 THEN datalength (text)
          ELSE statement_end_offset End
            -Statement_start_offset)/2) + 1) statement execution from Sys.dm_exec_cached_plans A
Cross apply sys.dm_exec_query_plan (A.plan_handle) c
, sys.dm_exec_query_stats b
Cross apply SYS.DM_EXEC_ Sql_text (b.sql_handle) d
--where A.plan_handle=b.plan_handle and total_logical_reads/execution_count>4000
Order by Total_elapsed_time/execution_count DESC;

 

Here's a quote from the author: "But there's no real difference between this type of writing and the direct execution of SQL."

Any concatenation of SQL is a risk of SQL injection, so if there is no substantive difference, then using exec dynamic execution of SQL does not prevent SQL injection.

For example, the following code:

The code is as follows Copy Code

private static void TestMethod ()
{
using (SqlConnection conn = new SqlConnection (connectionString))
{
Conn. Open ();
SqlCommand comm = new SqlCommand ();
Comm. Connection = conn;
Using exec to execute SQL dynamically
The query plan actually executed is (@UserID varchar (max)) SELECT * from Users (NOLOCK) where UserID in (1,2,3,4)
Not expected (@UserID varchar (max)) EXEC (' SELECT * from Users (NOLOCK) where UserID in (' + @UserID + ') ')
Comm.commandtext = "Exec" (' SELECT * from Users (NOLOCK) where UserID in (' + @UserID + ') ');
Comm. Parameters.Add (New SqlParameter ("@UserID", SqlDbType.VarChar,-1) {Value = "1,2,3,4"});
Comm. Parameters.Add (New SqlParameter ("@UserID", SqlDbType.VarChar,-1) {Value = "1,2,3,4"); Delete from users;--"});
Comm. ExecuteNonQuery ();
}
}

The SQL executed is as follows:

The code is as follows Copy Code

EXEC sp_executesql n ' EXEC (' select * from Users (NOLOCK) where UserID in (' + @UserID + ') ', n ' @UserID varchar (max) ', @Use Rid= ' 1,2,3,4 ' can see the SQL statement without parameterized queries. If you set the UserID to "1,2,3,4"; Delete from users;--

", then execute SQL is the following: EXEC sp_executesql n ' exec (NOLOCK) where UserID in (' + @UserID + ') ') ', n ' @UserID varchar (max) ', @UserID = ' 1,2,3,4 '); Delete from users;--'

Don't assume that adding a @userid represents the ability to prevent SQL injection, and the actual execution of SQL is as follows:

Any dynamic execution SQL has the risk of injecting, because dynamic means not reusing the execution plan, and if you don't reuse the execution plan, it's basically impossible to guarantee that the SQL you write is meant to mean what you're trying to say. This is like a childhood fill in the blanks, look for the password is (___) and user name is (___) user. Whatever value you fill in, that's what I'm saying. Finally, we conclude by saying that because parameterized queries can reuse execution plans, and if you reuse the execution plan, the semantics that SQL wants to express will not change, so you can prevent SQL injection, and if you can't reuse the execution plan, there's a possibility of SQL injection, and so is the stored procedure. Because the execution plan can be reused.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.