---
# System prepended metadata

title: Cross-site scripting (XSS)

---

# Cross-site scripting (XSS)
## Lý thuyết:
### XSS là gì?
* Cross-site scripting (XSS) là một lỗ hổng bảo mật web cho phép kẻ tấn công can thiệp vào tương tác của người dùng với một ứng dụng dễ bị tấn công. XSS cho phép kẻ tấn công vượt qua chính sách cùng nguồn gốc (same origin policy), một cơ chế bảo mật được thiết kế để ngăn cách các website khác nhau với nhau. Với lỗ hổng này, kẻ tấn công có thể giả dạng người dùng bị hại, thực hiện các hành động mà người dùng có thể làm, và truy cập vào dữ liệu của họ. Nếu người dùng bị hại có quyền hạn cao trong ứng dụng, kẻ tấn công thậm chí có thể chiếm quyền kiểm soát toàn bộ chức năng và dữ liệu của ứng dụng.

* Trong thực tế, XSS thường lợi dụng những điểm yếu trong việc xử lý dữ liệu nhập từ người dùng như không kiểm tra kỹ lưỡng đầu vào hoặc không mã hóa đúng cách trước khi hiển thị trên trang web.

![image](https://hackmd.io/_uploads/HJ_9JRTTR.png)






* Cross-Site Scripting (XSS) là một cuộc tấn công bảo mật web, trong đó kẻ tấn công lợi dụng lỗ hổng của trang web để chèn mã độc hại (thường là mã JavaScript) vào nội dung trang web. Sau đó, khi người dùng truy cập trang web đó, mã độc này sẽ được thực thi trong trình duyệt của họ mà không hay biết. Dưới đây là quy trình dựa trên hình minh họa bạn đã cung cấp:

1.  Chèn mã độc: Kẻ tấn công gửi yêu cầu đến một trang web có lỗ hổng và chèn đoạn mã độc hại vào URL hoặc một biểu mẫu trên trang web. Ví dụ, trong hình ảnh, mã script `<script>` đã được chèn vào URL.
 
2.  Máy chủ phản hồi mã độc: Do trang web không kiểm tra đúng cách dữ liệu đầu vào, nó gửi mã độc này trở lại trình duyệt của người dùng cùng với nội dung trang web.
 
1.  Thực thi mã trong trình duyệt của nạn nhân: Khi người dùng truy cập vào trang web này, trình duyệt của họ sẽ thực thi mã độc mà không biết đó là mã tấn công. Mã này có thể lấy cắp dữ liệu hoặc chiếm quyền điều khiển phiên làm việc của người dùng. 
1.  Kẻ tấn công lấy thông tin: Sau khi mã được thực thi, kẻ tấn công có thể truy cập các thông tin nhạy cảm của người dùng như:

* Mật khẩu đăng nhập
* Thông tin cá nhân, dữ liệu nhạy cảm (như tên mẹ để trả lời câu hỏi bảo mật)
* Thông tin tài khoản ngân hàng hoặc thực hiện các lệnh chuyển tiền.

5. Chiếm quyền phiên người dùng: Mã độc có thể chiếm quyền phiên người dùng, thực hiện các hành động thay mặt họ như truy cập dữ liệu, thay đổi thông tin hoặc thậm chí chuyển tiền mà người dùng không hay biết.

### Nguyên nhân
* Nguyên nhân của tấn công XSS (Cross-Site Scripting) chủ yếu do trang web không kiểm tra hoặc xử lý dữ liệu đầu vào đúng cách, dẫn đến việc chèn mã độc vào trang web. Dưới đây là các nguyên nhân chính:

1. Thiếu xác thực đầu vào: Trang web không lọc hoặc xác thực dữ liệu mà người dùng nhập vào, cho phép mã độc hại được gửi và lưu trữ trên trang web.
1. Thiếu mã hóa đầu ra: Dữ liệu không được mã hóa đúng cách khi hiển thị trên trình duyệt, cho phép thực thi mã độc trực tiếp trên trang web. 
1. Sử dụng HTML hoặc JavaScript động không an toàn: Khi trang web xây dựng nội dung HTML hoặc JavaScript từ đầu vào của người dùng mà không có biện pháp bảo vệ, dẫn đến việc mã độc có thể được chèn vào và thực thi.

### XSS Proof of Concept (PoC)
Để xác nhận lỗ hổng XSS, bạn có thể chèn mã độc và kiểm tra xem trình duyệt có thực thi không. Thông thường, hàm `alert()` được dùng vì nó ngắn, an toàn, và dễ thấy. Tuy nhiên, kể từ Chrome phiên bản 92 (20/7/2021), các iframe cross-origin bị chặn gọi `alert()`. Trong trường hợp này, bạn nên dùng hàm `print()` thay thế để xác minh XSS.

### Cách tấn công
* Reflected XSS: Mã độc được chèn vào và thực thi ngay lập tức từ yêu cầu HTTP hiện tại, không lưu trữ lại trên máy chủ. Kẻ tấn công thường gửi đường dẫn hoặc yêu cầu chứa mã độc để lừa nạn nhân nhấp vào.
* Stored XSS: Mã độc được lưu trữ trên cơ sở dữ liệu của trang web. Khi người dùng truy cập vào trang có chứa dữ liệu đã bị nhiễm mã độc, mã sẽ được thực thi trong trình duyệt của người dùng.
* DOM-based XSS: Lỗ hổng tồn tại ở mã phía client (trong DOM của trình duyệt), không liên quan đến máy chủ. Dữ liệu đầu vào của người dùng bị xử lý không an toàn trong JavaScript, dẫn đến mã độc được chèn trực tiếp và thực thi.

#### Reflected XSS
* Giả sử một trang web có chức năng tìm kiếm nhận cụm từ tìm kiếm do người dùng cung cấp trong tham số URL:
`https://insecure-website.com/search?term=gift`
* Ứng dụng lặp lại cụm từ tìm kiếm được cung cấp trong phản hồi URL này:
`<p>You searched for: gift</p>`

* Giả sử ứng dụng không thực hiện bất kỳ quá trình xử lý dữ liệu nào khác, kẻ tấn công có thể xây dựng một cuộc tấn công như sau:
`https://insecure-website.com/search?term=<script>/*+Bad+stuff+here...+*/</script>`

* This URL results in the following response:
`<p>You searched for: <script>/* Bad stuff here... */</script></p>`

#### Stored XSS
* Stored cross-site scripting (XSS), còn gọi là second-order hoặc persistent XSS, xảy ra khi một ứng dụng nhận dữ liệu từ một nguồn không tin cậy và sau đó bao gồm dữ liệu này trong các phản hồi HTTP tiếp theo mà không xử lý an toàn. Điều này có nghĩa là mã độc hại có thể được lưu trữ trên máy chủ và thực thi trong trình duyệt của người dùng mỗi khi họ truy cập vào trang bị ảnh hưởng, tạo nên một cuộc tấn công dài hạn hơn so với reflected XSS.

* Giả sử một trang web cho phép người dùng gửi nhận xét về các bài đăng trên blog, được hiển thị cho người dùng khác. Người dùng gửi nhận xét bằng cách sử dụng yêu cầu HTTP như sau:


```
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100

postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
```
* Sau khi nhận xét này đã được gửi, bất kỳ người dùng nào truy cập bài đăng trên blog sẽ nhận được những điều sau trong phản hồi của ứng dụng:
`<p>This post was extremely helpful.</p>`


Giả sử ứng dụng không thực hiện bất kỳ quá trình xử lý dữ liệu nào khác, kẻ tấn công có thể gửi nhận xét độc hại như sau:
`<script>/* Bad stuff here... */</script>`

Trong yêu cầu của kẻ tấn công, nhận xét này sẽ được mã hóa URL như sau:


`comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E`

#### DOM-based Cross-Site Scripting
* DOM (Document Object Model)-based Cross-Site Scripting một loại tấn công bảo mật trong đó kẻ tấn công lợi dụng các lỗ hổng JavaScript trên phía client (trình duyệt) để chèn mã độc và thực thi nó. Dữ liệu đầu vào mà kẻ tấn công kiểm soát, chẳng hạn như từ URL, được truyền đến một "sink" (điểm xử lý dữ liệu) mà không được kiểm tra an toàn. Từ đó, mã JavaScript độc hại có thể được thực thi, dẫn đến các hành vi như chiếm quyền tài khoản người dùng.

1. Sources: Đây là các điểm nhập mà dữ liệu của kẻ tấn công có thể truyền vào trang web, ví dụ như:

`window.location`: Dữ liệu từ URL có thể bị lợi dụng.

`document.referrer`: Có thể truyền dữ liệu từ trang gốc (referrer).

`document.cookie`: Cookies có thể được dùng để truy cập thông tin nhạy cảm.

`localStorage hoặc sessionStorage`: Dữ liệu được lưu trữ trên trình duyệt.

2. Sinks: Đây là các điểm trong mã JavaScript nơi dữ liệu từ source có thể được xử lý hoặc thực thi. Các sink phổ biến trong DOM XSS bao gồm:

`innerHTML`: Gắn kết dữ liệu vào nội dung HTML. Nếu dữ liệu không được mã hóa đúng cách, kẻ tấn công có thể chèn mã độc vào.

`eval()`: Thực thi chuỗi dữ liệu dưới dạng mã JavaScript, rất nguy hiểm nếu nguồn không được kiểm tra kỹ.

`document.write()`: Ghi trực tiếp dữ liệu vào trang, thường dẫn đến lỗ hổng XSS nếu không được kiểm tra.

`setTimeout() hoặc setInterval()`: Chạy mã JavaScript với sự trì hoãn, có thể thực thi mã độc từ dữ liệu được truyền vào.

`location.href hoặc location.assign`: Thay đổi vị trí URL, có thể lợi dụng để điều hướng người dùng đến trang độc hại.

* Exploiting DOM XSS with different sources and sinks
* The document.write sink works with script elements, so you can use a simple payload, such as the one below:

`> document.write('... <script>alert(document.domain)</script> ...');`

Hoặc với đoạn code dưới đây:
```


function trackSearch(query) {
     document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
  }
 var query = (new URLSearchParams(window.location.search)).get('search');
if(query) {
    trackSearch(query);
 }
```
Payload tấn công vào sink sẽ là: `"><script>alert("hhh")</script>`

* The innerHTML sink doesn't accept script elements on any modern browser, nor will svg onload events fire. This means you will need to use alternative elements like img or iframe. Event handlers such as onload and onerror can be used in conjunction with these elements. 


`element.innerHTML='... <img src=1 onerror=alert(document.domain)> ...'`
* Sources and sinks in third-party dependencies
* Các ứng dụng web hiện đại thường sử dụng nhiều third-party libraries và frameworks như jQuery hoặc AngularJS, tạo ra các sources và sinks tiềm ẩn cho DOM-based XSS. Dưới đây là một số cách mà các thư viện này có thể bị lợi dụng cho các cuộc tấn công.

#### DOM XSS trong jQuery

```
jQuery's 
attr()
```
 Function: Hàm attr() trong jQuery có thể thay đổi các thuộc tính của các phần tử DOM. Nếu dữ liệu từ một source (chẳng hạn như window.location.search) được truyền vào hàm này mà không được kiểm tra, kẻ tấn công có thể chèn các URL độc hại dẫn đến XSS.


```
$(function() {
  $('#backLink').attr("href", (new URLSearchParams(window.location.search)).get('returnUrl'));
});
```
Nếu URL chứa ?returnUrl=javascript:alert(document.domain), việc nhấp vào liên kết đã bị thay đổi sẽ thực thi mã độc alert().

```
jQuery's 
$()
```
 Selector Function: Hàm $() có thể được sử dụng để chèn các đối tượng vào DOM. Trong các phiên bản cũ của jQuery, việc sử dụng source như location.hash để tạo hoạt ảnh hoặc cuộn trang đến một phần tử có thể dẫn đến lỗ hổng XSS.


```
$(window).on('hashchange', function() {
  var element = $(location.hash);
  element[0].scrollIntoView();
});
```
Khai thác: Kẻ tấn công có thể thay đổi location.hash để chèn mã độc XSS vào trang.

Bản vá: Các phiên bản mới hơn của jQuery ngăn chặn việc chèn khi input bắt đầu bằng #, nhưng mã cũ vẫn có thể bị khai thác.

Ví dụ khai thác với Iframe:


`<iframe src="https://vulnerable-website.com#" onload="this.src+='<img src=1 onerror=alert(1)>'">`
==>  Iframe này sẽ kích hoạt sự kiện hashchange và thêm vector XSS.

DOM XSS trong AngularJS
AngularJS's ng-app Attribute: AngularJS xử lý các phần tử HTML có thuộc tính ng-app, cho phép các biểu thức động trong dấu ngoặc kép kép ({{ }}). Kẻ tấn công có thể lợi dụng để thực thi JavaScript mà không cần sử dụng các thẻ truyền thống như` <script> `hoặc các event handlers.

```
<div ng-app>
  ...
  {{ $on.constructor(alert(document.domain))() }}
  ...
</div>
```
Trong trường hợp này, AngularJS sẽ đánh giá biểu thức và thực thi alert(document.domain).

Giải thích về `$on.contructor()`

$on is event handler function in Angular JS. The $ sign just represents it is a function. $on.constructor is constructor function when invoked with parameters executes it's argument passed as a string. Thus passed with argument it is $on.constructor('alert(1)') and to denote constructor is a function "()" is added to look like: $on.constructor('alert(1)')(). This is similar to the following snippet in javascript:
```

function (){
   alert(1);
}
```
#### Cách nhận biết (tìm) lỗ hổng
1. Reflected XSS vuln
* Test every entry point: Test từng entry point mà dữ liệu có thể được gửi đến ứng dụng thông qua các yêu cầu HTTP, bao gồm các parameters trong chuỗi query URL, nội dung trong body của request, URL file path và các HTTP headers.

* Submit random alphanumeric values: Tại mỗi entry point, submit một random alphanumeric value và xác định xem giá trị đó có được reflect trong response hay không. Giá trị nên ngắn gọn, chứa các ký tự alphanumeric để vượt qua validation, thường khoảng 8 ký tự là lý tưởng.

* Determine the reflection context: Khi random value xuất hiện trong response, xác định reflection context, ví dụ giữa các thẻ HTML, trong attribute của thẻ, hoặc trong JavaScript string.

* Test a candidate payload: Dựa trên reflection context, thử nghiệm một candidate XSS payload đơn giản có thể kích hoạt JavaScript nếu nó không bị thay đổi trong response. Có thể dùng công cụ như Burp Repeater để test payload.

* Test alternative payloads: Nếu candidate XSS payload ban đầu bị thay đổi hoặc bị chặn, thử alternative payloads phù hợp với context và loại input validation của ứng dụng.

* Test the attack in a browser: Nếu payload có vẻ hoạt động trong Burp, hãy chuyển thử nghiệm sang browser thật để kiểm tra xem injected JavaScript có thực thi không. Cách test đơn giản là dùng alert(document.domain) để hiển thị popup nếu tấn công thành công.

2. Stored XSS vuln

Bước 1: Xác định các entry points và exit points

* Entry points là nơi dữ liệu có thể nhập vào hệ thống, bao gồm:
* Các parameters trong chuỗi URL, nội dung trong message body.
* URL file path.
* HTTP request headers.
* Các con đường khác ngoài band mà dữ liệu có thể được gửi vào ứng dụng (ví dụ: email, dữ liệu từ bên thứ ba như Twitter feeds hoặc dữ liệu từ các trang web khác trong một news aggregator).
* Exit points là nơi dữ liệu từ các entry points xuất hiện trong phản hồi HTTP trả về cho người dùng. Điều này có thể xảy ra ở bất kỳ đâu trong ứng dụng.

Bước 2: Tìm mối liên kết giữa entry và exit points

* Liên kết dữ liệu: Dữ liệu nhập vào ở bất kỳ entry point nào có thể xuất hiện ở bất kỳ exit point nào. Ví dụ, tên hiển thị do người dùng cung cấp có thể xuất hiện trong một audit log chỉ hiển thị cho một số người dùng.
* Khó khăn: Dữ liệu có thể dễ dàng bị ghi đè bởi các hành động khác trong ứng dụng. Ví dụ, các tìm kiếm gần đây có thể được thay thế nhanh chóng khi người dùng thực hiện tìm kiếm mới.

Bước 3: Thử nghiệm

* Gửi một giá trị cụ thể vào mỗi entry point và quan sát các phản hồi của ứng dụng để phát hiện nơi giá trị được xuất hiện. Tập trung vào các chức năng cụ thể như phần bình luận trên blog.
* Xác định lưu trữ dữ liệu: Khi giá trị xuất hiện trong phản hồi, xác định xem nó có được lưu trữ và xuất hiện qua các yêu cầu khác nhau, hay chỉ đơn giản là phản chiếu trong phản hồi ngay lập tức.

Bước 4: Kiểm tra lỗ hổng stored XSS

* Sau khi xác định được liên kết giữa entry và exit points, bạn cần kiểm tra cụ thể từng liên kết để phát hiện lỗ hổng stored XSS.
* Phân tích ngữ cảnh: Xác định ngữ cảnh trong phản hồi nơi dữ liệu lưu trữ xuất hiện (trong HTML tags, thuộc tính thẻ, JavaScript, v.v.).
* Thử nghiệm payload XSS: Kiểm tra các payload XSS phù hợp với ngữ cảnh đó để xem liệu mã độc có được thực thi hay không. Quy trình này tương tự với việc kiểm tra lỗ hổng reflected XSS.

3. DOM XSS:

* Kiểm tra các HTML sinks:
Đầu tiên, chèn một chuỗi dữ liệu ngẫu nhiên (alphanumeric string) vào phần URL (location.search) và kiểm tra trong DOM để xem chuỗi này có xuất hiện ở đâu trong mã HTML không. Sử dụng công cụ phát triển (developer tools) của trình duyệt để tìm kiếm vị trí mà dữ liệu xuất hiện.
Xác định ngữ cảnh nơi chuỗi xuất hiện trong HTML, sau đó thử chèn các ký tự đặc biệt như dấu ngoặc kép để xem liệu có thể thoát ra khỏi ngữ cảnh hiện tại và thực thi mã JavaScript hay không.

* Kiểm tra các JavaScript execution sinks:
Sử dụng công cụ phát triển của trình duyệt để tìm kiếm nơi các nguồn dữ liệu như window.location được sử dụng trong mã JavaScript.
Đặt các điểm dừng (breakpoints) trong mã JavaScript và theo dõi dòng chảy của dữ liệu để xem liệu nó có được truyền đến các sink nguy hiểm như eval() hoặc innerHTML hay không.
Sau đó, bạn có thể thử nghiệm các payload XSS để xem liệu mã JavaScript độc hại có được thực thi thành công không.

#### Công cụ hỗ trợ kiểm tra DOM XSS:
Burp Suite: Công cụ DOM Invader tích hợp trong Burp Suite giúp tự động xác định các nguồn và sink trong JavaScript, giúp phát hiện và khai thác lỗ hổng DOM XSS dễ dàng hơn.



### Lab 1: Reflected XSS into HTML context with nothing encoded
![image](https://hackmd.io/_uploads/rkhsewrpA.png)
* Phòng thí nghiệm này chứa một lỗ hổng kịch bản chéo trang đơn giản được phản ánh trong chức năng tìm kiếm. 
* Để giải quyết bài lab, hãy thực hiện một cuộc tấn công kịch bản chéo trang gọi hàm cảnh báo.
* Ứng dụng web có chức năng search và in chuỗi tìm kiếm ra giao diện.
![image](https://hackmd.io/_uploads/ryV1_PBaC.png)




* Kiểm tra mã nguồn HTML, có thể thấy, chuỗi tìm kiếm được truyền trực tiếp vào mà không có validate → reflected XSS.
![image](https://hackmd.io/_uploads/BktRDPBaC.png)



* Chỉ cần search chuỗi` <script>alert(1)</script>`, một thông báo alert sẽ xuất hiện.
![image](https://hackmd.io/_uploads/SJ_gOPBa0.png)



* Lúc này ta đã solve thành công challenge.![image](https://hackmd.io/_uploads/SJl-dvHTR.png)

### Lab 2: Stored XSS into HTML context with nothing encoded
![image](https://hackmd.io/_uploads/Hk3XOwrpC.png)
* Phòng thí nghiệm này chứa lỗ hổng kịch bản chéo trang được lưu trữ trong chức năng nhận xét.
* Để giải quyết bài thí nghiệm này, hãy gửi nhận xét gọi chức năng `alert` khi bài đăng trên blog được xem.
* Chức năng comment tại mỗi post trên ứng dụng bị dính lỗi Stored XSS.
![image](https://hackmd.io/_uploads/rkv5FvH60.png)





Thử comment với nội dung như trên, kiểm tra mã nguồn thì thấy các trường Comment, Name, Website được render ra HTML. Attacker hoàn toàn có thể truyền XSS payload vào trường nào.
![image](https://hackmd.io/_uploads/By1dFDBp0.png)
![image](https://hackmd.io/_uploads/By1BiDr6A.png)



Ở đây, mình chèn `<script>alert(1)</script>` vào trường comment.
![image](https://hackmd.io/_uploads/Bk2PowBT0.png)



Lúc này load lại trang chứa comment, một hộp thông báo alert đã xuất hiện. Như vậy, ta đã solve được challenge.
![image](https://hackmd.io/_uploads/Sk3KiwS6C.png)
![image](https://hackmd.io/_uploads/Hyc5oDrp0.png)

### Lab 3: DOM XSS in `document.write` sink using source `location.search`
![image](https://hackmd.io/_uploads/By2lnWOpC.png)
* Phòng thí nghiệm này chứa lỗ hổng kịch bản chéo trang dựa trên DOM trong chức năng theo dõi truy vấn tìm kiếm. Nó sử dụng hàm `document.write` của JavaScript để ghi dữ liệu ra trang. Hàm `document.write` được gọi với dữ liệu từ `location.search` mà bạn có thể kiểm soát bằng cách sử dụng URL trang web. 
* Để giải quyết bài thực hành này, hãy thực hiện một cuộc tấn công kịch bản chéo trang gọi hàm cảnh báo.
* Ứng dụng web có chức năng search và bị dĩnh lỗi DOM-based XSS tại chức năng seaerch tracking. Đọc mã nguồn HTML có thể thấy đoạn script chứa sink document.write ghi tag `<img>` chứa source query (chính là chuỗi được search).
![image](https://hackmd.io/_uploads/Hyx52WuTR.png)




* Chỉ cần search `aa"><script>alert(1)</script>` để escape tag img và thực thi alert.
![image](https://hackmd.io/_uploads/ByD5n-dTC.png)



* Như vậy ta solve được challenge.

![image](https://hackmd.io/_uploads/Bkej3WOpC.png)
### Lab 4: DOM XSS in innerHTML sink using source location.search
![image](https://hackmd.io/_uploads/SkbHeEuaA.png)
* Chuỗi search được lấy từ location.search và được trang web render ra HTML thông qua innerHTML.
![image](https://hackmd.io/_uploads/B1aRht_6R.png)



* Do innerHTML không hỗ trợ tag script nên ta sẽ sử dụng payload sau: `<img src=1 onerror=alert(1) - Do source ảnh sai nên event onerror sẽ được trigger → alert.`
![image](https://hackmd.io/_uploads/Bk4JpKua0.png)



* Thực hiện tìm kiếm với payload trên, ta thấy alert thành công.
![image](https://hackmd.io/_uploads/Bko16K_60.png)



* Như vậy ta đã solve được challenge.

![image](https://hackmd.io/_uploads/SJklptdaA.png)

### Lab 5: DOM XSS in jQuery anchor href attribute sink using location.search source
![image](https://hackmd.io/_uploads/Hy63j8FTA.png)
* Tại form submit feedback, trang web có chứa chức năng Back để quay lại trang trước.
![image](https://hackmd.io/_uploads/HJHIhLtpC.png)




* Khi click vào thì một GET request được gửi đến /feedback?returnPath=/ tức là trở về trang chủ. Nếu đọc mã nguồn HTML, có thể thấy có một đoạn script sử dụng JQuery để thêm attribute href vào tag `<a>` chứa đường link back ở trên. Và source lấy chính là tham số returnPath.

![image](https://hackmd.io/_uploads/S1583UFaC.png)


* Như vậy ta sẽ send request đến /feedback?returnPath=javascript:alert(1) để khi click vào Back, hàm alert trong href="javascript:alert(1)" được thực thi.
![image](https://hackmd.io/_uploads/H1fw3LtaA.png)



* Như vậy, ta solve được challenge.

![image](https://hackmd.io/_uploads/rJLD2UFTC.png)

### Lab 6: DOM XSS in jQuery selector sink using a hashchange event
![image](https://hackmd.io/_uploads/HkfMzRcT0.png)

* Đọc HTML source code thì có 1 đoạn script JQuery sử dụng selector $() thực hiện auto-scroll người dùng đến bài post có chứa chuỗi hash (lấy từ source location.hash) do người dùng nhập vào với prefix #. Nó sẽ được thực thi khi event hashchange được kích hoạt.

![image](https://hackmd.io/_uploads/SJipbA5aA.png)


* Ví dụ khi hash là Meeting:
![image](https://hackmd.io/_uploads/ByJ0WA9pA.png)



* Có thể thấy, ta hoàn toàn có thể inject 1 XSS vector thông qua location.hash. Tuy nhiên, ta cần xác định phương thức để kích hoạt hashchange event mà không cần có tương tác của người dùng. Cách đơn giản nhất là sử dụng iframe kiểu như sau:

`<iframe src="https://0a62004c0478f3bac9787abb0026009d.web-security-academy.net/#" onload="this.src+='<img src=1 onerror=print()>'"></iframe>`

* Cụ thể, src attribute hướng đến trang có lỗ hổng với hash value rỗng. Khi iframe được load, XSS payload <img src=1 onerror=print()> sẽ được gắn vào hash và khiến cho hashchange event được kích hoạt.

* Nhét payload trên vào exploit server để gửi đi cho nạn nhân.
![image](https://hackmd.io/_uploads/rJDRZCcTA.png)



* Lúc này tại máy nạn nhân, print() được thực thi và ta solve được challenge.

![image](https://hackmd.io/_uploads/HyZJMRcaA.png)


### Lab 7: Reflected XSS into attribute with angle brackets HTML-encoded
![image](https://hackmd.io/_uploads/S1QSzAc6A.png)



* Ta thấy chuỗi search được HTML encode khi render.
![image](https://hackmd.io/_uploads/HJ5M6T9pR.png)




* Tuy nhiên, chuỗi search lại được thêm vào thuộc tính value của tag input search. Do đó, sử dụng payload aaa" onfocus=alert(1) x=" để escape value và thêm event onfocus.
![image](https://hackmd.io/_uploads/ByJXTa9TA.png)



* Khi focus vào input search thì hàm alert được thực thi.
![image](https://hackmd.io/_uploads/BJEm6p56A.png)



* Như vậy ta đã solve được challenge.
![image](https://hackmd.io/_uploads/SJKmpp5aR.png)

### Lab 8: Reflected XSS into a JavaScript string with angle brackets HTML encoded
![image](https://hackmd.io/_uploads/r1Z_dA56A.png)
* Ứng dụng web tồn tại XSS tại chức năng search. Cụ thể chuỗi người dùng search sẽ được lưu vào biến searchTerms.
![image](https://hackmd.io/_uploads/rJc9O0cT0.png)



* Lúc này ta có thể escape searchTerms và gọi hàm alert bằng payload test';alert(1);//. Có thể thấy đoạn script được render sau khi ta inject vẫn đúng cấu trúc của Javascript.
![image](https://hackmd.io/_uploads/HJNoORqTR.png)



* Thực hiện search với payload trên, ta alert thành công.
![image](https://hackmd.io/_uploads/H1cs_Cq6R.png)



* Như vậy ta solve được challenge.

![image](https://hackmd.io/_uploads/S1asOA9TA.png)

### Lab 9: Stored XSS into anchor href attribute with double quotes HTML-encoded
![image](https://hackmd.io/_uploads/H1tpOCc6R.png)
* Ứng dụng web bị dính Stored XSS tại chức năng comment.
![image](https://hackmd.io/_uploads/SkFWtC56R.png)



* Sau khi post comment, kiểm tra mã nguồn HTML thì thấy trường Website được lưu trong href của tag `<a>`
![image](https://hackmd.io/_uploads/Bk1bKCcp0.png)



* Chỉ cần website là `javascript:alert(1)`, thì khi click vào link đó, ta alert được thành công.
![image](https://hackmd.io/_uploads/rkffFC5pC.png)



Lúc này ta solve được challenge.
![image](https://hackmd.io/_uploads/SJOGtC9pC.png)


### Lab 10: DOM XSS in document.write sink using source location.search inside a select element
![image](https://hackmd.io/_uploads/BkEmwP0pR.png)
* Ứng dụng web có chức năng Check stock tại mỗi sản phẩm theo từng store.
![image](https://hackmd.io/_uploads/SJ7lwTAaA.png)



* Inspect HTML ta đọc được đoạn script render ra `<select>` chứa các tên store. Cụ thể, ta có thể control được store cần tìm bằng tham số `storeId` thông qua location.search. Sau đó sink document.write được sử dụng để ghi `storeId` đó trực tiếp vào `<option>.`
![image](https://hackmd.io/_uploads/HJPvdDRa0.png)



* Thử thêm tham số `storeId` bằng chuỗi bất kì ta thấy option chứa chuỗi đó.
![image](https://hackmd.io/_uploads/HyADOP0TR.png)



* Sử dụng payload `hacked</option><script>alert(1)</script><option>` ta sẽ escape được tag `<option>` ban đầu và gọi được hàm `alert()`.
![image](https://hackmd.io/_uploads/B1uOdP0pA.png)



* HTML được render sau khi inject payload trên có dạng như sau:
![image](https://hackmd.io/_uploads/SyI9OwCTC.png)



* Như vây ta đã alert và solve challenge thành công.
 ![image](https://hackmd.io/_uploads/SJ9cdPCTR.png)


### Lab 11:DOM XSS in AngularJS expression with angle brackets and double quotes HTML-encoded
![image](https://hackmd.io/_uploads/SJtdnvCpR.png)
* Dễ thấy nó sử dụng công nghê angular 1-7-7. Nó nhận` {{}}` để thực thi đoạn mã javascript.
![image](https://hackmd.io/_uploads/ByC23wAaC.png)
* Kiểm tra mã HTML thì phát hiện có ng-app directive của AngularJS.
![image](https://hackmd.io/_uploads/BkgrpwRTA.png)



* Lúc này, sử dụng Angular expression với payload `{{constructor.constructor('alert(1)')()}}` để khởi tạo một hàm `alert()` bằng `constructor` và thực thi nó thông qua `{{}}`.

![image](https://hackmd.io/_uploads/BkKHpwATA.png)


Như vây, ta alert thành công và solve được challenge.

![image](https://hackmd.io/_uploads/H1pSpwC60.png)

### Lab 12: Reflected DOM XSS
![image](https://hackmd.io/_uploads/B1ltaPATA.png)
* Search bằng chuỗi xss và dùng DOM Invader tìm chuỗi xss thì thấy nó được lưu vào thuộc tính searchTerm của object searchResultsObj.
![image](https://hackmd.io/_uploads/rJPCt5Ra0.png)




* Ta sẽ escape thuộc tính searchTerm bằng payload `\" - alert(1)} //`. Lúc này searchTerm sẽ có giá trị NaN vì `"xss" - alert(1)` sẽ cho ra NaN. Và tất nhiên `alert(1)` đã được thực thi.
![image](https://hackmd.io/_uploads/HynAFqRpC.png)



* Như vậy, ta solve được challenge.
![image](https://hackmd.io/_uploads/rJ-J99RTA.png)

### LAB 13: Stored DOM XSS
* Tại chức năng comment, thực hiện comment có chứa chuỗi xss và sử dụng DOM Invader xem chuỗi xss thì thấy comment được lưu dạng object vào một mảng.

![image](https://hackmd.io/_uploads/Hy2GpoCpA.png)



* Kiếm được source code js, server sử dụng `JSON.parse` để parse mảng các comment đó rồi bắt đầu xử lý để hiển thị comment.


* Để ý một chút, hàm` escapeHTML()` được sử dụng có chức năng thay thế `<` và `>` lần lượt thành` &lt; và &gt;`. Tuy nhiên, nó chỉ thay thế kí tự đầu tiên nó gặp mà thôi. Có một số thuộc tính của comment sử dụng `escapeHTML()` trong đó có `comment.author`.
![image](https://hackmd.io/_uploads/ry_Q6sAaC.png)


* Tận dụng điều đó, ta sử dụng payload `<><img src=1 onerror=alert(1)>` tại trường Name, chính là `comment.author`. Lúc này chỉ có `<>` bị `escapeHTML` còn `<img src=1 onerror=alert(1)`> vẫn được giữ nguyên.
![image](https://hackmd.io/_uploads/By0VTj0T0.png)



* Submit comment và load lại trang ta thấy có alert xuất hiện. Như vậy ta solve được challenge.
![image](https://hackmd.io/_uploads/HJJI6jApA.png)

### Lab 14: Reflected XSS into HTML context with most tags and attributes blocked
![image](https://hackmd.io/_uploads/rJr26hCp0.png)

* Ứng dụng có chức năng search dính XSS nhưng đã block hầu hết các tags.
![image](https://hackmd.io/_uploads/HJ5_C30aC.png)



* Ta sẽ đi bruteforce tất cả các tag để xem các tag không bị block. Search với từ khóa `<$tag$>` với Intruder.
![image](https://hackmd.io/_uploads/rkgKR20TR.png)



* Kết quả có tag` <body>` trả về 200 → không bị block.
![image](https://hackmd.io/_uploads/rJUc0hA6C.png)



* Ta thử search `<body onload=1>` thì thấy event onload đã bị block.
![image](https://hackmd.io/_uploads/By9cCnCpC.png)



* Tương tự, ta sẽ đi tìm event chưa bị block bằng cách bruteforce.
![image](https://hackmd.io/_uploads/HJUsAhCa0.png)



* Kết quả trả về có 3 event có thể sử dụng được.
![image](https://hackmd.io/_uploads/S1Ti0nA6R.png)



* Ở đây, ta dùng `onresize=print().`
![image](https://hackmd.io/_uploads/H1w303AT0.png)

* Và để trigger XSS mà không cần thao tác người dùng, ta sử dụng `<iframe>` nhằm load body của trang với size khác để kích hoạt onresize:

`<iframe src="https://0a88004004f4b0bec237753300b50012.web-security-academy.net/?search=%3Cbody%20onresize=print()%3E" onload=this.style.width='150px'>`

* Set payload này vào exploit server và gửi cho nạn nhân. Ta solve được challenge khi hàm `print()` đã được gọi.![image](https://hackmd.io/_uploads/HJ5_C30aC.png)

![image](https://hackmd.io/_uploads/r1A20nRTR.png)

### Lab 15: Reflected XSS into HTML context with all tags blocked except custom ones
![image](https://hackmd.io/_uploads/Sk6Z5aATC.png)

Nâng cấp từ bài trên, tất cả các tag trong bài này đều bị block.
![image](https://hackmd.io/_uploads/S1fnd6CT0.png)




Tuy nhiên, trang vẫn chấp nhận các custom tags. Ở đây mình sử dụng tag `<xss>` với payload: `<xss onclick=alert(document.cookie)>aaa</xss>.`
![image](https://hackmd.io/_uploads/r1d2O60aR.png)



Khi click vào dòng aaa, ta thấy alert thành công. Tuy nhiên, để tấn công mà không cần tương tác từ người dùng, ta search với payload sau:

```
<xss id=xss onfocus=alert(document.cookie) tabindex=1>#xss
```

Payload này sẽ khiến nạn nhân khi load trang sẽ tự động tab đến tag có `id=xss` đầu tiên (do `tabindex=1`) và từ đó trigger onfocus → alert thành công.
![image](https://hackmd.io/_uploads/rySJFpCaR.png)



Lúc này, tạo 1 đoạn script chuyển trang đến URL chứa payload trên và lưu vào exploit server.
![image](https://hackmd.io/_uploads/B1i1tp0a0.png)



Thực hiện gửi nó cho nạn nhân và ta solve được challenge.
![image](https://hackmd.io/_uploads/ryggtTRa0.png)

### Lab 16: Reflected XSS with some SVG markup allowed
![image](https://hackmd.io/_uploads/BkJfGCCp0.png)
Thử search với payload chứa tag` <script>` thì thấy bị block.
![image](https://hackmd.io/_uploads/ByMQGCR6C.png)




Dùng Intruder với wordlist tag cho trước để tìm xem các tag nào không bị filter.
![image](https://hackmd.io/_uploads/SJ87zCAa0.png)



Kết quả trả về có 4 tag không bị block là `image, svg, title, animatetransform.`
![image](https://hackmd.io/_uploads/H1oQG00a0.png)



Như vậy, ta có thể sử dụng tag animatetransform trong tag `svg`. Ta tiếp tục dùng Intruder để xem event nào không bị block.
![image](https://hackmd.io/_uploads/BykEzCRaC.png)



Kết quả chỉ có onbegin không bị filter.
![image](https://hackmd.io/_uploads/HJrVGRRpC.png)



Sử dụng nó với payload` <svg><animatetransform onbegin=alert(1)>`, ta solve được challenge.

![image](https://hackmd.io/_uploads/By5VfARaC.png)


#  1 số điều lưu ý:
1. Tool xử lý tìm kiếm, lọc lỗ hổng.
* sast semgrep
* sast sonarqube
