In-depth analysis of. NET application SQL injection and. netsql Injection
1. preparation tools: SQL SERVER, Visual Studio
2. Database scripts and. net code (c #)
3. SqlServer Profiler
SQL script code:
Use master go -- retrieve if exists in the SQLTMP database (SELECT * from sysdatabases where name = 'sqltmp ') -- delete sqltmp database drop database sqltmpgo -- create database sqltmpgo -- use sqltmp database use sqltmpgo ------------- CREATE a table to verify the SQL injection vulnerability ---------------- whether the search table EXISTS IF EXISTS (SELECT * FROM SYSOBJECTS WHERE name = 'admin ') -- delete table drop table adminGO -- create table admin (id int primary key identity (), -- Set primary key name VARCHAR (20) not null, -- User name pass VARCHAR (20) not null -- password) ------------- INSERT a test data ------------------------- insert into admin VALUES ('admin', 'admin') -- Query inserted data SELECT * FROM admin
The following code verifies the user name and 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 = .; initial Catalog = SQLTMP; Integrated Security = True "; // create a database connection object static SqlConnection SqlCon = new SqlConnection (strCon); static void Main (string [] args) {Console. writeLine ("Enter the User name:"); String name = Console. readLine (); Console. writeLine ("Enter Password:"); String pass = Console. readLine (); try {Program p = new Program (); // open the database connection p. open (); string SQL = "SELECT COUNT (*) FROM admin WHERE name = '" + name + "' AND pass = '" + pass + "'"; sqlCommand sqlcom = new SqlCommand (SQL, SqlCon); int I = (int) sqlcom. executeScalar (); if (I> 0) {Console. writeLine ("Logon successful! ");} Else {Console. WriteLine (" Logon Failed! ");} Console. readLine ();} catch (Exception) {throw;} finally {// close the database connection pass. clone () ;}/// Open the database connection public void Open () {// Open the database connection if (SqlCon. state = ConnectionState. closed) {SqlCon. open ();} // Open the database connection if (SqlCon. state = ConnectionState. 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
Logon successful
Enter the wrong account password:
Test
Logon Failed
In the username field, enter 'or 1 = 1 --
Password 123
You can also find that the logon is successful!
If this account and password are not in the database, will the logon be successful?
Why?
0x03 profiling
Let's analyze the running process of SQL statements.
Use my SQL statement tracking tool (SQL Server Profiler)
Click link
Run
Let's take a look at the SQL statement of the correct account and password.
Run the following command in our SQL Server to check whether the data meets the conditions.
Let's take a look at the incorrect account and password SQL statement.
Run the following command in our SQL Server to check that no matching data exists.
Let's take a look at the SQL statement of the last account and password entered.
Let's take a look at the SQL statements in the image. Let's compare the preceding SQL statements.
<font size="3" color="#ff00ff">SELECT COUNT(*) FROM SQLTMP WHERE name = 'admin' AND pass = 'admin'SELECT COUNT(*) FROM SQLTMP WHERE name = '' or 1=1 -- ' AND pass = '123'</font>
We will find that the user name we entered has become empty, and there is more or 1 = 1 -- 'behind it. Why ???
Now 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 the name and pass in SQL are variables that are user-input accounts and passwords.
Let's take a look at the entered Username: 'or 1 = 1 --
If you enter ', the name = ''is automatically closed.
And or 1 = 1 sets the where condition forever
-- When SQL is annotated, the subsequent SQL statements are commented out !!!
So we can think that the SQL statement is like this at the end.
<font size="3" color="#ff00ff">SELECT COUNT(*) FROM SQLTMP WHERE name = '' or 1=1</font>
0x04 defense
There is a way to defend against attacks.
As far as I know, there are two common methods:
1. Use SQLParameter
Benefits: Pre-compiled SQL statements prevent conversion
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); // use Parameters. the addRange method adds para [] to sqlcom. parameters. addRange (para); int I = (int) sqlcom. executeScalar (); </font>
@ Symbol represents the parameter. we replace the concatenation method with the parameter format.
2. Stored Procedure
1. Create a stored procedure in the database
<font size="3" color="#ff00ff">CREATE PROC Login (@name VARCHAR(20) ,@pass VARCHAR(20))ASSELECT COUNT(*) FROM admin WHERE name =@name AND pass = @passGO</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"; // specify the execution type as stored procedure sqlcom. commandType = CommandType. storedProcedure; sqlcom. parameters. addRange (para); int I = (int) sqlcom. executeScalar (); </font>
Okay. I will introduce this article to you. the SQL injection of the NET application is introduced here. I hope it will help you. If you have any questions, please leave a message. The editor will reply to you in time, thank you very much for your support for the help House website!