当前位置: 首页 > 图文教程 > 数据库 > MSSQL > 有孔就入 SQL Injection的深入探讨

MSSQL
如何在 SQL SERVER 中快速有条件删除海量数据
Transact_SQL 小手册
一个过滤重复数据的 SQL 语句
MS-SQL Server 2005 其中三个版本的比较
SQL Server 的 SQL 语句导入导出大全
一些 T-SQL 技巧
显示 Sql Server 中所有表中的信息
MS-SQL Server 中单引号的两种处理方法
sql数据库不能直接用instr函数
MDF文件在SQL Server中的恢复技术
SQL Server 中调整自增字段的当前初始值
如何创建SQL Server 2000故障转移群集
SQL Server连接失败错误及解决
最长用最基本的MSSQL数据库备份与还原
清除SQLServer日志的两种方法
如何强制删除或恢复SQLServer正在使用的数据库
如何恢复数据库备份到一个已存在的正在使用的数据库上
设定sql server定期自动备份数据库
xp_cmdshell开启与关闭
更改SQL Server更改当前数据库的所有者:sp_changedbowner

MSSQL 中的 有孔就入 SQL Injection的深入探讨


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 40 ::
收藏到网摘: n/a

 

  SQL Injection这个话题越来越热了,很多的论坛和hack站点都或多或少地在谈论这个问题,当然也有很多革命前辈写了N多的关于这方面的文章,所利用的也是许多知名的程序,比如动网,尘缘雅境,而我们也可以拿到免费的程序来看其中的漏洞和数据库的结构,从中来达到注入的目的,不过如果是别人自己写的程序,那么我们就不知道他的源代码,更不知道他的数据库结构(数据表名和其中的字段名),就算有个变量未过滤提交到数据库去,我们也是无从对其下手的,只能利用通过猜解他的数据库结构来构造相应的SQL语句,那么是不是就到此为止,能猜到多少是多少呢?没有做不到的,只有想不到的,我相信这篇文章对研究SQL Injection朋友来说,应该会有所启发。

  一、发现漏洞,常规注入

  最近帮我们的站增加音乐,虽然本地的电信的音乐资源库非常丰富,但是缺少有关歌手和专辑的资料,所以到网上去闲逛找点有用的图片和歌手简介,通过百度搜索到了一个mp3的音乐超市,里面的资料还是比较丰富的,拷贝的同时顺手在他的Specialid=1817后面加了一个(单引号),我突然眼前一亮:

Microsoft OLE DB Provider for SQL Server 错误 80040e14
字符串 之前有未闭合的引号。
/showspecial.asp,行13 

  Specialid没有过滤掉单引号就直接用到SQL语句中去了,而且是SQL SERVER版本的,漏洞的可利用性极大,可不能就此放过这么好的练兵机会,接着换;(分号)提交进去,居然页面正常出来了,说明该变量也没有过滤掉;号,到这里,我们就可以对此进行SQL渗透了,按照常规的步骤:

  1、提交http://********/showspecial.asp?Specialid=1817;use master;--

  注:--的作用是注释掉程序中后面的SQL语句,以防对我们构造的语句有影响,比如order by..

  出现

Microsoft OLE DB Provider for SQL Server 错误 80040e21
多步 OLE DB 操作产生错误。如果可能,请检查每个 OLE DB 状态值。没有工作被完成。
/showspecial.asp,行13 

  想在他的数据库里增加一个管理员是不可能了,我们再换一种方法

  2、提交http://********/showspecial.asp?Specialid=1817 and 1<>(select count(id) from [user])

  这一句的意思是猜猜看是不是存在一个名为user的表和他里面有没有id这个字段

  一般来说:

  如果不存在该表的话,会出现

Microsoft OLE DB Provider for SQL Server 错误 80040e37
对象名 user 无效。
/showspecial.asp,行13 

  不存在该字段的话,会出现

Microsoft OLE DB Provider for SQL Server 错误 80040e14
列名 id 无效。
/showspecial.asp,行13 

  注:一般来说,第一步是猜一些公共的表,这里所指的公共表的意思是大多数的程序员在写设计数据库结构的时候会用到的常用的表和字段,比如新闻的news表中的编号字段id,标题字段title,用户表user或者user_data中的编号字段id,用户名字段username,当然你也可以在该站点的登陆界面看他的原代码,找到用户名和密码的表单的name值,那个也经常会是表字段名的真实值,如<INPUT type=text name=username size=15>

  很幸运,果然存在user表和id字段

  3、通过提交http://********/showspecial.asp?Specialid=1817 and 1<>(select count(username) from [user])

  这里的username是根据登陆框的表单名去猜的,恰好存在该字段。于是在该站注册了一个用户名为rrrrr的用户,作为注入的平台,得到我的用户名的id值103534

  4、继续猜下去,这里我还是利用的他程序中的表单名,提交:

http://********/showspecial.asp?Specialid=1817 and 1<>(select count(email) from [user])

  也存在,好了,到这里,我们的平台已经搭建好了。

  二、深入研究,让SQL自己招数据库结构

  很多时候,我们只能猜到大家比较熟用的表名,如果是非原程序公开下载的,我们很猜到他的真实数据库结构,有时候猜半天都猜不到,令人很郁闷,那么该如何拿到他的表结构呢?我们知道SQL SERVER的每一个数据库都会有用户表和系统表,根据SQL SERVER的联机帮助描述是系统表sysobjects:在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中占一行,那么也就是说当前数据库的表名都会在该表内有存在,(对象名 admin 无效。大家可以看到上面出现的报错把表名描述成对象)。

  我们要用的是其中的3个,描述如下(详细的见SQL SERVER的联机帮助):

   name 数据表的名字
   xtype 数据表的类型 u为用户表
   id 数据表的对象标志
   status 保留字段,用户表一般都是大于0的

  在查询分析器执行以下SQL语句(以我本地的数据库为例子)

select top 1 name from sysobjects where xtype=u and status>0

  我们马上就可以得到该数据