---
# System prepended metadata

title: XSS

---

## XSS

### XSS-Reflected:

* #### Raw input, không encode gì:

    Chèn thẳng thẻ script vào ô search:
    ![image.png](https://hackmd.io/_uploads/r1j6vgHXp.png)

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

* #### Attribute with angle brackets HTML-encoded:

    Đầu tiên sử dụng payload như phần trên, tuy nhiên không có gì xảy ra. Ta xem source của response trả về:
    
    ![image.png](https://hackmd.io/_uploads/r1AQqZS7T.png)

    Ta thấy angle bracket đã bị encode lại, từ đó payload không thực thi được. Để bypass, ta sử dụng dấu nháy kép, không bị encode khi truyền vào:
    ![image.png](https://hackmd.io/_uploads/rypo9WBmT.png)
    
    Ta sẽ end trường `name` bằng dấu nháy kép, sau đó thêm vào 1 trường mới, ở đây mình sử dụng trường `autofocus onfocus`, sau đó truyền `alert` vào - tức là sẽ popup alert khi ấn vào ô nhập text. Khi truyền payload ta sẽ có attribute input như này:
    ![image.png](https://hackmd.io/_uploads/SklRoWHma.png)
    
    Result:
    ![image.png](https://hackmd.io/_uploads/SkdIhWSm6.png)

* #### JavaScript string with angle brackets HTML encoded:
    Thử với 1 text bất kì, sau đó view source của response, ta thấy thẻ javascript sau sử dụng biến `searchterm` để thực thi:
    ![image.png](https://hackmd.io/_uploads/Hk_uZzHX6.png)
    
    Khi truyền thử payload cơ bản của bài đầu, ta thấy nó đã bị encode lại:
    ![image.png](https://hackmd.io/_uploads/ryjxzMSQp.png)

    Mình sẽ dùng payload sau: `hehe';alert("Hacked");'`
    + `'` để end biến searchterm.
    + `;` để break, nhảy sang line mới.
    + `alert("Hacked");`, dòng mới này gọi alert lên.
    + Và cuối cùng `'` để nối với dấu nháy bị dư thành 1 line rỗng.
    ![image.png](https://hackmd.io/_uploads/ByTJHGBma.png)
    
    Result:
    ![image.png](https://hackmd.io/_uploads/SyJWrzr7p.png)

* #### HTML context with most tags and attributes blocked:

    Thử với payload cơ bản của thẻ script, ta thấy nó bị block:
    ![image.png](https://hackmd.io/_uploads/ryydlUSmT.png)

    Đề cũng nói rằng kha khá tag và thuộc tính bị block, vì vậy ta sẽ bruteforce xem cái nào không bị block. Mình sẽ set position tại search, dùng tag wordlist trên [cheatsheet]([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet). Sau đó kiểm tra xem tag nào trả về 200:
    ![image.png](https://hackmd.io/_uploads/B1wS-8B7p.png)
    
    Ta có tag `Body` không bị block. Mình tiếp tục set pattern như sau để brute được event không bị block bằng cùng event wordlist từ cheatsheet bên trên:
    ![image.png](https://hackmd.io/_uploads/r1RxB8rmp.png)

    Ta có được tương đối nhiều event hợp lệ:
    ![image.png](https://hackmd.io/_uploads/r1LTLLr7p.png)

    Ở đây mình sẽ dùng event `onbeforeinput`, truyền alert vào làm func của onbeforeinput -> exploit thành công. Result:
    ![image.png](https://hackmd.io/_uploads/Bk4ydUS76.png)

### XSS-Stored: 

* #### Raw input, không encode gì:

    Vào comment 1 blog bất kì, post script vào comment, lúc này ta thấy script lưu trữ trong body của page:
    ![image.png](https://hackmd.io/_uploads/r1aOTPdm6.png)
    
    Result:
    ![image.png](https://hackmd.io/_uploads/rJ5qpPdQT.png)


* #### anchor href attribute with double quotes HTML-encoded:
    Để ý khi post comment bất kì, trường `website` sẽ được lưu lại tại href với dấu nháy kép bị encode:
    ![image.png](https://hackmd.io/_uploads/r1qTdOuQT.png)
    
    Vậy, ta sẽ thử link href với payload, và sử dụng nháy đơn để bypass:
    ![image.png](https://hackmd.io/_uploads/rydZt_ump.png)
    
    Result khi gọi tới người dùng đó:
    ![image.png](https://hackmd.io/_uploads/r1KBKd_X6.png)

### XSS-DOM:

* #### document.write sink using source location.search:
    View Source của page response về khi search, `document.write` concate chuỗi để write ra:
    ![image.png](https://hackmd.io/_uploads/SJXXiCum6.png)

    Lợi dụng concate, ta sẽ đóng thẻ img lại và chèn payload:
    ![image.png](https://hackmd.io/_uploads/Sy1ERRdXa.png)

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

* ####  innerHTML sink using source location.search:

    ![image](https://hackmd.io/_uploads/SJ86AQy46.png)
    
    Biến query lấy giá trị tham số search từ URL qua hàm URLSearchParams(). Nếu query khác rỗng thì gọi innerHTML để đổi trường searchMessage thành query.
    
    Vì chỉ khi true mới thực hiện như kia, nên ta sẽ tận dụng hàm onerror, lợi dụng hướng kích hoạt false để hàm này thực hiện được, từ đó sẽ trigger alert gọi tiếp bên trong. Payload: `<img src=1 onerror=alert("Hacked")>`
    
    Result:
    ![image](https://hackmd.io/_uploads/SyCvgVk4p.png)
