Tổng quan
Các kĩ thuật Web Application Attack được chia thành 2 nhóm chính:
- Attack phía server như SQL Injection, LFI (Local File Inclusion), SSRF (Server-site Request Forgery) …
- Attack phía user như XSS (Cross-site Scripting), CSRF (Cross-site Request Forgery), …
Tấn công phía server dường như mang lại hậu quả nặng nề hơn, vì nó giúp hacker control được các thành phần của server. Tuy nhiên tỷ lệ ứng dụng web chứa các lỗ hổng loại này lại ngày càng ít đi khi mà nhận thức về bảo mật của developper ngày nay đã được nâng cao hơn trước. Trong khi đó, các kĩ thuật tấn công phía user mà điển hình và nổi tiếng nhất là XSS lại trở nên phổ biến hơn do user thường là những người ít am hiểu và quan tâm về security. Và tác động mà nó mang lại cũng không nhỏ như người ta thường nghĩ.
Trong series này, tôi sẽ giới thiệu về các loại XSS, một số payload để bypass XSS filter, và các vấn đề liên quan xoay quanh chủ đề XSS Exploit như XSS Auditor, CSP (Content Security Policy). Tôi sẽ cố gắng đưa vào minh họa cụ thể lấy từ các bài CTF để bạn đọc dễ hình dung.
Hope you enjoy it, hacker!
XSS là gì?
XSS là kĩ thuật tấn công để chèn các script nguy hiểm vào source code ứng dụng web, mục đích thường là chiếm lấy phiên đăng nhập của người dùng. Xem xét ví dụ sau.
Source code server:

Khi client request 1 link có chứa tham số ‘name’, server sẽ gửi lời chào đến user.
Vấn đề sẽ phát sinh khi attacker thay vì nhập 1 tên bình thường thì lại gửi request như sau:

Session ID của user đã bị phơi bày, đây là ví dụ về loại phổ biến nhất của XSS: Reflected XSS cho thấy cách hoạt động của XSS, thực tế hacker thường lợi dụng XSS để gửi request chứa cookie cũng như các thông tin nhạy cảm về server của hacker.
Các loại XSS
Có 3 loại XSS chính:
- Reflected XSS: Script nguy hiểm được chèn trực tiếp vào response của user, hacker cần phải gửi link độc hại này cho user và lừa user nhấp vào link. Payload được thực hiện trong cùng một request và response nên còn được gọi là first-order XSS.
- Stored XSS: Hacker chèn script nguy hiểm vào trang web lỗi, script sẽ được lưu lại trong ứng dụng web. Bất cứ khi nào user truy cập vào trang web có chứa đoạn script đó, script sẽ được thực thi. Chính vì attack xảy ra qua 2 bước như vậy nên loại này còn được gọi là second-order XSS.
- DOM based XSS: Khá giống với Reflected XSS, tuy nhiên script của hacker sẽ không được nhúng trực tiếp vào ứng dụng web mà thông qua DOM (Document Object Model) và không giống như 2 loại XSS trên, mã độc sẽ được thực thi ngay khi xử lý phía client mà không thông qua server.
Không có lời giải thích nào tốt bằng ví dụ thực tế. Ta sẽ cùng xem xét các kịch bản khai thác của từng loại XSS để hiểu rõ hơn.
1. Reflected XSS
Trở về ví dụ phía trên, source code không thay đổi. Lần này thay vì nhúng mã độc đơn giản chỉ để alert cookie trên browser thì hacker sẽ gửi link sau cho victim:
Ở đây, tôi demo trên localhost. Sau khi victim truy cập vào link trên, đoạn mã độc sẽ được nhúng vào response gửi về client browser

Trong đó https://enx9vsvmn2qph50.m.pipedream.net là server mà hacker kiểm soát (tôi dùng 1 webhook miễn phí từ trang https://pipedream.com để nhận request). Đoạn mã độc trên sẽ gửi cookie của victim về cho hacker:

Hacker chỉ việc check request gửi đến server của mình sẽ nhận được session ID của victim, và dùng nó để chiếm phiên đăng nhập của người dùng.
Đặc điểm của loại XSS này là hacker phải gửi link chứa mã độc cho victim và lừa được user truy cập vào link này. Mã độc sẽ được thực thi ngay khi victim truy cập link.
2. Stored XSS
Xem xét 1 ví dụ khác lấy từ 1 challenge trên root-me:
http://challenge01.root-me.org/web-client/ch18/

Challenge này mô tả một ứng dụng web cho phép user gửi message đến admin. Admin sẽ định kỳ kiểm tra các message do user gửi đến. Khi chèn script sau vào khung Message:

Ta nhận được popup sau, chứng tỏ khung Message này bị lỗi XSS

Và điều quan trọng là, mã độc đã được lưu lại trên trang web, bất cứ khi nào admin truy cập vào ứng dụng để xem message, mã độc sẽ được thực thi. Do đó, hacker sẽ tấn công bằng cách gửi payload sau:

Ta chỉ cần đợi admin đọc message, mã độc được thực thi và gửi request chứa cookie của admin về server của hacker.

Easy challenge, right? 🙂
3. DOM based XSS
Xem xét ví dụ sau, source code phía server:

Khi gửi request có chứa tham số ‘name’, server sẽ dùng DOM (Document Object Model) để lấy giá trị của tham số ‘name’ và viết lời chào lên browser.

Khi hacker gửi request chứa mã độc, script sẽ được thực thi:

Tuy nhiên, điều đáng nói ở đây, và cũng là điểm khác biệt của DOM based XSS là mã độc được thực thi do đoạn Javascript phía client mà không cần server xử lý request. Kết quả là response trả về không hề chứa đoạn script của hacker. Bạn đọc sẽ thấy được điều này khi view-source trang web:

Bạn đọc đã thấy được sự khác nhau của DOM based XSS và Reflected XSS chứ. Thế nhưng bạn sẽ thắc mắc rằng sự khác biệt này thì có ý nghĩa gì. Thật ra là có đấy. Trình duyệt web Google Chrome có một tính năng bảo mật được bật mặc định là XSS Auditor, nó là 1 filter của browser, có chức năng ngăn chặn cuộc tấn công XSS. Browser sẽ kiểm tra xem trong request mà client gửi lên có chứa mã độc không, nó sẽ so sánh script này với nội dung response từ server. Nếu script từ request giống với response, XSS Auditor sẽ nhận biết đây là một cuộc tấn công XSS và block đoạn script này.
Như vậy XSS Auditor chỉ ngăn chặn được Reflected XSS mà không ngăn chặn được DOM based XSS, vì script của hacker không được copy vào response từ server. It’s cool, right?
Lời kết
Phần 1 của bài viết xin phép dừng tại đây. Phần 2 sẽ nói về các thể loại XSS filter và cách bypass.
Happy hacking!