XSS攻击常识及实战

什么是XSS?

XSS全称是Cross Site Scripting(为了和CSS进行区分,就叫XSS)即跨站脚本,当目标网站目标用户浏览器渲染HTML文档的过程中,出现了不被预期的脚本指令并执行时,XSS就发生了

XSS分类

XSS有三类:反射型XSS(非持久型)、存储型XSS(持久型)和DOM XSS

反射型XSS

发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS代码随响应内容一起传回给浏览器,最后浏览器解析执行XSS代码。这个过程像一次反射,所以称反射型XSS。
一个简单的例子:


echo $_GET['x'];
?>

如果输入x的值没有经过任何过滤直接输出,假设提交链接为:

http://www.foo.com/xss/reflect.php?x=

则alert()函数会在浏览器访问时触发

存储型XSS

存储型XSS和反射型XSS的差别仅在于,提交的代码会存储在服务器端(数据库、内存、文件系统等),下次请求目标页面时不用再提交XSS代码。最典型的例子就是留言板XSS,用户提交一条包含XSS代码的留言存储到数据库,目标用户查看留言板时,那些留言就会从数据库中加载出来并显示,于是出发了XSS攻击

DOM XSS

DOM XSS和反射型XSS、存储型XSS的区别在于DOM XSS代码并不需要服务器参与,出发XSS靠的是浏览器的DOM解析,完全是客户端的事情
www.xss.com/domxss.html 代码如下:


触发方式为:www.xss.com/domxss.html#alert(1) 这个URL#后的内容是不会发送到服务器端的,仅仅在客户端被接收并执行,常见的输入点有:

document.URL
document.URLUnencoded
document.localtion
document.referrer
window.location
window.name

实验一

1.构造代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>




My JSP 'xss_test.jsp' starting page







	<%
		String str = request.getParameter("name");
		out.print(str);
	%>


2.漏洞演练

首先访问:http://localhost:8080/jsp/user/xss_test.jsp?name=小明
XSS攻击常识及实战_第1张图片
接着我们试着加载一个js脚本看看,访问:http://localhost:8080/jsp/user/xss_test.jsp?name=

上面我都是用的Firefox或者chrome,但是这个只能用IE,因为只有IE才有ActiveXObject这个对象,而且访问之前要去IE的Internet选项里把安全级别调成很低,具体来说就是各种设置全部启用
XSS攻击常识及实战_第2张图片
既然连本地文件都可以打开,那么远程木马,写入文件?自己想象…

实验二

大部分网站都会和数据库打交道,XSS漏洞如果出现在这些网站会怎么样?

1.构造代码

user_insert.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>




My JSP 'user_insert.jsp' starting page








	

user_insert_action.jsp

<%@page import="java.sql.*"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>




user_insert_action.jsp







	<%
		//1.获取请求参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		String sex = request.getParameter("sex");
		String classes = request.getParameter("classes");
		String phone = request.getParameter("phone");
		String email = request.getParameter("email");
		String qq = request.getParameter("qq");
	%>
	<%
		//2.向数据库插入数据
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			//2.1 加载驱动类
			Class.forName("com.mysql.jdbc.Driver");
			
			//2.2 创建数据库连接
			String url = "jdbc:mysql://localhost:3306/jsp?useUnicode = true & characterEncoding = UTF-8";
			String userName = "root";
			String pwd = "root";
			conn = DriverManager.getConnection(url, userName, pwd);

			//2.3 创建预处理声明
			String sql = "insert into user" + "(username,password,name,sex,classes,phone,email,qq)"
					+ "values(?,?,?,?,?,?,?,?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, username);
			pstmt.setString(2, password);
			pstmt.setString(3, name);
			pstmt.setString(4, sex);
			pstmt.setString(5, classes);
			pstmt.setString(6, phone);
			pstmt.setString(7, email);
			pstmt.setString(8, qq);

			//2.4 向数据库发送sql语句
			int res = pstmt.executeUpdate();
			out.println(res);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			pstmt.close();
			conn.close();
		}
	%>


user.jsp

<%@page import="cn.edu.wic.jsp.bean.User"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>




JDBC








	<%
		List users = new ArrayList();
		Connection conn = null;
		PreparedStatement pstmt = null;//发送声明的对象
		ResultSet rs = null;//返货结果集的对象

		try {
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://localhost:3306/jsp?useUnicode=true&characterEncoding=UTF-8";
			String username = "root";
			String password = "root";
			conn = DriverManager.getConnection(url, username, password);
			pstmt = conn.prepareStatement("select * from user");
			rs = pstmt.executeQuery();
			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("username"));
				user.setPassword(rs.getString("password"));
				user.setName(rs.getString("name"));
			%>
	<%= user.getId() + ","%>
	<%= user.getUsername() + "," %>
	<%= user.getPassword() + "," %>
	<%= user.getName() %>
	
<% } } catch (Exception e) { e.printStackTrace(); } finally { if (pstmt != null) { try { pstmt.close(); } catch (Exception e) { } } if (conn != null) { try { conn.close(); } catch (Exception e) { } } } %>

用户从user_insert.jsp输入信息提交,然后跳转到user_insert_action.jsp,页面会显示数据库更改的条数信息,然后访问user.jsp查询数据库中的用户信息

2.漏洞实验

首先在user_insert.jsp输入信息
XSS攻击常识及实战_第3张图片
提交后跳转到user_insert_action.jsp,页面显示1,说明用户信息成功插入数据库
XSS攻击常识及实战_第4张图片
最后,访问user.jsp,XSS注入成功
XSS攻击常识及实战_第5张图片

上面实验一进行的实验都可以在这上面利用,比方说写入文件,或者实现页面跳转
XSS攻击常识及实战_第6张图片
信息提交成功
XSS攻击常识及实战_第7张图片
然后访问user.jsp,首先弹框1,没问题,点击确定后,就直接跳转到baidu的网站去了
XSS攻击常识及实战_第8张图片
如果我把弹框的信息删掉,只保留跳转,产生的效果就是只要有用户访问到user.jsp页面,就立马跳转到百度去了,类似DNS劫持

你可能感兴趣的:(渗透测试)