Préface
Bonjour à tous, un homme bon, c'est moi, je suis un homme bon, je suis -0nise. Sur les principales plateformes de rapports de vulnérabilité, nous voyons souvent les vulnérabilités XSS. La question est donc de savoir pourquoi ce type de vulnérabilité se produit-il? Comment réparer cette vulnérabilité?
texte
1.XSS? XSS? Qu'est-ce que c'est XSS?
XSS est également appelé script de site croisé. Je ne lui dirai pas qu'il s'appelait à l'origine CSS, mais pour ne pas se confondre avec les feuilles de style en cascade CSS que nous utilisons. CSS (attaque de script de site croisée), CSS (feuille de style en cascade) est idiot et ne peut pas faire la différence. C'est donc ce qu'on appelle XSS.
2. Quels sont les dangers du XSS?
Expérience 1:
Code de construction 0x00
<% @ Page Language = "Java" import = "java.util. *" Pageencoding = "utf-8"%> <% String path = request.getContextPath (); String basepath = request.getscheme () + ": //" + request.getServerName () + ":" + request.getServer () + path + "/";% "-//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" contenu = "keyword1, keyword2, keyword3"> <meta http-equiv = "description" content = "c'est ma page"> </ heading> <body> <div style = "margin: 0 auto"> <% request.SetcharAtterencoding ("utf-8"); // reçoit une chaîne de valeur entrante de l'utilisateur tmp = request.getParameter ("OPR"); // La valeur entrante par défaut est vide if (tmp == null) {out.print ("111"); } else {// transcoding string opr = new String (tmp.getBytes ("iso-8859-1"), "utf-8"); Out.print (OPR); }%> Je suis contenu </div> </body> </html>Disposition de l'environnement 0x01
0x02 Force de vulnérabilité
Nous visitons: http: // localhost: 8080 / xss / index.jsp? Opr = i% e6% 98% a5% e7% a7% 8b
Puis visitez: http: // localhost: 8080 / xss / index.jsp? Opr = 0nise
Enfin, nous avons découvert une "grande loi":
Imprimez la page à laquelle le paramètre OPR est égal. (Cela semble absurde)
Chargeons une image et voyons
Visite: http: // localhost: 8080 / xss / index.jsp? Opr =% 3cimg% 20src =% 221.png% 22% 3e% 3c / img% 3e
Étant donné que toutes les images peuvent être chargées, nos fichiers JS sont également chargés?
Visite: http: // localhost: 8080 / xss / index.jsp? Opr =% 3cscript% 3elert (/ 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? Alors, est-il possible de changer l'adresse après le saut?
Visitez: http: // localhost: 8080 / xss / index.jsp? Opr =% 3cscript% 3Elocation.href =% 27http: //bbs.icunqiu.com%27%3C/Script%3E
Puisque XSS peut charger JS, ouvrons-nous des choses locales via JS?
Mettez un fichier MD5.exe à l'avance
Visitez: http: // localhost: 8080 / xss / index.jsp? Opr = <script> var objshell = new activeXObject ("wscript.shell"); objshell.run ("g: /work/xss/webroot/md5.exe"); </ / script>
Étant donné que même les fichiers locaux peuvent être ouverts, un fichier distant distrant? Vous avez une parodie informatique? C'est lentement le quadrant. Je ne l'ai pas dit. . . . .
Tous les fichiers peuvent être ouverts, alors qu'en est-il de la rédaction de certains fichiers?
Visitez: http: // localhost: 8080 / xss / index.jsp? Opr =% 3cscript% 3evar% 20fso, tf; fso% 20 =% 20New% 20cactivexObject (% 22Script. 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 (); alerte (% 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
Grâce aux expériences ci-dessus, nous pouvons voir l'opération d'attribution des paramètres OPR. Si le paramètre OPR n'a aucune valeur, il ne peut pas être exécuté. La personne attaquée doit accéder à l'attaquant conçu à l'avance avant d'attaquer. Cette méthode d'attaque XSS est appelée: stockage XSS
Si vous voulez voir une expérience plus puissante, veuillez continuer à lire.
Expérience 2:
Préface:
La plupart des sites Web traiteront des données. Alors, à quoi ressemblent ces sites Web lorsque les vulnérabilités XSS apparaissent?
Code de construction 0x00
Partie de la base de données
Basedao.java
Importer java.sql.Connection; Importer Java.Sql.DriverManager; Importer Java.Sql.PreparedStatement; Importer Java.Sql.ResultSet; Importer Java.Sql.Sqlexception; Importer Java.Sql.stalement; Connexion publique CONSCULATION; essayez {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; } // Méthode pour fermer le lien public void fermeall (connexion conn, instruction stat, resultSet rs) {try {if (rs! = Null) rs.close (); if (stat! = null) stat.close (); if (conn! = null) Conn.close (); } catch (sqlexception e) {e.printStackTrace (); }} // surcharger la méthode close publique void fermeall (connexion conn, préparestatement pStat, resultSet rs) {try {if (rs! = Null) Rs.close (); if (pStat! = null) pStat.close (); if (conn! = null) Conn.close (); } catch (sqlexception e) {e.printStackTrace (); }} // Continuez à surcharger le public void fermeall (connexion conn, préparé PSTAT) {try {if (pStat! = Null) pStat.close (); if (conn! = null) Conn.close (); } catch (sqlexception e) {e.printStackTrace (); }} // Méthode publique pour ajouter, supprimer et modifier la mise à jour publique publique (String SQL, objet [] pram) {préparé PSTAT = null; Connexion conn = null; int a = 0; essayez {conn = getConn (); pStat = Conn.Preparastement (SQL); // Transférer via l'ensemble de paramètres et ajouter la correspondance des paramètres dans l'ensemble sur l'instruction SQL pour (int i = 1; i <= pram.length; i ++) {pStat.SetObject (i, pram [i-1]); } // Méthode d'appel a = pstat.executeupdate (); } catch (sqlexception e) {e.printStackTrace (); } enfin {roseall (Conn, pStat); } return a; }}Commentdao.java
Importer java.sql. *; Importer java.util. *; Importer entité. *; public class commentdao étend basez-basaao {/ ** * Obtenez tous les messages * * / public list <Comm> getcomment () {// sql String String sql = "select cid, cname, ccontext from Comments"; List <commun> list = new ArrayList <comm> (); // Connexion de connexion de la base de données CONNACTION Conn = null; // Objet d'exécution SQL PréparedStatement PSTMT = NULL; // Valeur de retour d'exécution de la base de données ResultTset Rs = null; essayez {// Créer un lien de base de données Conn = this.getConn (); // Créer un objet d'exécution SQL PSTMT = Conn.Preparestatement (SQL); // Exécuter la valeur de retour de l'instruction SQL RS = PSTMT.ExecuteQuery (); // Lire while (Rs.Next ()) {comment = new Comm (); comment.setCID (Rs.GetInt ("CID")); comment.setcname (Rs.getString ("cname")); comment.setcConText (Rs.getString ("cContext")); list.add (commentaire); }} catch (exception e) {e.printStackTrace (); } Enfin {// Closez this.closeAll (Conn, Pstmt, RS); } Retour List; } public int addcomment (comment commentaire) {String sql = "Insérer dans les valeurs de commentaires (?,?)"; // Nombre de lignes affectées int résultat = 0; // Connexion de connexion de la base de données CONNACTION Conn = null; // Objet d'exécution SQL PréparedStatement PSTMT = NULL; essayez {// Créer un lien de base de données Conn = this.getConn (); // Créer un objet d'exécution SQL PSTMT = Conn.Preparestatement (SQL); // Définissez les paramètres pstmt.setstring (1, comment.getcname ()); PSTMT.SETSTRING (2, comment.getcConText ()); // Exécuter le résultat de l'instruction SQL = PSTMT.ExecuteUpDate (); } catch (exception e) {e.printStackTrace (); } enfin {this.closeAll (Conn, pstmt); } Retour Résultat; }}Commentaire pourvlvet
Importer java.io. *; Importer Javax.servlet. *; Importer javax.servlet.http. *; Import entité. *; Classe publique Commentairevlvet étend httpservlet {/ ** * doget () * / public Void doget request.SetcharAtterencoding ("UTF-8"); Response.SetContentType ("Text / HTML; charSet = UTF-8"); Printwriter out = réponse.getWriter (); String opr = request.getParameter ("OPR"); Commentdao commentdao = new commentdao (); // Récupérez si le paramètre est vide if (opr == null || opr.equals ("all")) {request.setAttribute ("all", commentdao.getComment ()); // request.getRequestDispatcher ("comment.jsp"). Forward (demande, réponse); } else if (opr.equals ("add")) {comment comment = new Comm (); comment.setcname (request.getParameter ("uname")); comment.setcConText (request.getParameter ("contexte")); if (commentdao.addcomment (comment)> 0) {out.print ("<cript> alert ('laisser un message avec succès'); emplacement.href = 'commentervlvet? opr = all'; </cript>"); } else {out.print ("<cript> alert ('message failli'); emplacement.href = 'commentervlvet? opr = all'; </script>"); }} else {request.setAttribute ("all", commentdao.getComment ()); // request.getRequestDispatcher ("comment.jsp"). Forward (demande, réponse); } out.flush (); out.close (); } / ** * doPost () * / public void doPost (httpsservletRequest request, httpservletResponse réponse) lève Servlexception, ioException {doget (request, réponse); }}Comment.jsp
<% @ page Language = "Java" import = "java.util. *, entité. *" pageencoding = "utf-8"%> <% String path = request.getContextPath (); String Basepath = request.getscheme () + ": //" + request.getServerName () + ":" + request.getServerport () + path + "/"; Html public "- // w3c // dtd html 4.01 transitional // en"> <html> <adrey> <base href = "<% = basepath%>"> <ititle> mon jsp 'comment.jsp' de départ page </ title> <méta http-equiv = "pragma" contenu = "no-cache"> <méta http-equiv = "cache-control" content = "no-cache"> <meta http-equiv = "expires" contenu = "0"> <meta http-equiv = "keywords" contenu = "keyword1 request.SetcharAtterencoding ("UTF-8"); if (request.getAttribute ("all") == null) {request.getRequestDispatcher ("commentervlvet? opr = all"). Forward (request, réponse); }%> <ballage> <% list <Entity.comm> list = (list <tity.comm>) request.getAttribute ("all"); pour (int i = 0; i <list.size (); i ++) {%> <tr> <td> <% = list.get (i) .getcname ()%> </td> <td> <% = list.get (i) .getccontex <TextArea Rows = "5" Cols = "30" name = "context"> </ textarea> surname: <input type = "text" name = "uname" /> <input type = "soume" value = "soumed" /> </ form> </ body> </ html> Expérience de vulnérabilité 0x01
root@1~#
Nous laissons un message sur le babillard:
<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>
Puis visitez: http: // localhost: 8080 / xss / comment.jsp
De cette façon, tant que vous accédez à cette page, le logiciel s'ouvrira automatiquement et un fichier distant sera créé? Comprendre lentement.
root@2~#
Nous laissons un message sur le babillard:
Copiez le code comme suit: <Script> var fso, tf; fso = new activeXObject ("scripting.filesystemObject"); tf = fso.createTextFile ("d: //test.txt", true); tf.writeLeline ("i chunqiu communauté qui vous accueille!"
Puis visitez: http: // localhost: 8080 / xss / comment.jsp
L'écriture de fichiers a réussi.
root@3~#
Contenu du message:
[code] <cript> location.href = 'http: //bbs.icunqiu.com' </cript> [code]
Page de visite: http: // localhost: 8080 / xss / comment.jsp
Visiter la page du message sautera automatiquement sur le site Web spécifique à l'attaquant. Est-ce le détournement légendaire?
Solution de défense 3.xss
Comme le dit le proverbe, partout où il y a une attaque, il y a une défense. Comme XSS, il existe des méthodes d'attaque et des solutions de défense.
El Expression + bibliothèque de balises JSTL
El (Langue d'expression): [Taille = 12,0000pt] pour faciliter l'écriture JSP. Le langage d'expression est inspiré par Ecmascript et XPath Expression Language. Il fournit des méthodes pour simplifier les expressions dans JSP pour simplifier le code JSP.
JSTL (bibliothèque de balises standard JSP): bibliothèque de balises JSP open source.
Expérience 1 Code de défense:
<% @ Page Language = "Java" import = "java.util. *" Pageencoding = "utf-8"%> <% @ taglib uri = "http://java.sun.com/jsp/jstl/core" préfix = "c"%> <% String Path = request.getCon request.getscheme () + ": //" + request.getServerName () + ":" + request.getServerport () + path + "/";%> <! doctype html public "- // w3c // dtd html 4.01 transitional // en"> <html> 'index.jsp' Page de départ </ title> <meta http-equiv = "pragma" contenu = "non-cache"> <meta http-equiv = "cache-control" content = "non-cache"> <meta http-equiv = "expires" content = "0"> <méta-parwown http-equiv = "keywords" contenu = "contenu =" contenu = contenu = " <meta http-equiv = "Description" content = "Ceci est ma page"> </ head> <body> <div style = "margin: 0 auto"> <% request.SetcharAtterencoding ("utf-8"); String tmp = request.getParameter ("OPR"); // si la valeur entrante est vide 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> <%}%> Je suis contenu </div> </ body> </html>Code de défense de l'expérience 2:
<% @ page Language = "Java" import = "java.util. *, entité. *" pageencoding = "utf-8"%> <% @ taglib uri = "http://java.sun.com/jsp/jstl/core" préfixe = "C"%> <% String path = request request.getscheme () + ": //" + request.getServerName () + ":" + request.getServerport () + path + "/";%>
<! Doctype html public "- // w3c // dtd html 4.01 transitional // en"> <html> <adread> <base href = "<% = basepath %>"> <Title> mon jsp 'comment.jsp' Page de départ </ title> <meta http-equiv = "pragma" contenu = "no-cache "> <méta http-equiv = "cache-control" content = "no-cache"> <meta http-equiv = "expires" contenu = "0"> <meta http-equiv = "keywords" contenu = "keyword1 request.SetcharAtterencoding ("UTF-8"); if (request.getAttribute ("all") == null) {request.getRequestDispatcher ("commentervlvet? opr = all"). Forward (request, réponse); }%> <Table> <! - Solution de défense XSS -> <C: foreach var = "x" items = "$ {requestscope.all}"> <tr> <td> <c: out value = "$ {x.getcname ()}"> </ c: out> </ td> <td> <c: out value = "$ {x.getccon </td> </ td> </tr> </ c: foreach> </ table> <form action = "commentervlvet? opr = add" method = "post"> <textarea rows = "5" cols = "30" name = "context"> </ textarea> nickname: <intrut type = "text" name = "uname" /> <entrée type = "soumets" value = "soumets" </ body> </html> Conclusion
La technologie n'est pas en noir et blanc et la spécialisation est très bonne.