SQL注入
漏洞描述
Web程序中对于用户提交的参数未做过滤直接拼接到SQL语句中执行,导致参数中的特殊字符破坏了SQL语句原有逻辑,攻击者可以利用该漏洞执行任意SQL语句,如查询数据、下载数据、写入webshell、执行系统命令以及绕过登录限制等。
漏洞例子
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
如上,上述代码的功能为,当用户以get的方式传入参数时,赋值给 $id ,然后 $id直接作为参数放入SQL语句中执行,这种情况下就是存在SQL注入的例如我们输入
哪些数据库可以通过SQL注入提到主机权限
高风险数据库
- Microsoft SQL Server
 
- 通过xp_cmdshell存储过程执行系统命令
 - 使用OLE自动化过程执行命令
 - 通过SQL Server Agent jobs执行系统命令
 
- MySQL
 
- 在特定配置下使用INTO OUTFILE写入webshell
 - 通过LOAD_FILE()读取系统文件
 - 如果以root权限运行,可能通过UDF(用户定义函数)执行系统命令
 
- PostgreSQL
 
- 通过COPY命令读写文件系统
 - 使用大对象函数访问文件系统
 - 通过PL/pgSQL或PL/Perl等扩展执行系统命令
 
- Oracle
 
- 通过Java存储过程执行系统命令
 - 使用DBMS_SCHEDULER创建作业执行命令
 - 通过外部表访问文件系统
 
修复建议
代码层最佳防御sql漏洞方案:使用预编译sql语句查询和绑定变量。
(1)使用预编译语句,使用PDO需要注意不要将变量直接拼接到PDO语句中。所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎所有的数据库系统都提供了参数化SQL语句执行接口,使用此接口可以非常有效的防止SQL注入攻击。
(2)对进入数据库的特殊字符 ’”<>&\*;进行转义处理,或编码转换。
(3)确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
(4)数据长度应该严格规定,能在一定程度上防止比较长的SQL注入语句无法正确执行。
(5)网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
(6)严格限制网站用户的数据库的操作权限,给此用户提供仅仅能够满足其工作的权限,从而最大限度的减少注入攻击对数据库的危害。
(7)避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
(8)过滤危险字符,例如:采用正则表达式匹配union、sleep 、and、select、load
_file等关键字,如果匹配到则终止运行。
绕过手段
使用大小写绕过,双写绕过,URL编码绕过、使用URL编码绕过、使用添加一个闭合方式绕过,逻辑运算绕过、使用宽字符绕过(前提PHP使用GBK编码)