什么是SQL注入
简单来说就是把输入的SQL语句和源码进行拼接,既能执行源码,又可以使拼接的SQL语句正常执行,最终实现到对网站、数据库的操作
常见的联合查询要使用到的SQL语句
mysql>show databases; #查看当前数据库所有的库名
show tables; #查看表名
desc users; #查看表结构
select * from users; #查看所有列
select user,password from users; #查看指定列的数据
select * from users where user='admin'; #查看指定行的数据
select * from users where (id>5 or user='admin'); #使用逻辑操作符号
SQL注入的流程
- 判断是否存在注入点,注入类型
- 猜解字段数
- 确定显示位
- 查看数据库名、表名、列名
- 查看数据
以dvwa低等级为例进行演示SQL联合查询
判断是否存在注入点,注入类型
可以得到正常显示的页面,给后面添加单引号尝试能否得到输出
显示报错,单引号没有结束,说明识别了单引号,给后面添加语句
页面有显示,但是并不知道and语句是否执行,所以尝试and语句不成立
没有结果输出,说明执行了and语句。由此得出结论,这里存在注入,因为语句拼进了源码,而且也执行了语句。且用到了特殊字符,所以是字符型注入猜解字段数,使用order by x#
依次从1到3,3的时候报错,说明字段数是2确定显示位
得出库名是dvwa,版本号是5.5.53获取数据库的库名、表名、列名
得到两个表名guestbook和users
得到字段名获取数据
得到user和password的数据其中 group_concat()这个函数是为了把返回的结果单行以逗号分割显示,如:
information_schema()是一个集合体
用法是:当不知道表名的时候,需要在information_schema().tables里面查找,然后再加上一个库名做范围,就可以精确查到某库的所有表名
当不知道字段名的时候,需要在information_schema().columns里面找,然后再加上表名做范围,就可以查询到所有该表名下的所有字段名
总结
SQL注入的原理:
把用户输入SQL语句和源码拼接,使得执行插入的sql语句,可以对数据库做一些操作
手工注入流程:
判断是否存在注入,注入什么类型
猜解sql查询语句中的字段数
确定显示位置
获取数据库的库名、表名、列名
获取数据
SQL注入确认:
id=1’ -------报异常
id=1’ and ‘1’=’1 ----------正常
id=1’ and ‘1’=’2 -----------异常
以上三步可以确定为有注入点,为字符型
1.id=1’ -------报异常
2.id=1 and 1=1 ----------正常
3.id=1 and 1=2 -----------异常
以上三步可以确定为有注入点,为数字型
id=1’ or ‘1’=’1 - —正常,也可以判定有注入点
危害:
恶意操作数据库
信息泄露
网页篡改
私自添加账号或删除账号
挂马
反弹shell,实现远程控制
防御手段:
过滤特殊字符、关键字、空格
PDO预编译,将用户输入内容和源码分开
站库分离
寻找SQL注入
在网站中寻找链接如:http://www.xxx.com/xxx.asp?id=xx
一些特殊情况:
1.如果过滤掉关键字,一般情况下只会过滤大写关键字或者小写关键字,那么就可以用大小写混合输入,如:SeLect代替select,SELECT。
2.如果过滤掉空格,则可以用+代替,或者%20
3.如果过滤掉一些字符,可以使用ASCII码代替,如U=chr(85),a=chr(97)