谈谈PHP网站的防SQL注入

SQL(Structured Query Language)即结构化查询语言。SQL 注入,就是把 SQL 命令插入到 Web 表单的输入域或页面请求参数的查询字符串中,在 Web表单向 Web 服务器提交 GET 或 POST 请求时,如果服务器端未严格验证参数的有效性和合法性,将导致数据库服务器执行恶意的 SQL 命令。

SQL 注入攻击的过程:

(1)判断 Web 应用是否可以进行 SQL 注入。

(2)寻找 SQL 注入点。

(3)猜解用户名和密码。

(4)寻找 Web 系统管理后台入口。

(5)实施入侵和破坏。

一、 SQL注入漏洞测试工具

1. Sqlmap

Sqlmap 是一个自动化的 SQL 注入工具, 其主要功能是扫描,发现并利用给定的 URL 的 SQL 注入漏洞,日前支持的数据库是MS SQL Server, MySQL, oracle 和 postgresql。 SQLMAP 采用四种独特的 SQL 注入技术,分别是盲推理 SQL 注入, UNION 查询 SQL 注入,堆查询和基于时间的 SQL 盲注入。其广泛的功能和选项包括数据库指纹,枚举, 数据库提取,访问目标文件系统,并在获取完全操作权限时实行任意命令。

1.1 sqlmap 常用命令介绍

Target(目标):至少需要设置其中一个选项,设置目标 URL。

-d DIRECT 直接连接到数据库。

-u URL,--url=URL 目标 URL。

Request(请求):这些选项可以用来指定如何连接到目标 URL。

――data=DATA 通过 POST 发送的数据字符串。

――cookie=COOKIE HTTP Cookie 头。

Optimization(优化):这些选项可用于优化 sqlmap 的性能。

-o 开户所有优化开关

--threads=THREADS 最大的 HTTP( S)请求并发量(默认为 1)。

Injection(注入):这些选项可以用来指定测试哪些参数。

-p TESTPARAMETER 可测试的参数。

--prefix=PREFIX 注入 payload 字符串前缀。

2 SQLIer

SQLIer可以找到网站上一个有SQL注入漏洞的URL,并根据有关信息来生成利用SQL注入漏洞,但它不要求用户的交互。通过这种方法,它可以生成一个UNION SELECT查询,进而可以强力攻击数据库口令。这个程序在利用漏洞时并不使用引号,这意味着它可适应多种网站。

SQLIer通过“true/false” SQL注入漏洞强力口令。借助于“true/false” SQL注入漏洞强力口令,用户是无法从数据库查询数据的,只能查询一个可返回“true”、“false”值的语句。

据统计,一个八个字符的口令(包括十进制ASCII代码的任何字符)仅需要大约1分钟即可破解。

2.1 其使用语法如下,sqlier [选项] [URL]

其选项如下:

-c :[主机] 清除主机的漏洞利用信息

-s :[秒]在网页请求之间等待的秒数

-u:[用户名]从数据库中强力攻击的用户名,用逗号隔开

-w:[选项]将[选项]交由wget

此外,此程序还支持猜测字段名,有如下几种选择:

--table-names [表格名称]:可进行猜测的表格名称,用逗号隔开

--user-fields[用户字段]:可进行猜测的用户名字段名称,用逗号隔开

--pass-fields [口令字段]:可进行猜测的口令字段名称,用逗号隔开

3 Pangolin

Pangolin是一款帮助渗透测试人员进行SQL注入(SQL Injeciton)测试的安全工具。Pangolin与JSky(Web应用安全漏洞扫描器、Web应用安全评估工具)都是NOSEC公司的产品。Pangolin具备友好的图形界面以及支持测试几乎所有数据库(Access、MSSql、MySql、Oracle、Informix、DB2、Sybase、PostgreSQL、Sqlite)。Pangolin能够通过一系列非常简单的操作,达到最大化的攻击测试效果。它从检测注入开始到最后控制目标系统都给出了测试步骤。Pangolin是目前国内使用率最高的SQL注入测试的安全软件。

二、 防范SQL注入攻击

1. 对输入的数据进行过滤(过滤输入)

a) 对于动态构造SQL查询的场合,可以使用替换字符和删除特殊字符的方法。

b) 检查用户输入的合法性,防止非法数据输入。数据检查应当在客户端和服务器端执行。执行服务器端验证,是为了弥补客户端验证机制的不足。

c) 限制表单或查询字符串输入的长度范围。

d) 加密用户登录名称、 密码等数据。

2. 对发送到数据库的数据进行转义(转义输出)

尽量使用为自定义数据库设计的转义函数。如果没有,使用函数addslashes()是比较好的方法,对字符串型参数使用mysql_real_escape_string函数、对数字型参数使用intval,floatval函数强制过滤则更好。当所有用于建立一个 SQL 语句的数据被正确过滤和转义时,实际上也就避免了 SQL注入的风险。

3. 参数化查询

参数化查询(Parameterized Query)指的是 Web 程序在实施数据库查询时,在需提交数值或数据的地方避免直接赋值,而是采用参数来传递给值。

使用参数化查询技术,数据库服务器不会将参数的内容视为 SQL 指令的一个组成部分来处理,在数据库系统完成对 SQL 指令的编译后,再载入参数运行。因此,即使参数中含有指令,也不会被数据库编译运行。

4. 使用存储过程

存储过程存储在数据库系统内部, Web 应用程序通过调用来执行存储过程, 该技术允许用户定义变量、有条件执行以及其它丰富的编程功能。程序开发者利用存储过程事先构建好的 SQL 查询语句代码,然后在使用中通过参数传输数值。存储过程在使用时起到三点安全作用:首先,存储过程执行前要进行预编译,编译出错不予执行;其次,对于数据的授权访问是基于存储过程而不是直接访问基本表,攻击者无法探测到 select 语句;最后,存储过程可以指定和验证用户提供的值类型。

但是,存储过程也存在一定的局限,如果存储过程中执行的命令是拼接字符串,则会存在被注入攻击的隐患。此外,存储过程并不支持所有的数据库平台。

5. 使用PDO连接数据库

防止SQL注入最好的方法就是不要自己设置SQL 命令和参数,而是用PDO的prepare和bind,原理就在于要把SQL查询命令和传递的参数分开。使用prepare的时候,DB server会把SQL语句解析成SQL命令。使用bind的时候,只是动态传递DB Server解析好的 SQL 命令。

三、 总结

除了以上介绍的防范SQL注入攻击方法之外,还有URL重置技术、页面静态化、屏蔽出错信息、使用web应用防火墙等措施。通过以上措施,SQL注入才能防患于未然。