加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 数据库 > MsSql > 正文

SQL Server SQL数据库的高级sql注入的一些知识

发布时间:2020-05-25 06:49:49 所属栏目:MsSql 来源:互联网
导读:SQL Server SQL数据库的高级sql注入的一些知识

感兴趣的小伙伴,下面一起跟随脚本之家 jb51.cc的小编两巴掌来看看吧!

[概 要]
这篇文章讨论常用的"sql注入"技术的细节,应用于流行的Ms IIS/ASP/SQL-Server平台。这里探讨有关这种攻击各种可以注入程序访问数据和数据库防范的方法。这篇文章面向两种读者:一是基于数据库web程序开发人员和审核各种web程序的安全专家。
[介 绍]
结构化查询语言(SQL)是一种用来和数据库交互的文本语言SQL语言多种多样,大多的方言版本都共同宽松地遵循SQL-92标准(最新的ANSI标准[译者注:目前最新的是SQL-99])。SQL运行的典型的操作是“查询”,它是可以让数据库返回“查询结果记录集”的语句集合。SQL语句可以修改数据库的结构(用数据定义语言"DDL")和操作数据库里的数据(用数据操作语言"DML")。我们在这里着重讨论Transact-SQL(交互式SQL),应用于SQL-Server的SQL一种方言(非标准SQL)。如果攻击者可以插一系列的SQL语句进入应用程序的数据查询时,Sql注入攻击就可能发生。
一个典型的SQL语句是这样的:
select id,forename,surname from authors
这个查询语句将会从'authors'表中返回'id','forename'和'surname'列的所有行。返回的结果集也可以加以特定条件'author'限制:
select id,surname from authors where forename = 'john' and surname = 'smith'
注意这里很重要的一点是'john'和'smith'是被单引号引住的,假设'forename'和'surname'字段是来自于用户的输入,攻击者就可能通过输入非法字符串来对这个查询进行SQL注入:
Forename:jo'hn
Surname: smith
查询语句就会变成:
select id,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'(看上去是个数字)来选择一个用户,我们的查询可能会这样:
select id,surname from authors where id=1234
在这种情况下攻击者可以轻易的在数值输入后面添加SQL语句。在其他SQL方言中,使用着各种分隔符,比如MS Jet DBMS引擎,日期可以用'#'符号来分隔。
其次,避免单引号并不像开始我们想象的那样是必要的解决办法,原因下面讨论。
我们将以Active Server Pages(ASP)登陆页面为例子来详细说明,它访问一个Sql-Server数据库并且验证一个到我们假想的程序的访问。
这是用户填写用户名和密码的表单页面:

代码如下:

 
<HTML> 
<HEAD> 
<TITLE>Login Page</TITLE> 
</HEAD> 
<BODY bgcolor='000000' text='cccccc'> 
<FONT Face='tahoma' color='cccccc'> 
<CENTER><H1>Login</H1> 
<FORM action='process_login.asp' method=post> 
<TABLE> 
<TR><TD>Username:</TD><TD><INPUT type=text name=username size=100%width=100></INPUT></TD></TR> 
<TR><TD>Password:</TD><TD><INPUT type=password name=password size=100% 
width=100></INPUT></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_login.asp'中的创建'query string'的部分:
var sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
如果用户指定了下面这样的数据:
Username: '; drop table users--
Password:
'users'表会被删除,所有用户都不能登陆。'--'是Transact-SQL(交互式SQL)的单行注释符,';'标志着一个查询的结束另一个查询的开始。用户名最后的'--'用来使这个特殊的查询无错误结束。
攻击者只要知道用户名,就可以通过以下的输入以任何用户的身份登陆:
Username: admin'--
攻击者可以通过下面的输入以用户表里的第一个用户来登陆:
Username: ' or 1=1--
...更有甚者,攻击者通过以下的输入可以以任意虚构的用户登陆:
Username: ' union select 1,'fictional_user','somoe_password',1--
因为程序相信攻击者指定的常量是数据库返回的记录集的一部分。
[通过错误信息获取信息]
这个技术是David Litchfield在一次渗透入侵测试中首先发现的,后来david写了篇关于这个技术的文章,很多作者都参考过这篇作品。这里我们讨论“错误消息”技术潜在的机制,使读者可以充分理解它并且能灵活应用。
为了操作数据库里的数据,攻击者要确定某个数据库的结构。例如:我们的"user"表是用下面的语句建立的:

代码如下:

 
create table users( id int,username varchar(255),password varchar(255),privs int 
) 

并且插入了下面的用户:
insert into users values( 0,'admin','r00tr0x!',0xffff )
insert into users values( 0,'guest',0x0000 )
insert into users values( 0,'chris','password',0x00ff )
insert into users values( 0,'fred','sesame',0x00ff )
我们假设攻击者要为自己插入一个用户,如果不知道表的结构的话,他不可能成功。即使他运气好,'priv'字段的重要性还不清楚。攻击者可能插入'1',给自己在程序里添加了一个低权限的用户,而他的目标是管理员的权限。
对于攻击者来说幸运的是:如果程序返回错误(asp默认如此),攻击者可以猜测整个数据库的结构,读取ASP程序连接到SQL-Server的帐号权限内可以读取的任何值。
(下面给出的使用上面提供的示例数据库和asp脚本来说明这些技术怎样实现的)
首先,攻击者要确定查询的表名和字段名。要做到这点,攻击者可以使用'select'语句的'having'子句:
username: ' having 1=1 --
这会引起下面的错误(译者注:having字句必须和GROUP BY或者聚合函数一起配合使用,否则出错):

代码如下:

 
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'子句继续得到其他列名,如下:

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读