整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何解析SQL 注入

如何解析SQL 注入

、介绍

SQL 注入攻击是网络上非常常见的一种攻击!

黑客通过将恶意的 SQL 查询或者添加语句插入到应用的输入参数中,然后在后台 SQL 服务器上解析执行进行程序攻击!

哪黑客具体是如何将恶意的 SQL 脚本进行植入到系统中,从而达到攻击的目的呢?

现在的 Web 程序基本都是三层架构,也就是我们常说的 MVC 模式:

  • 表示层:用于数据的展示,也就是前端界面
  • 业务逻辑层:用于接受前端页面传入的参数,进行逻辑处理
  • 数据访问层:逻辑层处理完毕之后,会将数据存储到对应的数据库,例如mysql、oracle、sqlserver等等

例如在上图中,用户访问主页进行了如下过程:

  • 1、在 Web 浏览器中输入www.shiyanlou.com接到对应的服务器
  • 2、Web服务器从本地存储中加载index.php脚本程序并解析
  • 3、脚本程序会连接位于数据访问层的DBMS(数据库管理系统),并执行Sql语句
  • 4、数据库管理系统返回Sql语句执行结果给Web服务器
  • 5、Web服务器将页面封装成HTML格式发送给Web浏览器
  • 6、Web浏览器解析HTML文件,将内容展示给用户

整个过程中间的业务逻辑层只是进行逻辑处理,从用户到获取数据,简单的说,三层架构是一种线性关系。

二、SQL 注入漏洞详解

刚刚我们也讲到,当我们访问网页时,Web 服务器会向数据访问层发起 SQL 查询请求,如果权限验证通过就会执行 SQL 语句。

一般来说,如果是正常使用是不会有什么危险的,但是如果用户输入的数据被构造成恶意 SQL 代码,Web 应用又未对动态构造的 SQL 语句使用的参数进行检查,则会带来意想不到的危险!

废话也不多说来,下面我们就一起来看看,黑客是如何绕过参数检查,从而实现窃取数据的目的!

2.1、SQL 注入示例一:猜解数据库

下面我们使用DVWA 渗透测试平台,作为攻击测试的目标,让你更加清楚的理解 SQL 注入猜解数据库是如何发生的。

启动服务之后,首先观察浏览器中的URL,先输入 1 ,查看回显!

从图中可以看出,ID : 1,First Name:admin,Surname:Admin信息!

那后台执行了什么样的 SQL 语句呢?点击view source查看源代码 ,其中的 SQL 查询代码为:

SELECT first_name, last_name FROM users WHERE user_id='1';

OK!

如果我们不按常理出牌,比如在输入框中输入1' order by 1#

实际执行的 SQL 语句就会变成这样:

SELECT first_name, last_name FROM users WHERE user_id='1' order by 1#

这条语句的意思是查询users表中user_id1的数据并按第一字段排行

其中#后面的 SQL 语句,都会当作注释进行处理,不会被执行!

输入 1' order by 1#1' order by 2#时都能返回正常!

当输入1' order by 3#时,返回错误!

由此得知,users表中只有两个字段,数据为两列!

接下来,我们玩点高级的!

我们使用union select联合查询继续获取信息!

直接在输入框中输入1' union select database(),user()#进行查询!

实际执行的Sql语句是:

SELECT first_name, last_name FROM users WHERE user_id='1' union select database(),user()#'

通过返回信息,我们成功获取到:

  • 当前网站使用数据库为dvwa
  • 当前执行查询用户名为root@localhost

接下来我们尝试获取dvwa数据库中的表名!

在输入框中输入1' union select table_name,table_schema from information_schema.tables where table_schema='dvwa'#进行查询!

实际执行的Sql语句是:

SELECT first_name, last_name FROM users WHERE user_id='1' union select table_name,table_schema from information_schema.tables where table_schema='dvwa'#'

通过上图返回信息,我们再获取到:

  • dvwa 数据库有两个数据表,分别是 guestbookusers

可能有些同学还不够满足,接下来尝试获取重量级的用户名、密码

根据经验我们可以大胆猜测users表的字段为 userpassword,所以输入:1' union select user,password from users#进行查询:

实际执行的Sql语句是:

SELECT first_name, last_name FROM users WHERE user_id='1' union select user,password from users#'

可以看到成功爆出了用户名、密码,密码通过猜测采用 md5 进行加密,可以直接到www.cmd5.com网站进行解密。

2.2、SQL 注入示例二:验证绕过

接下来我们再试试另一个利用 SQL 漏洞绕过登录验证的示例!

这是一个普通的登录页面,只要输入正确的用户名和密码就能登录成功。

我们先尝试随意输入用户名 123 和密码 123 登录!

好像不太行,登录被拦截,从错误页面中我们无法获取到任何信息!

点击view source查看源代码 ,其中的 SQL 查询代码为:

select * from users where username='123' and password='123'

按照上面示例的思路,我们尝试在用户名中输入 123' or 1=1 #, 密码同样输入 123' or 1=1 #

恭喜你,登录成功!

为什么能够登陆成功呢?实际执行的语句是:

select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'

按照 Mysql 语法,# 后面的内容会被忽略,所以以上语句等同于:

select * from users where username='123' or 1=1

由于判断语句 or 1=1 恒成立,所以结果当然返回真,成功登录!

我们再尝试不使用 # 屏蔽单引号,在用户名中输入 123' or '1'='1, 密码同样输入 123' or '1'='1

依然能够成功登录,实际执行的 SQL 语句是:

select * from users where username='123' or '1'='1' and password='123' or '1'='1'

两个 or 语句使 and 前后两个判断永远恒等于真,所以能够成功登录!

2.3、SQL 注入示例三:判断注入点

通常情况下,可能存在 SQL 注入漏洞的 Url 是类似这种形式 :http://xxx.xxx.xxx/abcd.php?id=XX

对 SQL 注入的判断,主要有两个方面:

  • 判断该带参数的 Url 是否可以进行 SQL 注入
  • 如果存在 SQL 注入,那么属于哪种 SQL 注入

可能存在 SQL 注入攻击的动态网页中,一个动态网页中可能只有一个参数,有时可能有多个参数。有时是整型参数,有时是字符串型参数,不能一概而论。

总之,只要是带有参数的动态网页且此网页访问了数据库,那么就有可能存在 SQL 注入。

例如现在有这么一个 URL 地址:

http://xxx/abc.php?id=1

首先根据经验猜测,它可能执行如下语句进行查询:

select * from <表名> where id=x

因此,在 URL 地址栏中输入http://xxx/abc.php?id=x and '1'='1页面依旧运行正常,继续进行下一步!

当然不带参数的 URL 也未必是安全的,现在有很多第三方的工具,例如postman工具,一样可以模拟各种请求!

黑客们在攻击的时候,同样会使用各种假设法来验证自己的判断!

三、如何预防 SQL 注入呢

上文中介绍的 SQL 攻击场景都比较基础,只是简单的向大家介绍一下!

那对于这种黑客攻击,我们有没有什么办法呢?

答案肯定是有的,就是对前端用户输入的所有的参数进行审查,最好是全文进行判断或者替换

例如,当用户输入非法字符的时候,使用正则表达式进行匹配判断!

private String CHECKSQL="^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$";
Pattern.matches(CHECKSQL,targerStr);

或者,全局替换,都可以!

public static String TransactSQLInjection(String sql) {
   return sql.replaceAll(".*([';]+|(--)+).*", " ");   
}

还可以采用预编译的语句集

例如当使用Mybatis的时候,尽可能的用#{}语法来传参数,而不是${}

举个例子!

如果传入的username 为 a' or '1=1,那么使用 ${} 处理后直接替换字符串的sql就解析为

select * from t_user where username='a' or '1=1'

这样的话所有的用户数据就被查出来了,就属于 SQL 注入!

如果使用#{},经过 sql动态解析和预编译,会把单引号转义为 \',SQL 最终解析为

select * from t_user where username="a\' or \'1=1 "

这样会查不出任何数据,有效阻止 SQL 注入!

四、参考

1、简书 - Jewel591 - sql注入基础原理

2、极术社区 - 悟能之能 - 你真的了解MyBatis中${}和#{}的区别吗?

、选择题(1-18题各3分19-36题各2分,共92分)

1.在HTML的<TD>标签中,align 属性的取值是( C )

A. top ; B. middle ; C. center ; D. bottom

<table border="1">

<tr>

<td width="100px">姓名</td>

<td>性别</td>

<td>年龄</td>

</tr>

<tr>

<td>张三</td>

<td>男</td>

<td>20龄</td>

</tr>

</table>

2. CSS样式表根据所在网页的位置,可分为( B )

A.行内样式表、内嵌样式表、混合样式表; B.行内样式表、内嵌样式表、外部样式表;

C.外部样式表、内嵌样式表、导入样式表; D.外部样式表、混合样式表、导入样式表

行内样式:

<html>

<body>

<div style="width:100px;height:100px;background:red;"></div>>

</body>

</html>

-----------------------------------------------------------------

内嵌样式:

<html>

<head>

<style type="text/css">

#div{width:100px;height:100px;background:red;}

</style>

</head>

<body>

<div id="div"></div>

</body>

</html>

--------------------------------------------------------------

外部样式:

<html>

<head>

<link rel="stylesheet" type="text/css" href="ccss.css">

</head>

<body>

<div id="div"></div>>

</body>

</html>

---------------------

css文件

#div{width:100px;height:100px;background:red;}

#和.区别

.点是使用class引用的,多个控件可以同时使用一个class,一个控件上也可以使用多个class,比如

.tdRed{border:solid 1px red;}

.tdBKBlue{background-color:blue;}

<td class="tdRed" />

<td class="tdRed tdBKBule"/>

而ID是在一个页面中唯一的

总得来说class表示泛性的,id表示个性的

比如你所有的按钮都是一个颜色的

.normalButton{background-color:blue;border:solid 0px black;}

对于提交按钮会要做的大一点

#submit{width:100px;height:100px;}

那么你的按钮就是

<input type="button" id="submit" class="normalButton" value="提交" />

普通的按钮就是

<input type="button" id="abcdefg" class="normalButton" value="普通按钮" />

3. 在插入图片标签中,对插入的图片进行文字说明使用的属性是( D )

A.name; B.id; C.src; D. alt

4. 对于<FORM action=″URL″ method=*>标签,其中*代表GET或( C )

A.SET; B. PUT; C. POST ; D. INPUT

Get和post区别

安全性:POST比GET安全;

编码方式:POST方式提交时可以通过HTML文档中的<META>元素设置实体部分的编码方式,而GET方式提交时URI默认的编码方式为ISO-8859-1,不可以在页面中设置;

传输文件大小:POST方式提交文件放在实体部分传输,大小无上限,而GET方式提交文件内容放在URI部分传输,最大为2KB;

请求速度:GET比POST快。

数据传输方式:GET:查询字符串(名称/值对)是在 GET 请求的 URL 中发送的,如:/test/demo_form.asp?name1=value1&name2=value2;POST:查询字符串(名称/值对)是在 POST 请求的 HTTP 消息主体中发送的。

5. 下列标签可以不成对出现的是( B )

A.〈HTML〉〈/HTML〉 ; B.〈P〉 〈/P〉; C.〈TITLE〉〈/TITLE〉 ; D.〈BODY〉〈/BODY〉

<p>是段落标签。

在HTML4.01中某些标签(<p><br>,<hr>,<img>, <input>,<link>等)允许不成对出现,但是不推荐。在现在的浏览器里,都会“兼容”这些单标签。浏览器解释<p>标签后,碰到一个不对应的标签时,会自动填补</p>。所以<p>标签可以单标签使用,但不推荐。

在HTML5中规定了元素必须始终关闭,也就是标签必须成对出现。

6. 对于标签〈input type=*〉,如果希望实现密码框效果,*值是( C

A. hidden; B.text ; C. password ; D. submit

7. HTML代码<select name=“name”></select>表示?( D

A. 创建表格 ; <table>

B. 创建一个滚动菜单; <marquee>

C. 设置每个表单项的内容;

D.创建一个下拉菜单

8. BODY元素用于背景颜色的属性是( C )

A. alink ; B. vlink ; C. bgcolor; D. background

9. 在表单中包含性别选项,且默认状态为“男”被选中,下列正确的是( A )

A. <input type=radio name=sex checked> 男 ; B.<input type=radio name=sex enabled>

C.<input type=checkbox name=sex checked>男;

D.nput type=checkbox name=sex enabled>男

性别(单选框):<input type="radio" value="1" name="sex" checked="checked"/>男

<input type="radio" value="2" name="sex"/>女

角色(下拉框):<select name="role">

<option value="1" selected="selected">教师</option>

<option value="2">学生</option>

</select>

10. 在CSS中下面哪种方法表示超链接文字在鼠标经过时,超链接文字无下划线?( B )

A. A:link{TEXT-DECORATION: underline }; B. A:hover {TEXT-DECORATION: none};

C. A:active {TEXT-DECORATION: blink }; D. A:visited {TEXT-DECORATION: overline }

11. JavaScript代码: 'abcdefg'.indexOf('D') 结果是( B )

A:0 B:-1 C:3 D:4

Js常用方法

1.substr

substr(start,length)表示从start位置开始,截取length长度的字符串。

var src="images/off_1.png";

alert(src.substr(7,3));

弹出值为:off

2.substring

substring(start,end)表示从start到end之间的字符串,包括start位置的字符但是不包括end位置的字符。

var src="images/off_1.png";

alert(src.substring(7,10));

弹出值为:off

3.indexOF

indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置(从左向右)。没有匹配的则返回-1,否则返回首次出现位置的字符串的下标值。

var src="images/off_1.png";

alert(src.indexOf('t'));

alert(src.indexOf('i'));

alert(src.indexOf('g'));

弹出值依次为:-1,0,3

4.lastIndexOf

lastIndexOf()方法返回从右向左出现某个字符或字符串的首个字符索引值(与indexOf相反)

var src="images/off_1.png";

alert(src.lastIndexOf('/'));

alert(src.lastIndexOf('g'));

弹出值依次为:6,15

5.split

将一个字符串分割为子字符串,然后将结果作为字符串数组返回。

以空格分割返回一个子字符串返回

var s, ss;

var s="1,2,3,4";

ss=s.split(",");

alert(ss[0]);

alert(ss[1]);

12. <img src="name">的意思是?( A )

A. 图像相对于周围的文本左对齐; B. 图像相对于周围的文本右对齐;

C. 图像相对于周围的文本底部对齐; D. 图像相对于周围的文本顶部对齐

13. 点击按钮,在ID为“Link”的DIV标签内显示东软实训超链接, 下面对该按钮的onClick事件函数描述正确的是:C

A. Link.innerText='<a href="http://www.jb-aptech.com.cn">东软实训</a>';

B. Link.outerText='<a href="http://www.jb-ptech.com.cn">东软实训</a>';

C. Link.innerHTML='<a href="http://www.jb-aptech.com.cn">东软实训</a>';

D. Link.outerHTML='<a href="http://www.jb-aptech.com.cn">东软实训</a>'

innerHTML 设置或获取位于对象起始和结束标签内的

HTML

outerHTML 设置或获取对象及其内容的 HTML 形式

innerText 设置或获取位于对象起始和结束标签内的文本

outerText 设置(包括标签)或获取(不包括标签)对象的文本

innerText和outerText在获取时是相同效果,但在设置时,innerText仅设置标签内的文本,而outerText设置包括标签在内的文本

14.(“24.7” + 2.3 ) 的计算结果是( C

A. 27 ; B. 24.7 2.3; C. 24.72.3; D. 26.7

15. ( B )事件处理程序可用于在用户单击按钮时执行函数

A. onSubmit; B. onClick; C. onChange; D. onExit

属性当以下情况发生时,出现此事件onabort图像加载被中断onblur元素失去焦点onchange用户改变域的内容onclick鼠标点击某个对象ondblclick鼠标双击某个对象onerror当加载文档或图像时发生某个错误onfocus元素获得焦点onkeydown某个键盘的键被按下onkeypress某个键盘的键被按下或按住onkeyup某个键盘的键被松开onload某个页面或图像被完成加载onmousedown某个鼠标按键被按下onmousemove鼠标被移动onmouseout鼠标从某元素移开onmouseover鼠标被移到某元素之上onmouseup某个鼠标按键被松开onreset重置按钮被点击onresize窗口或框架被调整尺寸onselect文本被选定onsubmit提交按钮被点击onunload用户退出页面

16. 用户更改表单元素 Select 中的值时,就会调用( D )事件处理程序

A. onClick; B. onFocus; C. onMouseOver; D. onChange

17.onMouseUp 事件处理程序表示( A

A. 鼠标被释放; B. 鼠标按下; C. 鼠标离开某个区域; D. 鼠标单击

18. 下列哪一项表示的不是按钮( C

A. type="submit"; B. type="reset"; C. type="image"; D. type="button"

<img src="/i/eg_tulip.jpg" alt="上海鲜花港 - 郁金香" />

19.下面哪一项是换行符标签?( C

A. <body>; B. <font>; C. <br>; D. <p>

font规定文本字体、大小和颜色:

<font size="3" color="red">This is some text!</font>

<font size="2" color="blue">This is some text!</font>

<font face="verdana" color="green">This is some text!</font>

20. 下列哪一项是在新窗口中打开网页文档。( B

A. _self; B. _blank; C. _top; D. _parent

_blank在新窗口中打开被链接文档;

_self是指在本身这个网页窗口来打开新的网页链接;

_top表示在顶层窗口打开网页链接,即在整个窗口中打开被链接文档;

_parent表示在父窗口打开网页链接;

<a href="http://www.w3school.com.cn/" target="_blank">Visit W3School!</a>onclick="javascript:window.open('Default.aspx','_blank');"

21. 下面说法错误的是( D )

A. CSS样式表可以将格式和结构分离;

B. CSS样式表可以控制页面的布局;

C. CSS样式表可以使许多网页同时更新;

D. CSS样式表不能制作体积更小下载更快的网页

CSS样式表能为我们实现些什么样的功能?

1、你可以将格式和结构分离。

2、你可以以前所未有的能力控制页面布局。

3、你可以制作体积更小下载更快的网页。

4、你可以将许多网页同时更新,比以前更快更容易。

5、浏览器将成为你更友好的界面

将格式和结构分离

HTML从来没打算控制网页的格式或外观。这种语言定义了网页的结构和各要素的功能,而让浏览器自己决定应该让各要素以何种模样显示。 但是网页设计者要求的更多。所以当 Netscape推出新的可以控制网页外观的HTML标签时,网页设计者无不欢呼雀跃。 我们可以用<FONT FACE>、<I>包在<P>外边控制文章主体的外观等等。然后我们将所有东西都放入表格,用隐式GIF空格 产生一个20象素的边距。一切都变得乱七八糟。编码变得越来越臃肿不堪,要想将什么内容迅速加到网页中变得越来越难。 串接样式表通过将定义结构的部分和定义格式的部分分离使我们能够对页面的布局施加更多的控制。HTML仍可以保持简单明了的初衷。CSS代码独立出来从另一角度控制页面外观。

以前所未有的能力控制页面的布局

<FONT SIZE>能使我们调整字号,表格标签帮助我们生成边距,这都没错。但是,我们对HTML总体上的控制却很有限。我们不可能精确地生成80象素的高度,不可能控制行间距或字间距,我们不能在屏幕上精确定位图象的位置。但是现在,样式表使这一切都成为可能。

可以制作出体积更小下载更快的网页还有更好的消息:

样式表只是简单的文本,就象HTML那样。它不需要图象,不需要执行程序,不需要插件,不需要流式。它就象HTML指令那样快。有了CSS之后,以前必须求助于GIF的事情现在通过CSS就可以实现。还有,正如我先前提到的,使用串接样式表可以减 少表格标签及其它加大HTML体积的代码, 减少图象用量从而减少文件尺寸。

可以更快更容易地维护及更新大量的网页

没有样式表时,如果我想更新整个站点中所有主体文本的字体,我必须一页一页地修改每张网页。即便站点用数据库提供服务,我仍然需要更新所有的模板, 而且更新每一模板中每一个实例实例的 <FONT FACE>。样式表的主旨就是将格式和结构分离。 利于样式表,我可以将站点上所有的网 页都指向单一的一个CSS文件,我只要 修改CSS文件中某一行,那么整个站点 都会随之发生变动。

浏览器将成为你更友好的界面

不象其它的的网络技术,样式表的代码 有很好的兼容性,也就是说,如果用户 丢失了某个插件时不会发生中断,或者 使用老版本的浏览器时代码不会出现杂 乱无章的情况。 只要是可以识别串接样式表的浏览器就 可以应用它。

22. 要使表格的边框不显示,应设置border的值是( B )

A. 1; B. 0; C. 2; D. 3

23. 如果要在表单里创建一个普通文本框,以下写法中正确的是( A )

A. <INPUT>; B. <INPUT type="password">;

C. <INPUT type="checkbox">; D. <INPUT type="radio">

24. 以下有关按钮的说法中,错误的是( B )

A. 可以用图像作为提交按钮; B. 可以用图像作为重置按钮;

C. 可以控制提交按钮上的显示文字; D. 可以控制重置按钮上的显示文字。

<input type="image" src="pic.jpg" onclick="fangfa();"/>

function fangfa(){

document.formname.submit();

document.formname.reset();

}

码输入框是一种特殊的文本域,主要用于输入一些保密的信息。当网页浏览者输入文本时,显示的是黑点或者其他符号,这样就提高了输入文本的安全性。代码格式如下。

<input type="password" name="..." size="..." maxlength="...">

其中type="password"定义密码框;name属性定义密码的名称,要保证唯一性;size属性定义密码框的宽度,单位是单个字符宽度;maxlength属性定义最多输入的字符数。

(1)编写代码如下图所示,在<body>标签中加入以下代码。

(2)在浏览器中打开文件,预览效果图如下所示,输入用户名和密码时可以看到密码以黑点的形式显示。