[web] mikufanpage

📌 Intro

처음 웹 사이트에 접속하면 위와 같은 이미지가 보인다.
🔬 Analysis

문제 파일은 위와 같은 디렉토리 구조를 가지고 있으며, 여러개의 miku1.jpg 이미지와 함께 flag.txt가 존재한다.
/image?path=miku1.jpg 로 접속하면 img 하위에 있는 이미지를 조회할 수 있다.

index.html 페이지가 로드될 때 아래와 같이 7개의 이미지를 요청한다.

// app.js const express = require('express'); const path = require('path'); const app = express(); const PORT = process.env.PORT ?? 3000; app.use(express.static(path.join(__dirname, 'public'))); app.listen(PORT, (err) =>{ if(!err) console.log("mikufanpage running on port "+ PORT) else console.log("Err ", err); }); app.get("/image", (req, res) => { console.log(req.query.path); if (req.query.path.split(".")[1] === "png" || req.query.path.split(".")[1] === "jpg") { // only allow images res.sendFile(path.resolve('./img/' + req.query.path)); } else { res.status(403).send('Access Denied'); } });
/image?path=miku1.jpg 와 같이 요청한다고 가정했을 때, req.query.path의 값은 miku1.jpg가 된다.
req.query.path.split(".")을 통해 miku1.jpg는 [ 'miku1', 'jpg' ] 로 split되며,
[1]번째 값을 가져오므로 req.query.path.split(".")[1]의 값은 jpg가 된다.
🎉 Exploit
/image?path=miku1.jpg./../flag.txt 와 같이 입력하면 req.query.path.split(".")을 통해 [ 'miku1', 'jpg', '/', '', '/flag', 'txt' ] 로 split되며, [1]번째 값은 jpg가 되므로 if문을 통과한다.
결국 req.query.path는 miku1.jpg./../flag.txt가 되고 flag를 읽을 수 있다.
🚩 Flag

'🚩 CTF Writeup > osu!gaming CTF 2024' 카테고리의 다른 글
[web] stream-vs (0) | 2024.03.08 |
---|
댓글을 사용할 수 없습니다.