Web关于SQL Injection 的攻防

来源:互联网 发布:腾讯视频mac版有吗 编辑:程序博客网 时间:2024/06/01 21:14

这几日整理一些以前看过的网路文章,替一些比较冷门的站点做备份,也许以后会再阅读到


//

陈华 2008年9月12日

目标
• • • • • 1 什么是Sql 注入?

• • • • • 2 Sql注入的原理? 

• • • • • 3 Sql注入的一般形式? 

• • • • • 4 Sql注入的特点? 

• • • • • 5 Java关于Sql注入的防范?

1. 什么是Sql注入?
• 程序员在编写代码的时候,没有对用户输入数据的合法性 进行判断,使应用程序存在安全隐患。用户可以提交一段 数据库查询代码,根据具体情况进行分析,构造巧妙的 SQL语句,从而成功获取想要的数据,这就是所谓的SQL Injection,即SQL注入。

2. Sql注入的原理(Web)
• 通过向服务器提交自己伪装过的SQL命令,来获得响应, 进而通过服务器的响应来判断推测自己想要的数据。

3. Sql 注入的一般形式(Web)
• 1 通过表单提交数据,比如登陆 比如用户名,密码这样输入: UserName:Admin Password:123 or 1=1

• 2 通过URL连接的修改来注入。 ① http://www.19cn.com/showdetail.asp?id=49 ② http://www.19cn.com/showdetail.asp?id=49 and 1=1 ③ http://www.19cn.com/showdetail.asp?id=49 and 1=2 4 http://www.19cn.com/showdetail.asp?id=49 and (select count(*) from admin)>0

4. Sql注入的特点
• A SQL注入是从正常的WWW端口访问,而且表面看起来 跟一般的Web页面访问没什么区别,所以目前市面的防火 墙都不会对SQL注入发出警报。 • B 根据提交的SQl语句逐个得到: 数据库类型 ——系统用户表——表字段——用户名——密 码———获得管理员权限

判断能否经行Sql注入一
• 判断能否经行Sql注入? ① http://www.19cn.com/showdetail.asp?id=49 ② http://www.19cn.com/showdetail.asp?id=49 and 1=1 ③ http://www.19cn.com/showdetail.asp?id=49 and 1=2 1 正常显示(这是必然的,不然就是程序有错误了) 2 正常显示,内容基本与①相同 3 提示BOF或EOF(程序没做任何判断时)、或提示找 不到记录(判断了rs.eof时)

这表示是可以Sql注入的。 注入的。 这表示是可以 注入的

判断能否经行Sql注入二
① http://www.19cn.com/showdetail.asp?id=49 ② http://www.19cn.com/showdetail.asp?id=49 and 1=1 ③ http://www.19cn.com/showdetail.asp?id=49 and 1=2 ①同样正常显示, ②和③一般都会有程序定义的错误提示,或提示类型转换 时出错, 如果是这样就表示程序是不能注入的。

判断系统用什么样的数据库一
• A根据URL的连接判断语言 的连接判断语言,然后根据语言 的连接判断语言 根据语言 判读数据库,然后在推测服务器 推测服务器的原则。 判读数据库 推测服务器 • B根据目前的流行的语言和数据库的搭配 • A PHP+MySql+Apache • B Jsp+Oracle+Web服务器 • C Asp.net+SqlServer+IIS • D Asp+Access+IIS

判断系统试用什么样的数据库二
• 首先,根据语言来判断数据库,应为这样 的结合才能产生比较好的性能。

• 其次,根据Sql注入后的返回值来判断。

例子一
• http://www.19cn.com/showdetail.asp?id=49 and user>0 1 user是SQLServer的一个内置变量,它的值是当 前连接的用户名,类型为nvarchar。 2 拿一个nvarchar的值跟int的数0比较,系统会先 试图将nvarchar的值转成int型,当然,转的过程 中肯定会出。 SQLServer的出错提示是:将nvarchar值 ”abc” 转换数据类型为 int 的列时发生语法错误,abc正 是变量user的值,这样就拿到了数据库的用户名

例子一
• 3 另外: SQLServer的用户sa是个等同Adminstrators权 限的角色,拿到了sa权限,几乎肯定可以拿到主机的 Administrator了。上面的方法可以很方便的测试出是否是 用sa登录,要注意的是:如果是sa登录,提示是将”dbo” 转换成int的列发生错误,而不是”sa”。 • 如果服务器IIS不允许返回错误提示,那怎么判断数据库 类型呢?我们可以从Access和SQLServer和区别入手, Access和SQLServer都有自己的系统表,比如存放数据库 中所有对象的表,Access是在系统表[msysobjects]中, 但在Web环境下读该表会提示“没有权限”,SQLServer 是在表[sysobjects]中,在Web环境下可正常读取

例子一
• http://www.19cn.com/showdetail.asp?id=4 9 and (select count(*) from sysobjects)>0 • 如果返回值与 http://www.19cn.com/showdetail.asp?id=49 相同,那么就是SQlserver数据库。

例子二
• 在互联网上有这样一链接: http://www.930bobo.cn/Class.asp?ID=33 我们在后面加一个点: http://www.930bobo.cn/Class.asp?ID=33’ 得到如下结果。如下图:

例子二

例子二
• • • • • 结论: 1 此网站可以进行SQL注入,通过Web端。 2 这里可以看出它用的数据库是Access. 3 编程语言是ASP 4 服务器很可能就是IIS

例子二
• http://www.930bobo.cn/Class.asp?ID=33 and 1=1 语句更改成这样后

5. Java Sql注入的防范
• Java语言和数据库打交道的常用下面的方 法 • A JDBC • B Hibernate • C Ibatis

存在安全问题的代码
• public void execute(String user,String pass){ boolean foo=false; try{ Class.forName("com.mysql.jdbc.Driver"); Connection con=DriverManager.getConnection("jdbc:mysql://localhost/students","root",""); Statement stam=con.createStatement(); //存在注入攻击漏洞:select * from login where user='' or'x'='x' or 'x'='' and '1' ResultSet rs=stam.executeQuery("select * from login where user='" + user + "' and pass='"+ pass + "'"); while(rs.next()){ foo=true; } if(foo){ System.out.println("登陆成功 登陆成功"); 登陆成功 } else { System.out.println("用户名密码错误 用户名密码错误"); 用户名密码错误 } }catch(ClassNotFoundException e){ e.printStackTrace(); }catch(SQLException e){ e.printStackTrace(); }

问题
• 不安全因素:statement。。。应该用Preparedstatement 来代替statement,这样我们就可以使用占位符作为实参 来定义sql语句,从而避免sql注入的攻击。 • 我们在用hibernate等框架的时候(hql语句),避免sql注入 攻击也是一样的,关键是不要用string来构造sql语句,不 管什么框架,还是纯JDBC,只要用Preparedstatement就 OK

防御办法
• 1、PreparedStatement
用PreparedStatement String hql = "select count(*) from CpUser where ID=?..."; ps1.setString(1,userForm.getId());

• 2、正则表达式

• 3、字符串过滤

• 4、不安全字符屏蔽



原文地址:http://www.chinadmd.com/file/xtt3vorzazcx3sso33ecpszc_1.html

0 0