1. Preparation tools: SQL SERVER, Visual Studio
2. Database scripts and. NET code (C #)
3.SqlServer Profiler
SQL script code:
Use MASTER
Go
-Retrieves whether the SQLTMP database exists
if EXISTS (SELECT * from sysdatabases WHERE name = ' sqltmp ')
- Delete sqltmp database
drop db sqltmp Go-
-Creating database Create DB sqltmp go-
-Using SQLTMP database Use
sqltmp
Go
-------------Create a table to validate the SQL injection Vulnerability----------------
--Retrieves whether the table exists if
EXISTS (SELECT * from sysobjects WHERE Name = ' admin ')-
-delete table
drop table admin
go
-create table created tables
admin
(
ID INT PRIMARY Key IDENTITY (1,1),--set the primary key
name VARCHAR (.) not NULL,--user name
pass VARCHAR (a) not null--password
)
-------- -----Insert a test data---------------------------insert INTO
admin VALUES (' admin ', ' admin ')-
-Query insert Data
SELECT * FROM admin
Here is a section of C # code that validates the username password:
<font size= "3" color= "#ff00ff" >using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using System.Threading.Tasks;
Using System.Data;
Using System.Data.SqlClient; Namespace Sqltmp {class Program {//database connection string public static string Strcon = ' Data source=.;i
Nitial catalog=sqltmp;integrated security=true ";
Create a database Connection object static SqlConnection Sqlcon = new SqlConnection (Strcon);
static void Main (string[] args) {Console.WriteLine ("Please enter user name:");
String name = Console.ReadLine ();
Console.WriteLine ("Please enter password:");
String pass = Console.ReadLine (); try {program P = new program ();//Open database connection P.open (); String sql = "Select COUNT (*) from admin WHERE name = '" +name+ "' and P
Ass = ' "+pass+" ";
SqlCommand sqlcom = new SqlCommand (sql, Sqlcon); int i = (int) sqlcom.
ExecuteScalar (); if (i > 0) {Console.WriteLine ("Login Successful!")
");
}
else {Console.WriteLine ("Login failed!");}
Console.ReadLine (); The catch (Exception) {throw;} finally {//Shutdown database connection pass.
Clone (); }//Open database connection public void open ()
{///closed Open database connection if (sqlcon.state = = connectionstate.closed) {Sqlcon.open ();}//Break case Open database connection if (sqlcon.state = = Connec
Tionstate.broken) {//close sqlcon.close ();
Sqlcon.open (); //Close the database connection public void Close () {if (sqlcon.state = ConnectionState.Open | |
Sqlcon.state = = Connectionstate.broken) {sqlcon.close ();}} }} </font>
Let's test it.
Enter the correct account password:
Admin Admin
Login successful
Enter the wrong account password:
Test test
Login failed
We enter in Username: ' or 1=1--
Password: 123
Will find that you can login successfully!
Database does not have this account password, but also login successful?
Why?
0X03 Analysis
Let's dissect the running process of SQL statements
Use my SQL statement tracking tool (SQL Server Profiler)
Click the link
Run
Let's take a look at the correct account password and the SQL statement.
Perform a look in our SQL Server, with data that meets the criteria
Let's take a look at the input error account password SQL statement
Perform a look in our SQL Server, no data that meets the criteria
Let's take a look at the SQL statement of the account password we entered last time.
Let's take a look at the SQL statement in the picture. Compare our SQL statements above
<font size= "3" color= "#ff00ff" >select count (*) from sqltmp WHERE name = ' admin ' and ' = ' admin '
SELECT COUNT ( *) from sqltmp WHERE name = ' or 1=1 '-' and pass = ' 123 '
</font>
We will find that the username we entered becomes empty, followed by an or 1=1--' Why, what's the cause???
From here we should look at this piece of code:
<font size= "3" color= "#ff00ff" > String sql = "Select COUNT (*) from admin WHERE name = '" +name+ "' and pass = ' +pass+ ' '";
</font>
We can see that SQL is in the name and pass is the variable is the user entered the account and password
Let's take a look at the username entered: ' or 1=1--
Then the user will automatically "close" the name = ' when input '
And or 1=1 the Where condition forever
--In the sense that SQL is annotated, the following SQL statement is commented out!!!
So we can assume that the SQL statement looks like this in the end.
<font size= "3" color= "#ff00ff" >select COUNT (*) from sqltmp WHERE name = ' or 1=1</font>
0X04 Defense
There's a way to attack, a defensive way.
As far as I know, there are two ways to use it:
1. Through SqlParameter
Benefits: Precompiling SQL statements to prevent being transferred
Usage:
<font size= "3" color= "#ff00ff" >string sql = "Select COUNT (*) from admin WHERE name = [Url=home.php?mod=space&uid =116087] @name [/url] and pass = @pass ";
Create sparameter[]
sqlparameter[] para = {
new SqlParameter ("@name", name),
new SqlParameter ("@pass", pass)
};
SqlCommand sqlcom = new SqlCommand (sql, Sqlcon);
Para[is put in sqlcom by Parameters.addrange method
. Parameters.addrange (para);
int i = (int) sqlcom. ExecuteScalar ();
</font>
At the @ symbol for the parameter, we change the splicing mode to the form of the parameter
2. Stored Procedures
1. First create the stored procedure in the database
<font size= "3" color= "#ff00ff" >create PROC Login (@name VARCHAR, @pass VARCHAR) as
SELECT COUNT (*) From admin WHERE name = @name and pass = @pass
go
</font>
2. Call the stored procedure
<font size= "3" color= "#ff00ff" >sqlparameter[] para = {
new SqlParameter ("@name", name),
new SqlParameter ("@pass", pass)
};
SqlCommand sqlcom = new SqlCommand ();
Sqlcom. Connection = Sqlcon;
Sqlcom.commandtext = "Login";
Specifies that the execution type is stored procedure
sqlcom.commandtype = CommandType.StoredProcedure;
Sqlcom. Parameters.addrange (para);
int i = (int) sqlcom. ExecuteScalar ();
</font>
Well, about this article for you to introduce. NET application SQL injection to introduce to everyone here, I hope to help you, if you have any questions welcome to my message, small series will promptly reply to everyone, here also thank you for your support cloud Habitat community site!