Réecriture de l'attaque et amélioration du Makefile

This commit is contained in:
Yohan Simard 2021-02-13 15:51:58 +01:00
parent 758d24ff55
commit 5134979c68
5 changed files with 171 additions and 154 deletions

View file

@ -1,12 +1,12 @@
default:
@echo "Usage : [ Classic | SansCanary | 32bits | 32bitsSansCanary | Attaque ]"
@echo "Usage : [ 64b | 64b_nocanary | 32b | 32b_nocanary ]"
Classic: cleanServCli serveur client
SansCanary: cleanServCli serveurSsCanary client
32bits: cleanServCli serveur32 client32
32bitsSansCanary: cleanServCli serveur32SsCanary client32
64b: clean_serv_client serv64b client64b attaque
64b_nocanary: clean_serv_client serv64b_nocanary client64b attaque
32b: clean_serv_client serv32b client32b attaque
32b_nocanary: clean_serv_client serv32b_nocanary client32b attaque
Attaque: cleanAttaque attaque.c
attaque: attaque.c
@echo "######################################"
@echo "# Compilation du programme ATTAQUANT #"
@echo "######################################"
@ -15,67 +15,67 @@ Attaque: cleanAttaque attaque.c
@echo ""
@echo ""
serveur: Serveur.c
serv64b: serveur.c
@echo "######################################"
@echo "####### Compilation du SERVEUR #######"
@echo "######################################"
@echo ""
gcc -Wall Serveur.c -o serveur
gcc -Wall serveur.c -o serveur
@echo ""
@echo ""
client: Client.c
client64b: client.c
@echo "######################################"
@echo "####### Compilation du CLIENT #######"
@echo "######################################"
@echo ""
gcc -Wall Client.c -o client
gcc -Wall client.c -o client
@echo ""
@echo ""
serveur32: Serveur.c
serv32b: serveur.c
@echo "######################################"
@echo "# Compilation du SERVEUR en 32 bits #"
@echo "######################################"
@echo ""
gcc -Wall -m32 Serveur.c -o serveur
gcc -Wall -m32 serveur.c -o serveur
@echo ""
@echo ""
client32: Client.c
client32b: client.c
@echo "######################################"
@echo "## Compilation du CLIENT en 32 bits ##"
@echo "######################################"
@echo ""
gcc -Wall -m32 Client.c -o client
gcc -Wall -m32 client.c -o client
@echo ""
@echo ""
serveurSsCanary: Serveur.c
serv64b_nocanary: serveur.c
@echo "######################################"
@echo "# Compilation du SERVEUR sans Canary #"
@echo "######################################"
@echo ""
gcc -Wall -fno-stack-protector Serveur.c -o serveur
gcc -Wall -fno-stack-protector serveur.c -o serveur
@echo ""
@echo ""
serveur32SsCanary: Serveur.c
serv32b_nocanary: serveur.c
@echo "#################################################"
@echo "# Compilation du SERVEUR en 32 bits sans Canary #"
@echo "#################################################"
@echo ""
gcc -Wall -m32 -fno-stack-protector Serveur.c -o serveur
gcc -Wall -m32 -fno-stack-protector serveur.c -o serveur
@echo ""
@echo ""
edit:
pluma Serveur.c Client.c Attaque.c &
pluma serveur.c client.c Attaque.c &
cleanAttaque:
clean_attack:
@rm -f attaque
cleanServCli:
clean_serv_client:
@rm -f client serveur
clean: cleanAttaque cleanServCli
clean: clean_attack clean_serv_client

View file

@ -1,24 +1,47 @@
# Projet d'Initiation à la Recherche (PIR) | 4A-IR-SI | INSA Toulouse
Projet d'Initiation à la Recherche (PIR) | 4A-IR-SI | INSA Toulouse
**Membres** :
NOM DU PIR
- Léonie Gallois
- Elies Tali
- Yohan Simard
- Paul Faure
- Nahom Belay
- Jean-Rémy Hok
Membres : (Noms ecrit de mémoire, check orthographe)
- Léonie Gallois
- Elies Tali
- Yohan Simard
- Paul Faure
- Nahom Bellay
- Jean Remi Hok
**Tuteurs** :
Tuteurs :
- Didier LeBotlan
- Eric AlataS
- Didier Le Botlan
- Eric Alata
WARNING : TO USE THE MAKEFILE YOU MAY NEED "gcc-multilib" (sudo apt-get install gcc-multilib)
## Compilation
WARNING : TO USE THE MAKEFILE YOU MAY NEED "gcc-multilib" (`sudo apt-get install gcc-multilib`)
### Commandes make
Ces commandes compileront les trois exécutables client, serveur et attaque.
*Note : le programme attaque est toujours compilé en 64 bits avec canary, car il n'y a pas d'utilité à le compiler autrement.*
#### 64bit, avec canary
`make 64b`
#### 64bit, sans canary
`make 64b_nocanary`
#### 32bit, avec canary
`make 32b`
#### 32bit, sans canary
`make 32b_nocanary`
## Principe général
Programmes SERVEUR et CLIENT, principe général :
- Le serveur : Gere un entier (init 0) En écoute sur un port passé en paramètre, des qu'une connexion arrive, il fork, traite la connexion dans le fils, le père se remet en attente
- Gestion de la connexion : Attends une chaine de caractère du client, et, en fonction de son contenu effectue les actions adéquates
- Chaine attendues :
@ -33,7 +56,7 @@ Programmes SERVEUR et CLIENT, principe général :
* Le serveur copie la chaine reçue avec le read mal fait -> risque de buffer Overflow
* Le serveur fork, l'attaquant peut accumuler de la connaissance
Etapes de dévellopement :
## Étapes de dévelopement
- Step 1 : FAIT
* Le serveur : Gere le nombre de connexions, à chaque connexions, il l'affiche juste.

107
attaque.c
View file

@ -1,69 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define LATENCE 10000
#define FAT_LATENCE 1000000
#define FUNCTION usleep
#define SIZE_BUFF 228
#define NUM_PORT 1258
int main(int argc, char * argv[]) {
char prog_name[30];
sprintf(prog_name, "./client localhost %d", NUM_PORT);
// On ajoute 100 a la valeur
FILE * prog = popen(prog_name, "w");
char prog_name[100];
void runClientWithCommand(char *cmd) {
FILE *prog = popen(prog_name, "w");
FUNCTION(LATENCE);
if (prog == NULL) {
printf("ERREUR\n");
return;
}
fprintf(prog, "%s", cmd);
printf("%s", cmd);
FUNCTION(LATENCE);
fprintf(prog, "ADD\n");
printf("ADD\n");
FUNCTION(LATENCE);
fprintf(prog, "100\n");
printf("100\n");
FUNCTION(LATENCE);
pclose(prog);
// On affiche la valeur
prog = popen(prog_name, "w");
if (prog == NULL) {
printf("ERREUR\n");
}
FUNCTION(LATENCE);
fprintf(prog, "PRINT\n");
printf("PRINT\n");
FUNCTION(LATENCE);
pclose(prog);
// On hack pour RESET
prog = popen(prog_name, "w");
if (prog == NULL) {
printf("ERREUR\n");
}
FUNCTION(LATENCE);
char buff[SIZE_BUFF + 1];
int i;
for (i=0; i<(SIZE_BUFF / 4); i++) {
buff[(i*4)] = 0xef;
buff[(i*4) + 1] = 0xca;
buff[(i*4) + 2] = 0x5c;
buff[(i*4) + 3] = 0x56;
}
buff[SIZE_BUFF] = '\0';
fprintf(prog, "%s\n", buff);
printf("Hack : %s\n%x%x%x%x\n", buff, buff[0], buff[1], buff[2], buff[3]);
FUNCTION(LATENCE);
pclose(prog);
// On Affiche pour verifier
prog = popen(prog_name, "w");
if (prog == NULL) {
printf("ERREUR\n");
}
FUNCTION(LATENCE);
fprintf(prog, "PRINT\n");
printf("PRINT\n");
FUNCTION(LATENCE);
fprintf(prog, "QUIT\n");
printf("QUIT\n");
pclose(prog);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage : ./attaque addresseServeur portServeur\n");
return 2;
}
int port = atoi(argv[2]);
if (port <= 0 || port > 65535) {
printf("Usage : ./attaque addresseServeur portServeur\n");
return 3;
}
sprintf(prog_name, "./client %s %s", argv[1], argv[2]);
// On ecrit 100 a l'index 2
printf("-- Write --\n");
runClientWithCommand("WRITE 100 2\n");
// On affiche la valeur a l'index 1
printf("-- Read --\n");
runClientWithCommand("READ 1\n");
// On affiche le tableau sur le serveur
printf("-- Print --\n");
runClientWithCommand("PRINT\n");
// TODO
// // On hack pour RESET
// printf("-- Hack --\n");
// char buff[SIZE_BUFF + 1];
// int i;
// for (i=0; i<(SIZE_BUFF / 4); i++) {
// buff[(i*4)] = 0xef;
// buff[(i*4) + 1] = 0xca;
// buff[(i*4) + 2] = 0x5c;
// buff[(i*4) + 3] = 0x56;
// }
// buff[SIZE_BUFF] = '\0';
// runClientWithCommand(buff);
}

View file

View file

@ -12,8 +12,8 @@
/* la lib standard */
#include <stdlib.h>
/* pour le fork */
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
/* pour la manipulation des strings */
#include <string.h>
@ -24,18 +24,15 @@
#define NB_SEP 65
#define NB_PAR_LIGNE 16
// printf("BEFORE: %p\n", __builtin_return_address(0));
//printf("BEFORE: %p\n", __builtin_return_address(0));
void handle_sigsegv(int signum)
{
fprintf(stderr,"Signal SIGSEGV (%d) received : SEG FAULT\n", signum);
_exit(0);
void handle_sigsegv(int signum) {
fprintf(stderr, "Signal SIGSEGV (%d) received : SEG FAULT\n", signum);
_exit(0);
}
int min(int a, int b) {
if (a<b) {
if (a < b) {
return a;
} else {
return b;
@ -50,14 +47,14 @@ void print_nb_connexions(int nb_connexions) {
printf("Nouvelle connexion, 2nd connexion\n");
} else {
printf("Nouvelle connexion, %deme connexion\n", nb_connexions);
}
}
printf("L'adresse du nombre de connexions est : %p\n", &nb_connexions);
}
void print_ligne(int * ligne, int n) {
void print_ligne(int *ligne, int n) {
printf("|");
int i;
for (i=0; i<n; i++) {
for (i = 0; i < n; i++) {
printf(" %d |", ligne[i]);
}
printf("\n");
@ -65,41 +62,43 @@ void print_ligne(int * ligne, int n) {
void print_sep() {
int i;
for (i=0; i<NB_SEP; i++) {
for (i = 0; i < NB_SEP; i++) {
printf("-");
}
printf("\n");
}
void print_tab(int * tab, int n) {
void print_tab(int *tab, int n) {
print_sep();
int i;
for (i=0; i<n; i+=NB_PAR_LIGNE) {
print_ligne(&(tab[i]), min(n-i, NB_PAR_LIGNE));
for (i = 0; i < n; i += NB_PAR_LIGNE) {
print_ligne(&(tab[i]), min(n - i, NB_PAR_LIGNE));
print_sep();
}
}
// Fonction lancée a chaque fork
void process(int sock) {
// Tableau des datas du client
// Tableau des datas du client
int tab[SIZE_TAB];
// initialisation (tt a 0)
int i;
for (i=0; i<SIZE_TAB; i++) {
for (i = 0; i < SIZE_TAB; i++) {
tab[i] = 0;
}
int quit = 0;
while (quit == 0) {
// récupération de l'input du client
// récupération de l'input du client
char buff[40] = "\0";
read(sock, buff, 40);
int nbBytesRead = read(sock, buff, 40);
if (nbBytesRead == 0) {
break;
}
char what;
int param1;
int param2;
@ -141,26 +140,24 @@ void process(int sock) {
}
}
int main(int argc, char * argv[]) {
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("ERREUR : Usage : ./serveur N°Port\n");
exit(2);
}
// install a handler for SIGSEGV in a part of your code
if(signal(SIGSEGV,&handle_sigsegv)==SIG_ERR)
{
fprintf(stderr,"Could not install SIGSEGV handler");
return -1;
if (signal(SIGSEGV, &handle_sigsegv) == SIG_ERR) {
fprintf(stderr, "Could not install SIGSEGV handler");
return -1;
}
// On crée le socket local
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("ERREUR lors de la création du socket\n");
exit(1);
}
// On crée le socket local
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("ERREUR lors de la création du socket\n");
exit(1);
}
// On cree l'adresse du socket local
struct sockaddr_in addr_local;
@ -170,42 +167,44 @@ int main(int argc, char * argv[]) {
addr_local.sin_port = atoi(argv[1]);
addr_local.sin_addr.s_addr = INADDR_ANY;
//On bind l'adresse du socket créee avec le socket local
binder = bind(sock,(struct sockaddr *) &addr_local, sizeof(struct sockaddr_in));
if (binder == -1){
printf("ERREUR lors du bind du socket\n");
exit(1);
// On bind l'adresse du socket créee avec le socket local
binder =
bind(sock, (struct sockaddr *) &addr_local, sizeof(struct sockaddr_in));
if (binder == -1) {
printf("ERREUR lors du bind du socket\n");
exit(1);
}
//Initialisation file d'attente
// Initialisation file d'attente
listen(sock, 100);
// Variable de stockage de l'addresse emmeteur
struct sockaddr_in addr_em;
unsigned int longueur_addr_em = sizeof(struct sockaddr_in);
// On se met en état d'acceptation de connexion (et on crée un socket en passant)
int pid = 1;
int nb_connexions = 0;
while (pid != 0){
int sock_connexion = accept(sock, (struct sockaddr *)&addr_em, &longueur_addr_em);
nb_connexions++;
pid = fork();
if (pid == -1){
// On se met en état d'acceptation de connexion (et on crée un socket en
// passant)
int pid = 1;
int nb_connexions = 0;
while (pid != 0) {
int sock_connexion =
accept(sock, (struct sockaddr *) &addr_em, &longueur_addr_em);
nb_connexions++;
pid = fork();
if (pid == -1) {
printf("ERREUR lors du fork\n");
exit(1);
} else if (pid == 0) {
} else if (pid == 0) {
if (sock_connexion == -1) {
printf("ERREUR lors de l'acceptation de la connexion\n");
exit(1);
} else {
printf("ERREUR lors de l'acceptation de la connexion\n");
exit(1);
} else {
// Traitement de la connexion
process(sock_connexion);
}
}
}
return 0;
}
}
return 0;
}