Current keys: easy: -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEAsJEbaDYkaGjbbFwWi1u2dIHkrvuOeVMZKRsb967Xe3+/as2rgXYn JjIIqRP54VkDodqTPZHowhUM980kyDgKv+4RbpzhhoEEg5Ux/s5Kbd1+pd/WrWTJ BIgOPbuQCBjpyzMic+JJldza6T4xtFL8UQem7nBaVLABGVRUA+bnj+BwD6VU6ARH nKyxEPR7r2EWGRQoXu+ciL3O5dzCbox3H4p0b/+igOBMVDo7pECtgZptVQD6zHQR JjIR3FeHvjn5a2ovr3DMUDpw9l7VlVlr29j9dCp+QZUH0ujCZFmJ8mXVzxMd39x7 nRdzbQgLNXXFPYCLNcOLlMsphxDZtKUQswIDAQAB -----END RSA PUBLIC KEY----- simple: -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA39HZExGvxj/Mok5wVa42caOgrIBZlin1GCdsR4+DdWtILBjVSfzz 51P6VxPg06bjkYBbdRkbRZUZM0Xh6zPYl00nnxoeWLF5s/Af4jFXgX2GmOo9sZlJ sSTimyIjGXMfLa8aiv7NrKj7XFKgnylj2NeMLU4Jk2ZR0YjbnQ8QSNT27UC8iARv Lx+uMWSs+yXky/hR3dCR/jBDTQjd0+qGuPALcQjRa6pgteOj2RbCPKXVPYoIgiA6 X2PnxyCMDN+8OeeH1yWueRnhViHM30V9IWblC6AxKBA10Rw+wpkQa//j+A0wLBwN oz1knL+8dswxkgT1BZzvkHVEpcLZbZWckwIDAQAB -----END RSA PUBLIC KEY----- weak: -----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEA5L/dgmQJk+1FuXWrq7dzis5fLgcFIQyBGHdlDqiwpYALVI+kZA2Q PoktlYQl25z5P8H/PZ9IHzr40x55MuHV3P7O3nL8z6+U40y//QFSC757za6fNRdF d09Mfml24sMWQBV3bvsrHxpLxdKGp0l7VV2CDmPEGj9KsIDempI31jX8/Zv0+ZAQ ReM6XnTxKZmKjoEtKxXQ9x0qRQiNhlK7StgoQk/XvR7kHRPJ4+VjS4Ur20sSDKks 2E5HugCIxPAoVujRywmUs5/9znhqIv8ytFPh6TzmDAPJ5vtapcS/VXD5wRQd8z9C w60MVNDjN7hRNwVpNGDJHlXhdTp5Ku/JaQIDAQAB -----END RSA PUBLIC KEY----- Source: const express = require("express"); const jwt = require("jsonwebtoken"); const { generateKeyPairSync } = require("crypto"); const fs = require("fs"); const SOURCE = fs.readFileSync(__dirname + '/../src/app.ts'); const FLAG = fs.readFileSync(__dirname + "/../src/flag.txt"); //const FLAG = "CTF{dummyflag}" const pems = {}; const kids = ["easy", "simple", "weak"]; kids.forEach((kid) => { var { publicKey, privateKey } = generateKeyPairSync("rsa", { modulusLength: 2048, publicKeyEncoding: { type: "pkcs1", format: "pem" }, }); pems[kid] = publicKey; }); const checkAuth = async function (token) { const decodedJwt = jwt.decode(token, { complete: true }); if (!decodedJwt) { throw Error("Not a valid JWT token"); } const kid = decodedJwt.header.kid; const pem = pems[kid]; if (!pem) { throw Error("Invalid kid"); } jwt.verify(token, pem, {}, (err, payload) => { if (err) { throw err; } }); }; const app = express(); app.get("/", async (req, res) => { res.statusCode = 200; res.setHeader("Content-Type", "text/plain;charset=utf-8"); if (!("token" in req.query)) { res.write("Current keys: \n"); for (let kid in pems) { res.write(kid + ": " + pems[kid] + "\n"); } res.write("Source: \n"); res.end(SOURCE); return; } var token = req.query.token; try { await checkAuth(token); res.end(FLAG); } catch (error) { res.end("Authentication error:\n" + error); } }); const port = 3000; app.listen(port, (err) => { if (err) { return console.error(err); } return console.log(`server is listening on ${port}`); });