반응형
문제 Docker
해당 문제의 경우 시간 안에는 풀지는 못했지만, 이후 Docker File을 이용하여 Flag를 획득한 문제 입니다. 돌이켜보면, 충분히 풀 수 있었던 문제인데 조급하게 다가갔던 것 같습니다. ㅠㅠ
1. 해당 문제는 URI를 입력하면 headless Browser로 접속을 시도한 뒤, Rendering된 화면을 캡쳐 후 보여주는 서비스가 구현되어 있습니다.
2. 이때 사용자가 입력한 URI는 반드시 http 또는 https로 시작해야 합니다.
router.post('/archiveSave', async (req, res) => {
const { url } = req.body;
if (typeof url !== 'string' ||
!(url.startsWith('http://') || url.startsWith('https://')))
return res.status(400).render('index', { error : 'Invalid URL.' });
try {
await saveArchive(url);
return res.status(200).render('index', { success : `Sucessfully saved archive for ${url}` });
} catch (e) {
console.log(e)
return res.status(500).render('index', { error : 'Oops, an unknown error has occured.' });
}
});
3. http로 시작하는 URI가 정상적으로 입력되었다면, 서버는 http://sandbox.bluearchive.kr:31337에 사용자가 입력한 URI를 url parameter로 포함한 GET 요청을 보내는데, url parameter는 iframe의 src 속성의 값으로 사용됩니다.
const sandbox_url = `http://sandbox.bluearchive.kr:${process.env.PORT}/?url=`
const config = require('./config');
async function saveArchive(url) {
const hash = crypto.createHmac('sha256', config.SECRET).update(url).digest('hex');
const archive_dir = `${config.ARCHIVE_DIR}/${hash}`;
if (!fs.existsSync(archive_dir))
fs.mkdirSync(archive_dir);
const timestamp = moment().format('YYYYMMDDHHmmssSSS');
const archive_path = `${archive_dir}/${timestamp}.${config.ARCHIVE_EXT}`;
const browser = await puppeteer.launch({
executablePath: './chrome/chrome',
ignoreDefaultArgs: true,
args: [
'--headless',
'--diable-gpu',
'--disable-dev-shm-usage',
'--ignore-certificate-errors',
'--hide-scrollbars',
'--window-size=1280,720',
"--js-flags=--noexpose_wasm,--jitless"
],
});
const page = await browser.newPage();
await page.goto(sandbox_url + url, { timeout: 3000 });
await new Promise(resolve => setTimeout(resolve, 3000));
await page.screenshot({
fullPage: true,
path: archive_path,
});
await browser.close();
}
// sandbox index.js
const express = require('express')
const { encode } = require("html-entities");
const app = express()
app.get('/', function (req, res) {
data = `<html>
<head><title>sandbox</title></head>
<body>
<script>
FLAG = "cce2022{this_is_not_real_flag}"
</script>
<iframe src="${encode(req.query.url)}" style="width: 100%; height: 100%; border: 0"></iframe>
</body>
</html>`
res.setHeader("Content-Type","text/html").send(data);
})
app.listen(process.env.PORT);
4. Payload를 아래와 같이 구성하여 webhook.site에 flag를 전송하도록 함으로써 Flag를 획득할 수 있었습니다.
Payload 흐름
http://sandbox.bluearchive.kr:31337/ -> http://sandbox.bluearchive.kr:3133 -> https://webhook.site
전체 Paylaod
'CTF&War Game > CTF' 카테고리의 다른 글
WITHCON 2022 Buffalo [Steal] Write Up (0) | 2022.10.15 |
---|---|
[CCE 2022] BabyWeb Write Up (0) | 2022.09.24 |
[CCE 2022] reborn of php Write Up (0) | 2022.09.24 |
댓글