SQL Injection
SQL Injection,即SQL注入,是指攻击者通过注入恶意的SQL命令,破坏SQL查询语句的结构,从而达到执行恶意SQL语句的目的。SQL注入漏洞的危害是巨大的,尽管如此,SQL注入仍是现在最常见的Web漏洞之一。
手工注入思路
自动化的注入神器sqlmap固然好用,但还是要掌握一些手工注入的思路,下面简要介绍手工注入(非盲注)的步骤。
1.判断是否存在注入,注入是字符型还是数字型
2.猜解SQL查询语句中的字段数
3.确定显示的字段顺序
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.下载数据
在不知道MySQL数据如何设计的情况下,可以通过元数据库informatio_schema
,一步步将整个数据库内容窃取出来。
请登录MySQL数据库,并运行show databases;
命令,就可以获取所有数据库列表,如下图所示:
图片中标红色的数据库information_schema
就是元数据库,里面应用尽有。
我们所说的根就在SCHEMATA
表,它里面描述了整个MySQL 下所有数据库。
然后再利用TABLES
表,则可以看到数据下的表名,再利用COLUMNS
表,则可以看到每个表下的字段名。下面依次展示如何查看这些数据。
查看所有数据库
查看所有数据库
SCHEMATA
表描述所有数据库信息,只需标准的select语句:
SELECT * FROM information_schema.SCHEMATA
即可将该表的内容全部显示出来:
图中SCHEMA_NAME
字段为数据库名,从查询结果可以知该MySQL服务器有6个数据库。
查看表
有了数据库列表,就可以进一步查看某个数据库下所有表(当前也可以查看所有数据库下的所有表)。比如查看lyt_test数据库下的所有表,使用SQL语句:
SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'security'
查询结果如下图所示:
TABLE_NAME表示表名,左列TABLE_SCHEMA为数据库名,由于security数据库下只有*****这个表,所以输出结果只有8888列。
查看表中的所有字段
然后使用COLUMNS表可以查询表的所有字段信息,使用下面SQL语句可查询accounts表的所有字段名和类型:
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME = 'accounts'
查询出accounts表所有字段和类型信息如下图所示:
查看表中的所有记录
查看accounts表中的内容更是小菜一碟了,学过数据库的都知道SQL写成下面这样:
SELECT * FROM security.accounts
结果如下:
到这里相信已经学习如何从MySQL中窃取所有数据库内容了。
进入information_schema数据库,看看里面有哪些数据表,使用如下命令:
但该SQL能注入的部分只是WHERE
部分,而SELECT ... FROM ...
部分中的字段和表名却是无法注入的,那怎么可以将其它表的数据窃取出来呢?
那就是利用UNION语句。是的,标准SQL提供了UNION
语句,可以将两个SELECT
结果联合起来(即对两个SELECT结果作并集)。UNION
语句的语法如下:
SELECT column_name1(s) FROM table_name1
UNION
SELECT column_name2(s) FROM table_name2
没有拿到源代码,怎么知道SELECT * from userinfo
查询结果有多少列呢?
显然是不知道的,但可通过试探方法拿到这个数值:依次注入UNION SELECT 1, ... N
这样的语句来试探。先尝试SELECT 1
, 再SELECT 1,2, 然后SELECT 1,2,3,直到不运行出错为止。
总结
SQL注入爆数据库是这么容易的,但有几个必备条件
MySQL中出现一个元数据库information_schema,它描述整个MySQL服务器所有数据库->表->字段关系树
SQL语言提供了UNION语句,可以新增窃取其它数据合并到被注入SELECT结果
MySQL对SQL做扩展,提供注释符#,让注入可以为所欲为
防止SQL注入,我们需要注意以下几个要点:
永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
sql注入的检测方法一般采取辅助软件或网站平台来检测。