# VSCTF Write Up [Event Details](https://ctftime.org/event/1658) Ở giải này thì team mình được hạng 33 :+1: ![](https://i.imgur.com/TLsdo2j.png) Đây là write up cho các challs team giải được, mọi người đọc vui # Danh sách các mảng --- - [Web](#Web) - [Baby Eval](#Baby-Eval) - [Forensics](#Forensics) - [Roblox 1](#Roblox-1) - [Roblox 2](#Roblox-2) - [Cryptography](#Cryptography) - [Misc](#Misc) ## Web --- ### Baby Eval Ờ giải này có 3 chall web mà mình làm được có 1 cái chall `Baby eval`, mọi người đọc đỡ: Source: ``` title View Source CTF description Powered by Node.js and Express.js lastUpdate 2022-02-22T22:22:22.222Z source const express = require('express'); const app = express(); function escape(s) { return `${s}`.replace(/./g,c => "&#" + c.charCodeAt(0) + ";"); } function directory(keys) { const values = { "title": "View Source CTF", "description": "Powered by Node.js and Express.js", "flag": process.env.FLAG, "lyrics": "Good job, you’ve made it to the bottom of the mind control facility. Well done.", "createdAt": "1970-01-01T00:00:00.000Z", "lastUpdate": "2022-02-22T22:22:22.222Z", "source": require('fs').readFileSync(__filename), }; return "<dl>" + keys.map(key => `<dt>${key}</dt><dd><pre>${escape(values[key])}</pre></dd>`).join("") + "</dl>"; } app.get('/', (req, res) => { const payload = req.query.payload; if (payload && typeof payload === "string") { const matches = /([\.\(\)'"\[\]\{\}<>_$%\\xu^;=]|import|require|process|proto|constructor|app|express|req|res|env|process|fs|child|cat|spawn|fork|exec|file|return|this|toString)/gi.exec(payload); if (matches) { res.status(400).send(matches.map(i => `<code>${i}</code>`).join("<br>")); } else { res.send(`${eval(payload)}`); } } else { res.send(directory(["title", "description", "lastUpdate", "source"])); } }); app.listen(process.env.PORT, () => { console.log(`Server started on http://127.0.0.1:${process.env.PORT}`); }); ``` - Phần 1: phân tích code - Trong source bao gồm các function: `escape` - này dùng để làm rối code html, `directory` - hàm này hiện thị 1 số value trên màn hình - Và đoạn code cho người dùng nhập thông tin payload vào: ``` const payload = req.query.payload; if (payload && typeof payload === "string") { const matches = /([\.\(\)'"\[\]\{\}<>_$%\\xu^;=]|import|require|process|proto|constructor|app|express|req|res|env|process|fs|child|cat|spawn|fork|exec|file|return|this|toString)/gi.exec(payload); if (matches) { res.status(400).send(matches.map(i => `<code>${i}</code>`).join("<br>")); } else { res.send(`${eval(payload)}`); } } else { res.send(directory(["title", "description", "lastUpdate", "source"])); } ``` - Phần 2: hướng giải quyết Ta có dễ dàng thấy được flag trong function directory tại dòng: `"flag": process.env.FLAG,`, và tại dòng `res.send(directory(["title", "description", "lastUpdate", "source"]));` ta có thể mường tượng được cơ chế hoạt động của hàm `directory(keys)` là in ra value dựa theo key đầu vào, vậy bây giờ ta cần dùng lệnh `directory(flag)` Tiếp theo là bây giờ gửi lệnh như nào? Tại dòng `const payload = req.query.payload;` Vậy ta chỉ cần thêm ở phần sau url `?payload=<querry>`. Kết hợp với phần trên thì payload sẽ là: `?payload=directory(flag)` Nhưng vấn đề gặp ở `preg_match` là không được dùng `( )`. Dựa trên bài viết [này](https://book.hacktricks.xyz/pentesting-web/xss-cross-site-scripting?q=parenthesis) ta có thể bypass bằng cách thay cặp dấu `()` thành `` Sau khi nhập payload vào thì ta thu được flag ![](https://i.imgur.com/f6fIOe9.png) ## Forensics --- Giải này mình thấy khá đầu tư cho các Chall ở mảng Forensics và Misc :v tiếc là mình không làm được nhiều. Series Roblox 1,2,3 thì mình mới chỉ làm ra được 1 với 2 :cry: ### Roblox 1 Description: `The user of this PC has been accused for exploiting on Roblox. We need to find his username for further investigations. Find the username of the main Roblox account used on this system. The flag will be the format of vsctf{username}.` Đầu tiên thì mình mở file image đề cho bằng [FTK Imager](https://go.exterro.com/l/43312/2021-09-13/f5zf7n) Đi tìm thư mục chứa game ở `Users\adminbot6000\AppData\Local\Roblox`. Để tìm username thì mình đơn giản là vào file logs để kiếm tra ![](https://i.imgur.com/FSCWXBK.png) Chúng ta dễ dàng nhìn thấy username có tên là **ftcsvisgreat** `Flag: vsctf{ftcsvisgreat}` ### Roblox 2 Description: `The user of this PC has been using exploits on Roblox! We suspect that he was using an alt account to exploit. Find the name of the game he played on his alt account. The flag will be the format of vsctf{nameofgamewithnospaces} (all lowercase)` Theo như đề bài thì ta cần tìm xem đối tượng đã chơi trò gì trên account phụ của hắn. ![](https://i.imgur.com/dgst8CA.png) - Chúng ta có kha khá file log ở đây nên mình sẽ kiểm tra. Mình để ý là trong cái file log, khi bạn join vào 1 game bất kì thì nó sẽ có output như sau ![](https://i.imgur.com/KoraAfg.png) - Ta có thể sử dụng **placeId** để tìm ra trò chơi bằng cách thêm vào đường dẫn `roblox.com/games/placeId` - Trong các file log thì mình tìm thấy được 1 file với username khác so với username chúng ta tìm được trên câu Roblox 1 ![](https://i.imgur.com/FGECkul.png) Vậy đây chắc chắn là tài khoản phụ mà chúng ta cần tìm, giờ thì chỉ cần coi đối tượng đã chơi game gì. Chúng ta có **placeId** là ![](https://i.imgur.com/MbSxDjR.png). Sử dụng cách mình đề cập ở trên thì chúng ta sẽ biết được tên của trò chơi là gì. ![](https://i.imgur.com/fror0jH.png) `flag: vsctf{themeparktycoon2}` ## Cryptography --- ## Misc --- ###### tags: `vsctf`