java jsp 木马_JSP安全开发之XSS漏洞详解

本文详细介绍了XSS跨站脚本攻击的原理、危害以及在JSP环境下的实战演练,包括存储型XSS的利用。同时,展示了如何通过EL表达式和JSTL标签库进行有效的防御措施。
摘要由CSDN通过智能技术生成

前言

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

正文

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

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

2.XSS的危害是什么?

实验一:

0x00构造代码

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

My JSP 'index.jsp' starting page

//设置编码

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);

}

%>

我是内容

0x01环境布局

0x02漏洞演练

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

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

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

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

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

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

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

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

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

提前放了一个MD5.exe文件

访问:http://localhost:8080/XSS/index.jsp?opr=

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

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

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

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

实验二:

前言:

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

0x00构造代码

数据库部分

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 GetComment(){

//SQL语句

String sql = "SELECT CID,CName,CContext FROM Comments";

List list = new ArrayList();

//数据库连接对象

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("");

}else{

out.print("");

}

}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

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

My JSP 'comment.jsp' starting page

request.setCharacterEncoding("UTF-8");

if(request.getAttribute("all") == null){

request.getRequestDispatcher("CommentServlvet?opr=all").forward(request, response);

}

%>

List list = (List)request.getAttribute("all");

for(int i = 0; i < list.size(); i++ ){

%>

}

%>

昵称:

0x01漏洞实验

root@1~#

我们在留言板留言:

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

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

root@2~#

我们在留言板留言:

文件写入成功。

root@3~#

留言内容:

[code][code]

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

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

3.XSS防御方案

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

EL表达式+JSTL标签库

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

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

实验一防御代码:

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

My JSP 'index.jsp' starting page

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);

%>

}

%>

我是内容

实验二防御代码:

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

My JSP 'comment.jsp' starting page

request.setCharacterEncoding("UTF-8");

if(request.getAttribute("all") == null){

request.getRequestDispatcher("CommentServlvet?opr=all").forward(request, response);

}

%>

昵称:

结束语

技术无黑白,专研甚好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值