sql字符串注入攻击
SQL注入攻击是黑客对数据库进行攻击的常用手段之一。SQL注入的手法相当灵活
SQL注入攻击会导致的数据库安全风险包括:刷库、拖库、撞库。
一般来说,SQL注入一般存在于形如:HTTP://xxx.xxx.xxx/abc.asp?id=XX等带有参数的ASP动态网页中,
如果ASP程序员没有安全意识,不进行必要的字符过滤,存在SQL注入的可能性就非常大。
SQL注入攻击被俗称为黑客的填空游戏。
发现SQL注入位置;
判断后台数据库类型;
确定XP_CMDSHELL可执行情况
发现WEB虚拟目录
上传ASP木马;
得到管理员权限;
案例1(接练习题、向数据库添加数据)
cmd.CommandText = "insert into Students values( ' " +code+ " ', ' " +name+ " ' )";
conn.Open();
cmd.ExecuteNonQuery(); -- 攻击前 用 C# 编写的 字符串拼接形式
conn.Close();
SQL注入攻击
a ' ) ; update students set Sname = ' 傻 X ' ; --
cmd.CommandText = "insert into Students values
( ' code' ,' a ' ); update students set Sname = ' 傻 X ' ; --
conn.Open();
cmd.ExecuteNonQuery(); -- 攻击后 实际运行
conn.Close();
案例2
某个网站的登录验证的SQL查询代码为:
strSQL =
"SELECT * FROM users WHERE (name='"
+ userName+
"') and (pw= '"
+
passWord
+
"');"
恶意填入
userName =
"1' OR '1'='1"
;
passWord
=
"1' OR '1'='1"
;
将导致原本的SQL字符串被填为
strSQL =
"SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
也就是实际上运行的SQL命令会变成下面这样的
strSQL =
"SELECT * FROM users;"
达到无账号密码,亦可登录网站。
防御
可以通过数据库防火墙实现对SQL注入攻击的防范,,
可以使用虚拟补丁技术实现对注入攻击的SQL特征识别,实现实时攻击阻断。
对案例1进行防御
cmd.CommandText = "insert into Students values(@a,@b)";
cmd.Parameters.Clear(); -- 清空
cmd.Parameters.AddWithValue( " @a " , code ); -- @a 占位符 与对应的值 code
cmd.Parameters.AddWithValue( " @b " , name ); -- @b 占位符 与对应的值 name
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
Student表 Scode,Sname
添加学生信息 ,只需要用户输入学生姓名,编号自动生成:S001 S002 .....using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.SqlClient;namespace ConsoleApplication1{ class Program { static void Main(string[] args) { //默认表中没有数据 string code = "S001"; while (true) { Console.Write("请输入添加的学生姓名:"); string name = Console.ReadLine(); string sql = "server=.;database=Data0216;user=sa;pwd=123"; SqlConnection conn = new SqlConnection(sql); SqlCommand cmd = conn.CreateCommand(); //查询所有降序排列 cmd.CommandText = "select *from Students order by Scode desc"; conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); if (dr.HasRows) { //生成编号 dr.Read(); //取第一个(最大) string s = dr["Scode"].ToString(); // 截取 s 后面的 转换类型 留3位数 code = "S" + (Convert.ToInt32(s.Substring(1)) + 1).ToString("000"); } conn.Close(); cmd.CommandText = "insert into Students values(@a,@b);"; cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@a", code); cmd.Parameters.AddWithValue("@b", name); conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); Console.ReadLine(); } } }}
2
using System;using System.Collections.Generic;using System.Data.SqlClient;using System.Linq;using System.Text;namespace ConsoleApplication4{ class Program { static void Main(string[] args) { //5、Student表 Scode,Sname //添加学生信息 ,只需要用户输入学生姓名, //编号自动生成:S001 S002 string sql = "server=.;database=Data0216_5;user=sa;pwd=123"; SqlConnection conn = new SqlConnection(sql); SqlCommand cmd = conn.CreateCommand(); Console.Write("请输入姓名:"); string name = Console.ReadLine(); string scode; cmd.CommandText = "select * from student"; conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); if (dr.HasRows) { int a = 0; while (dr.Read()) { a += 1; } scode = "s" + (a+1).ToString("000"); } else { scode = "s001"; } conn.Close(); cmd.CommandText = "insert into student values('" + scode + "','" + name + "')"; conn.Open(); int aa = cmd.ExecuteNonQuery(); if (aa > 0) { Console.WriteLine("添加成功"); } else { Console.WriteLine("添加失败!"); } conn.Close(); Console.ReadLine(); } }}
1于2的区别