WEB安全

深入分析.NET应用程序SQL注入【危害】

字号+ 作者:0nise 来源:i春秋社区 2016-11-25 09:38 我要评论( )

作者:0nise 时间:2016年8月11日 14:22:55 社区:i春秋 前言 不管 是用什么语言编写WEB应用程序,他们都或多或少有一些地方存在漏洞。如果你想知道漏洞的运行原理......

作者:0nise
时间:2016年8月11日 14:22:55
社区:i春秋
前言
不管是用什么语言编写WEB应用程序,他们都或多或少有一些地方存在漏洞。如果你想知道漏洞的运行原理,和防御方案,那么请看完本篇文章。
目录
第一节 注入攻击原理及防御
         1.1、什么是SQL注入
         1.2、SQL注入演练
         1.3如何防御SQL注入
正文
第一节 注入攻击原理及防御
1.1、什么是SQL注入
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
1.2、SQL注入演练
Servlet普及
   1.Servlet简介
    Servletsun公司提供的一门用于开发动态web资源的技术。
    Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
    1、编写一个Java类,实现servlet接口。
    2、把开发好的Java类部署到web服务器中。
    按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
   2.Servlet的运行过程
       Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
      ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第步,否则,执行第步。
      装载并创建该Servlet的一个实例对象。
      调用Servlet实例对象的init()方法。
      创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servletservice()方法并将请求和响应对象作为参数传递进去。
     ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servletdestroy()方法。
   
  3.Servlet常用方法
    doPost() 方法
  当一个客户通过 HTML 表单发出一个 HTTP POST 请求时,doPost() 方法被调用。与 POST 请求相关的参数作为一个单独的 HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时,应该使用 doPost() 方法。
   doGet() 方法
当一个客户通过 HTML 表单发出一个 HTTP GET 请求或直接请求一个 URL 时,doGet() 方法被调用。与 GET 请求相关的参数添加到 URL 的后面,并与这个请求一起发送。当不会修改服务器端的数据时,应该使用 doGet() 方法。
我们来看一段JSP代码中的【登陆验证
login.jsp核心代码

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<form action="UserServlet?opr=login" method="post">
 <table>
        <tr>
        <td>用户名:</td>
        <td><input type="text" name = "name"></td>
        </tr>
        <tr>
        <td>密码:</td>
        <td><input type="password" name = "pwd"></td>
        </tr>
        <tr>
        <td colspan="2"><input type="submit" value="登陆" /> </td>
        </tr>
        </table>
</form>

UserServlet核心代码
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
 *        doGet()
 */
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
  
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String opr = request.getParameter("opr");
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
BaseDao baseDao = new BaseDao();
admin user = new admin();
user.setName(name);
user.setPass(pwd);
if(opr.equals("login")){
String sql = "SELECT id,name,pass FROM [admin] WHERE name = '"+user.getName()+"' AND pass = '"+user.getPass()+"'";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
admin admin = null;
try {
conn = baseDao.getConn();
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
while(rs.next()){
admin = new admin();
admin.setId(rs.getInt("id"));
admin.setName(rs.getString("name"));
admin.setPass(rs.getString("pass"));
}
} catch (Exception e) {
e.printStackTrace();
}
if(admin != null){
out.print("登陆成功,欢迎"+admin.getName());
}
}
out.flush();
out.close();
}
/**
 * doPost()
 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

我们来构造登陆代码
用户名:
[Java] 纯文本查看 复制代码
?
1
’ or 1=1 --

密 码:
[Java] 纯文本查看 复制代码
?
1
123


然后通过断点捕获的SQL执行语句

[SQL] 纯文本查看 复制代码
?
1
SELECT id,name,pass FROM [admin] WHERE name = '' or 1=1 --' AND pass = '123'


相关的代码代码剖析
传送门:http://bbs.ichunqiu.com/thread-7636-1-1.html
1.3、SQL注入防御方案
预编译语句集,通过setting方法对参数进行赋值
UserServlet核心代码

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 *        doGet()
 */
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
  
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
String opr = request.getParameter("opr");
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
BaseDao baseDao = new BaseDao();
admin user = new admin();
user.setName(name);
user.setPass(pwd);
if(opr.equals("login")){
String sql = "SELECT id,name,pass FROM [admin] WHERE name = ? AND pass = ?";
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
admin admin = null;
try {
conn = baseDao.getConn();
stmt = conn.prepareStatement(sql);
stmt.setString(1, user.getName());
stmt.setString(2, user.getPass());
rs = stmt.executeQuery();
while(rs.next()){
admin = new admin();
admin.setId(rs.getInt("id"));
admin.setName(rs.getString("name"));
admin.setPass(rs.getString("pass"));
}
} catch (Exception e) {
e.printStackTrace();
}
if(admin != null){
out.print("登陆成功,欢迎"+admin.getName());
}else{
out.print("登陆失败!");
}
}
out.flush();
out.close();
}        /**
 * doPost()
 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

  构造登陆代码

    用户名:
[Java] 纯文本查看 复制代码
?
1
’ or 1=1 --

    密  码:
[Java] 纯文本查看 复制代码
?
1
123




然后通过断点捕获的SQL执行语句

[SQL] 纯文本查看 复制代码
?
1
SELECT id,name,pass FROM [admin] WHERE name = ? AND pass = ?

我们可以发现我们的SQL语句跟我们原来构造没有发生任何变化,从而避免了SQL注入的发生!
    如果你觉得SQL注入不重要那么请看这里
    传送门:http://bbs.ichunqiu.com/thread-8005-1-1.html

本文来自: 蜗蜗侠's Blog-关注网络安全 http://blog.icxun.cn/Web/258.html

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 移位溢注:告别依靠人品的偏移注入

    移位溢注:告别依靠人品的偏移注入

    2017-03-09 14:12

  • ZABBIX SQL注入

    ZABBIX SQL注入

    2016-12-24 14:47

  • 浅谈sql注入中的Post注入

    浅谈sql注入中的Post注入

    2016-11-25 10:17

  • mysql注入点的另类利用

    mysql注入点的另类利用

    2016-11-25 09:54

网友点评
暂时未开启评论功能~