Status: Done
Summary
Note
💡 Bypass template routing to reach mediaparser, then abuse EXIF XSS.
Description
Analyst
- Bài này có lỗ hổng XSS ở file
mediaparser. Tuy nhiên file này không được gọi trong các template nên ta cần tìm cách để gọi được template này.
app.get("/fave/:GrandPrixHeaven", async (req, res) => {
const grandPrix = await Configuration.findOne({
where: { public_id: req.params.GrandPrixHeaven },
});
if (!grandPrix) return res.status(400).json({ error: "ERROR: ID not found" });
let defaultData = {
0: "csp",
1: "retrieve",
2: "apiparser",
3: "head_end",
4: "faves",
5: "footer",
};
- Ở đây ta không gọi được
mediaparsernhưng ta có giá trịcustomcó thể thay đổi đoạn này. Đoạn check giá trịcustomnhư sau:

-
Ở đây ta có thể bypass được
parseInt()khi truyền vào 1 string bắt đầu bằng số. Thêm nữa khineedlenhận vàoneedleBodythì có set multipart và boundary mà boundary ta đã biết.
-
Từ đó ta nghĩ đến ý tưởng chèn
mediaparservào giá trịknhư sau:
1_--GP_HEAVENmediaparser--GP_HEAVEN
- Từ đó ta có thể gọi được
mediaparser. - Thêm 1 bước nữa, ở file
mediaparsercó gọi đến classRequester(hàm này từ fileretriev.js).


- Mục tiêu của ta là cần
makeRequesttrả về response là file JPEG, tuy nhiênthis.urlđược set mặc định/api/get-carnên trả về JSON. - Ý tưởng: làm sao để URL fetch được đến
/media/img_idthì sẽ trả về ảnh. Ở đoạn clean URL, regex dùng[A-z](không phải[A-Za-z]) nên có thể bypass vì có các ký tự ở giữa vẫn dùng được.

- Ta có thể sử dụng
\, vì backslash khi được set trong URL sẽ tự chuyển thành forward slash và có thể điều hướng sang media. - Từ đó ta thành công trigger:
https://grandprixheaven-web.2024.ctfcompetition.com/fave/3Pg8TkzJ6ifVyONPKTmNI?F1=\media\ttTE6KozICvAd5-jghfzN
- Tạo 1 file ảnh bằng exiftool với payload XSS và upload lên, sau đó gửi URL cho bot là lấy được flag.
