浅析JSP入侵中的SQL注入之1'or'1'='1
http://www.176ku.com/wenzhai/ruqin/200905/10630.html
BY:黑色之恋 【B.H.S.T】
浅析JSP入侵中的SQL注入之1'or'1'='1
我们在入侵ASP站的时候,会遇到很多由于代码过滤不完全,导致的万能密码入侵,也就是我们常见的'or'='or'入侵
在JSP中呢,这种情况也有,下面我们就从入侵实战开始到本地搭建简单分析下产生的原因,以及简单的2种修复方法
(一)入侵实战:
至此完成一个简单的攻击
(二)本地搭建测试
下面我们本地简单构造一下这样的环境
创建3个JSP页
login.jsp(登录页)
loginch.jsp(验证处理页)
wel.jsp(登录成功后转到页)
代码分别如下
login.jsp
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head></head>
<body bgcolor=gray>
<center> 用户登录<br> <hr>
<form action="loginch.jsp" method="post">
用户名:<input type="text" name="username"><br>
密 码:<input type="password" name="passwd"><br>
<input type="submit" value="登录">
<input type="reset" value="重置">
</form>
loginche.jsp
<%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="gb2312"%>
<html>
<head>
<title>loginch.jsp</title>
</head>
<body>
<%
String u=request.getParameter("username");
String p=request.getParameter("passwd");
//======================MSSQL连接实现=============================
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_net";连接URL
String userName = "sa";//连接用户
String password="forhack";连接密码
Connection ct=DriverManager.getConnection(url,userName,password);//实现连接
//创建statement
Statement sm=ct.createStatement();
//执行查询
ResultSet rs=sm.executeQuery("select * from tb_usertable where name='"+u+"'and password='"+p+"'");
if(rs.next())
{
//查询到就转到成功页面
response.sendRedirect("wel.jsp");
}else
{
//说明不存在用户,转到登陆页面
response.sendRedirect("login.jsp");
}
%>
</body>
</html>
wel.jsp
<%@ page language="java" pageEncoding="gb2312"%>
<html>
<head>
<title>wel.jsp</title>
</head>
<body>
<h1>恭喜你登录成功</h1>
<a href="login.jsp">返回登录</a>
</body>
</html>
这三个页面分别建立,下面我们简单分析下
产生1'or'1'='1注入的原因
我们来看下验证页面loginch.jsp里面的SQL查询语法
select * from tb_usertable where name='"+u+"'and password='"+p+"'"
如果我们把[' or '1' = '1]作为password传入进来.用户名随意,看看会成为什么?
select * from tb_usertable where name='"+HEHE+"'and password='1'or'1'='1'
这样构造成的SQL语句中因为'1'='1'肯定成立,所以可以任何通过验证
打开我们的SQL查询分析器看下
查询出了用户名和密码,也就是说可以通过验证,也就实现了所谓的SQL注入攻击
(三)简单修复
当然知知道了这样的注入产生的原因后,我们就可以通过修改代码来实现防止这样攻击的方法
下面简单说2种,网上有很多防止这样攻击的方法
(1)
首先就是用PreparedStatement来替代Statement
PreparedStatement 接口继承 Statement,PreparedStatement 实例包含已编译的 SQL 语句。这就是使语句“准备好”。包含于 PreparedStatement 对象中的 SQL 语句可具有一个或多个 IN 参数。IN参数的值在 SQL 语句创建时未被指定。相反的,该语句为每个 IN 参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX 方法来提供。 由于 PreparedStatement 对象已预编译过,所以其执行速度要快于 Statement 对象。因此,多次执行的 SQL 语句经常创建为 PreparedStatement 对象,以提高效率。
下面我们来通过修改loginch.jsp代码来实现防止攻击的目的
<%@ page language="java" import="java.util.*,java.sql.*" pageEncoding="gb2312"%>
<html>
<head>
<title>loginch.jsp</title>
</head>
<body>
<%
String u=request.getParameter("username");
String p=request.getParameter("passwd");
//======================MSSQL连接实现=============================
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_net";
String userName = "sa";
String password="forhack";
//建立连接
Connection ct=DriverManager.getConnection(url,userName,password);
String sql="select * from tb_usertable where name=? and password=?";
//创建PreparedStatement
PreparedStatement ps=ct.prepareStatement(sql);
ps.setString(1,u);//设置PS内容
ps.setString(2,p);
//执行查询
ResultSet rs=ps.executeQuery();
if(rs.next())
{
//查询到就执行转到WEL.JSP
response.sendRedirect("wel.jsp");
}else
{
//反之说明不存,返回登录
response.sendRedirect("login.jsp");
}
%>
</body>
</html>
这样修改代码后不仅效率提高,同时也达到了防止攻击的目的
(2)
修改SQL语句
<%
String u=request.getParameter("username");
String p=request.getParameter("passwd");
//======================MSSQL连接实现=============================
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://127.0.0.1:1433;databaseName=db_net";
String userName = "sa";
String password="forhack";
Connection ct=DriverManager.getConnection(url,userName,password);
//创建statement
Statement sm=ct.createStatement();
//执行查询
ResultSet rs=sm.executeQuery("select password from tb_usertable where
name='"+u+"'");
if(rs.next())
{
//说明用户存在并验证密码
if(rs.getString(1).equals(p))
{
response.sendRedirect("web.jsp");
}else
{
//密码不正确
response.sendRedirect("login.jsp");
}
}else
{
//说明不存在用户
response.sendRedirect("login.jsp");
}
%>