diff --git a/03-Average3/A3-report.pdf b/03-Average3/A3-report.pdf new file mode 100644 index 0000000..e567758 Binary files /dev/null and b/03-Average3/A3-report.pdf differ diff --git a/03-Average3/A3-report.typ b/03-Average3/A3-report.typ new file mode 100644 index 0000000..1293fc9 --- /dev/null +++ b/03-Average3/A3-report.typ @@ -0,0 +1,88 @@ +#import "@preview/grape-suite:2.0.0": exercise +#import exercise: project, task, subtask +#import "@preview/codly:1.3.0": * +#import "@preview/codly-languages:0.1.1": * +#show: codly-init.with() + +#let task = task.with(numbering-format: (..n) => numbering("1", ..n)) +#let subtask = subtask.with(markers: ("a)", "1)")) + +#show: project.with( + no: 3, + type: "Average", + //suffix-title: "", + + university: [HES-SO Master], + institute: [MSE], + seminar: [SRE], + + author: "Rémi Heredero", + + show-solutions: false, + show-hints: false, + + task-type: [], + + date: datetime.today() +) + +#task[ + What is the algorithm used to check the validity of a password? +][][ + The algorithm is in 2 parts: + - Part 1: Lot of instructions (~30k) to calculate some constants. + - Part 2: Use these constants to calculate each of the 12 letters of the passwords. +] + +#task[ + This program relies on a specific trick. How does it work? +][][ + Most of the code is useless. Only the last instruction is useful. + At the end, the algorithm doesn't provide directly the letters of the password, but the index on a character array. +] + +#task[ + Can you recover the secret password? You must send 1 the valid password by email to pascal+sre25\@mod-p.ch before Apr. 28th, 2025, 12h00 CET to validate this lab and get 10 points. +][][ + JFuzhFSI4YShfqE7 +] + +#task[ + Difficulties encountered during the lab +][][ + I didn't encounter particular difficulties. I quickly identified the main function for the algorithm with Ghidra. I copy past this main function in my IDE (Zed) and change the end of the function with the code bellow to as directly the right password: + + #[ + #set text(size: 8pt) + ```c + pw[0] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar6 >> 0x1a]; + pw[1] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar6 >> 0x14 & 0x3f]; + pw[2] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar6 >> 0xe & 0x3f]; + pw[3] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar6 >> 8 & 0x3f]; + pw[4] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar6 >> 2 & 0x3f]; + pw[5] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[(uVar6 & 3) << 4 | uVar4 >> 0x1c]; + pw[6] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar4 >> 0x16 & 0x3f]; + pw[7] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar4 >> 0x10 & 0x3f]; + pw[8] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar4 >> 10 & 0x3f]; + pw[9] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar4 >> 4 & 0x3f]; + pw[10]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 >> 0x1e | (uVar4 & 0xf) << 2]; + pw[11]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 >> 0x18 & 0x3f]; + pw[12]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 >> 0x12 & 0x3f]; + pw[13]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 >> 0xc & 0x3f]; + pw[14]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 >> 6 & 0x3f]; + pw[15]= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-"[uVar5 & 0x3f]; + ``` + ] + + With that I only print the passowrd at then end + + #[ + #set text(size: 8pt) + ```c + printf("%s\n", password); + ``` + ] + + I test it, and it's work! + +] diff --git a/03-Average3/A3.txt b/03-Average3/A3.txt index 675f952..f4f4554 100644 --- a/03-Average3/A3.txt +++ b/03-Average3/A3.txt @@ -1,6 +1,11 @@ 1. What is the algorithm used to check the validity of a password? +The algorithm is in 2 parts: +- Part 1: Lot of instructions (~30k) to calculate some constants. +- Part 2: Use these constants to calculate each of the 12 letters of the passwords. 2. This program relies on a specific trick. How does it work? +Most of the code is useless. Only the last instruction is useful. +At the end, the algorithm doesn't provide directly the letters of the password, but the index on a character array. 3. Can you recover the secret password? You must send 1 the valid password by email to pascal+sre25@mod-p.ch before Apr. 28th, 2025, 12h00 CET to validate this lab and get 10 points. JFuzhFSI4YShfqE7 diff --git a/04-Difficult1/D1 b/04-Difficult1/D1 old mode 100644 new mode 100755 diff --git a/04-Difficult1/D1-report.pdf b/04-Difficult1/D1-report.pdf new file mode 100644 index 0000000..c52463c Binary files /dev/null and b/04-Difficult1/D1-report.pdf differ diff --git a/04-Difficult1/D1-report.typ b/04-Difficult1/D1-report.typ new file mode 100644 index 0000000..b2ad5c6 --- /dev/null +++ b/04-Difficult1/D1-report.typ @@ -0,0 +1,117 @@ +#import "@preview/grape-suite:2.0.0": exercise +#import exercise: project, task, subtask +#import "@preview/codly:1.3.0": * +#import "@preview/codly-languages:0.1.1": * +#show: codly-init.with() + +#let task = task.with(numbering-format: (..n) => numbering("1", ..n)) +#let subtask = subtask.with(markers: ("a)", "1)")) + +#show: project.with( + no: 1, + type: "Difficult", + //suffix-title: "", + + university: [HES-SO Master], + institute: [MSE], + seminar: [SRE], + + author: "Rémi Heredero", + + show-solutions: false, + show-hints: false, + + task-type: [], + + date: datetime.today() +) +#let code-size = 9pt + +#task[ + What is the flow of the algorithm used to check the validity of a password? +][][ + 1. The application XOR a memory zone with a constant (0x17 in my case). + #[ + #set text(size: code-size) + ```c + __addr[i] = (code)((&DAT_004020c0)[i] ^ 0x17); + ``` + ] + 2. The result of the XOR is put on the protected memory zone on the heap. + #[ + #set text(size: code-size) + ```c + __addr = (code *)valloc(1024); // Allocate memory aligned to page boundary + mprotect(__addr,1024,7); // protect this memory + ``` + ] + 3. It's cast on a function pointer to be executed with the password (_param_2[1]_) filled by the user as parameter. + #[ + #set text(size: code-size) + ```c + DAT_00404098 = (*__addr)(param_2[1]); + ``` + ] + 4. This newly "decrypted" function XOR each char of the password with a specific constant. The result as to be 0 for a valid password, so the password can be extracted as each constant. + #[ + #set text(size: code-size) + ```c + int check_password(char* password) { + return (int)(char)( // Have to be equal to 0 for a good password + password[0] ^ 0x58 | // X + password[1] ^ 0x67 | // g + password[2] ^ 0x6e | // n + password[3] ^ 0x73 | // s + password[4] ^ 0x57 | // W + password[5] ^ 0x45 | // E + password[6] ^ 0x7a | // u + password[7] ^ 0x41 | // A + password[8] ^ 0x74 | // t + password[9] ^ 0x66 | // f + password[10] ^ 0x42 | // B + password[11] ^ 0x6f // o + ); + } + ``` + ] +] + +#task[ + Can you recover the secret password? You must send 1 the valid password by email to pascal+sre25\@mod-p.ch before Apr. 28th, 2025, 12h00 CET to validate this lab and get 30 points +][][ + XgnsWEuAtfBo +] + +#task[ + Difficulties encountered during the lab +][][ + I didn't encounter particular difficulties during the lab. + + I lose a bit of time trying to XOR directly data on Ghidra. I finally, export data from Ghidra, XOR them with a C script (@script-xor) and export the result directly as a binary code in a file. \ + I finally opened this new file on Ghidra to decompile it. + +] +#figure([ + #set text(size: code-size) + ```c + + uint8_t super_function[] = { 0x5f, 0xaf, 0xac, 0x93, 0x9a, 0x87, 0xa3, 0xb1, 0x8e, 0xb5, 0x5f, 0x9e, 0x53, 0x33, 0xe7, 0xd1, 0x53, 0x33, 0xeb, 0x17, 0xd0, 0x53, 0x33, 0xef, 0x80, 0x92, 0xb6, 0x9b, 0x9d, 0x53, 0x33, 0xe7, 0x25, 0x10, 0x23, 0xf4, 0x9d, 0x5b, 0x33, 0xe6, 0x25, 0x58, 0x16, 0x97, 0xe6, 0xf4, 0x1f, 0xd6, 0x9d, 0x53, 0x33, 0xe5, 0x25, 0x50, 0x15, 0x23, 0xf4, 0x9d, 0x43, 0x33, 0xe4, 0x25, 0x40, 0x14, 0x97, 0xe5, 0xf4, 0x1f, 0xd5, 0x1f, 0xdd, 0x9d, 0x53, 0x33, 0xe3, 0x25, 0x50, 0x13, 0x23, 0xf4, 0x9d, 0x5b, 0x33, 0xe2, 0x25, 0x58, 0x12, 0x97, 0xe6, 0xf4, 0x1f, 0xd6, 0x9d, 0x53, 0x33, 0xe1, 0x25, 0x50, 0x11, 0x23, 0xf4, 0x1f, 0xdf, 0x9d, 0x5b, 0x33, 0xe0, 0x25, 0x58, 0x10, 0x1f, 0xc7, 0x9d, 0x43, 0x33, 0xef, 0x25, 0x40, 0x1f, 0x97, 0xe6, 0xf4, 0x97, 0xe5, 0xf4, 0x1f, 0xdd, 0x9d, 0x5b, 0x33, 0xee, 0x25, 0x58, 0x1e, 0x97, 0xe6, 0xf4, 0x1f, 0xc6, 0x9d, 0x43, 0x33, 0xed, 0x25, 0x40, 0x1d, 0x97, 0xe5, 0xf4, 0x1f, 0xdd, 0x9d, 0x5b, 0x33, 0xec, 0x25, 0x58, 0x1c, 0x1f, 0xd5, 0x97, 0xe6, 0xf4, 0x1f, 0xc6, 0x18, 0xa9, 0xd6, 0xd4 }; + + uint8_t main(int argc, char** argv) { + uint8_t length = sizeof(super_function); + uint8_t my_new_byte[length]; + for(uint8_t i = 0; i < length; i++) { + my_new_byte[i] = super_function[i]^0x17; + } + + FILE *fptr = fopen("./test_password", "wb+"); + if(fptr != NULL){ + fwrite(my_new_byte, 1, length, fptr); + fclose(fptr); + } + } + ``` +], +caption: [Script to XOR data from Ghidra], +supplement: "Code" +) diff --git a/04-Difficult1/D1.txt b/04-Difficult1/D1.txt new file mode 100644 index 0000000..757d5e9 --- /dev/null +++ b/04-Difficult1/D1.txt @@ -0,0 +1,3 @@ +1. What is the flow of the algorithm used to check the validity of a password? + +2. Can you recover the secret password? You must send 1 the valid password by email to pascal+sre25@mod-p.ch before Apr. 28th, 2025, 12h00 CET to validate this lab and get 30 points diff --git a/04-Difficult1/ba b/04-Difficult1/ba new file mode 100644 index 0000000..e493e28 Binary files /dev/null and b/04-Difficult1/ba differ diff --git a/04-Difficult1/code.c b/04-Difficult1/code.c new file mode 100644 index 0000000..dae5e63 --- /dev/null +++ b/04-Difficult1/code.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include + +uint32_t* DAT_00404068; +uint64_t* DAT_00404090; + + +void FUN_00401380(undefined4 param_1,undefined8 param_2,undefined8 param_3) + +{ + ulong uVar1; + + _DT_INIT(); + uVar1 = 0; + do { + (*(code *)(&__DT_INIT_ARRAY)[uVar1])(param_1,param_2,param_3); + uVar1 = uVar1 + 1; + } while (uVar1 < 2); + return; +} + + +void _FINI_1(void) + +{ + char local_48 [32]; + ulong local_28; + undefined8 uStack_20; + undefined8 local_18; + undefined1 local_10; + + if (DAT_00404068 == 0) { + if (DAT_00404098 == 0) { + local_10 = 0; + builtin_strncpy(local_48,"\nCongratulations ! The right pas",0x20); + local_18 = 0xa0a292d3a207325; + local_28 = 0x73692064726f7773; + uStack_20 = 0x20646565646e6920; + fprintf(stderr,local_48,DAT_00404090); + } + else { + local_28 = local_28 & 0xffffffffffffff00; + builtin_strncpy(local_48,"\nWrong password ! Try again...\n\n",0x20); + fputs(local_48,stderr); + } + return; + } + return; +} + + +int check_password(char* password) { + return (int)(char)( // Have to be equal to 0 for a good password + password[0] ^ 0x58 | // X + password[1] ^ 0x67 | // g + password[2] ^ 0x6e | // n + password[3] ^ 0x73 | // s + password[4] ^ 0x57 | // W + password[5] ^ 0x45 | // E + password[6] ^ 0x7a | // u + password[7] ^ 0x41 | // A + password[8] ^ 0x74 | // t + password[9] ^ 0x66 | // f + password[10] ^ 0x42 | // B + password[11] ^ 0x6f // o + // XgnsWEuAtfBo + ); +} + + + +int8_t main(int param_1,char* *param_2) { + char *password; + int ret; + size_t pw_length; + code *__addr; + long lVar3; + + if (param_1 == 2) { + password = (char *)param_2[1]; + pw_length = strlen(password); + if (pw_length == 12) { + DAT_00404068 = 0; //4 bytes + DAT_00404090 = password; //8 bytes + + // Allocate memory aligned to page boundary + __addr = (code *)valloc(1024); + + // protect this memory + ret = mprotect(__addr,1024,7); // 0 if successful + + if ((__addr != (code *)0x0) && (ret == 0)) { // If memory right allocated and protected correctly + + for(uint32_t i = 0; i < 169; i++) { + + __addr[i] = (code)((&DAT_004020c0)[i] ^ 0x17); // 1 byte + + } + + DAT_00404098 = (*__addr)(password); // Have to be equal to 0 for a good password + return 1; + } + /* WARNING: Subroutine does not return */ + return(-1); + } + fwrite("\nWrong password ! Try again...\n\n",1,0x20,stderr); + } + else { + fwrite("\nMSE-SRE Challenge D1 --- Enjoy !\n",1,0x22,stderr); + fwrite("\nWhat I need is the right password!\n",1,0x24,stderr); + fprintf(stderr,"\nUsage: %s \n\n",*param_2); + } + return 1; +} diff --git a/04-Difficult1/script.c b/04-Difficult1/script.c new file mode 100644 index 0000000..a82bc69 --- /dev/null +++ b/04-Difficult1/script.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include +#include + +uint8_t super_function[] = { 0x5f, 0xaf, 0xac, 0x93, 0x9a, 0x87, 0xa3, 0xb1, 0x8e, 0xb5, 0x5f, 0x9e, 0x53, 0x33, 0xe7, 0xd1, 0x53, 0x33, 0xeb, 0x17, 0xd0, 0x53, 0x33, 0xef, 0x80, 0x92, 0xb6, 0x9b, 0x9d, 0x53, 0x33, 0xe7, 0x25, 0x10, 0x23, 0xf4, 0x9d, 0x5b, 0x33, 0xe6, 0x25, 0x58, 0x16, 0x97, 0xe6, 0xf4, 0x1f, 0xd6, 0x9d, 0x53, 0x33, 0xe5, 0x25, 0x50, 0x15, 0x23, 0xf4, 0x9d, 0x43, 0x33, 0xe4, 0x25, 0x40, 0x14, 0x97, 0xe5, 0xf4, 0x1f, 0xd5, 0x1f, 0xdd, 0x9d, 0x53, 0x33, 0xe3, 0x25, 0x50, 0x13, 0x23, 0xf4, 0x9d, 0x5b, 0x33, 0xe2, 0x25, 0x58, 0x12, 0x97, 0xe6, 0xf4, 0x1f, 0xd6, 0x9d, 0x53, 0x33, 0xe1, 0x25, 0x50, 0x11, 0x23, 0xf4, 0x1f, 0xdf, 0x9d, 0x5b, 0x33, 0xe0, 0x25, 0x58, 0x10, 0x1f, 0xc7, 0x9d, 0x43, 0x33, 0xef, 0x25, 0x40, 0x1f, 0x97, 0xe6, 0xf4, 0x97, 0xe5, 0xf4, 0x1f, 0xdd, 0x9d, 0x5b, 0x33, 0xee, 0x25, 0x58, 0x1e, 0x97, 0xe6, 0xf4, 0x1f, 0xc6, 0x9d, 0x43, 0x33, 0xed, 0x25, 0x40, 0x1d, 0x97, 0xe5, 0xf4, 0x1f, 0xdd, 0x9d, 0x5b, 0x33, 0xec, 0x25, 0x58, 0x1c, 0x1f, 0xd5, 0x97, 0xe6, 0xf4, 0x1f, 0xc6, 0x18, 0xa9, 0xd6, 0xd4 }; + +uint8_t my_new_byte[169]; + +uint8_t main(int argc, char** argv) { + uint8_t size_of_sf = sizeof(super_function); + printf("Size of super function: %d \n", size_of_sf); + for(uint8_t i = 0; i < size_of_sf; i++) { + my_new_byte[i] = super_function[i]^0x17; + printf("%02x ", my_new_byte[i]); + } + + FILE *fptr = fopen("ba", "wb+"); + + if(fptr != NULL){ + fwrite(my_new_byte, 1, 169, fptr); + fclose(fptr); + } +} diff --git a/SRE.rep/idata/00/00000007.prp b/SRE.rep/idata/00/00000007.prp new file mode 100644 index 0000000..ec0b7b5 --- /dev/null +++ b/SRE.rep/idata/00/00000007.prp @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/SRE.rep/idata/00/00000008.prp b/SRE.rep/idata/00/00000008.prp new file mode 100644 index 0000000..dd2f967 --- /dev/null +++ b/SRE.rep/idata/00/00000008.prp @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/SRE.rep/idata/00/~00000006.db/db.2.gbf b/SRE.rep/idata/00/~00000006.db/db.2.gbf new file mode 100644 index 0000000..ced607a Binary files /dev/null and b/SRE.rep/idata/00/~00000006.db/db.2.gbf differ diff --git a/SRE.rep/idata/00/~00000006.db/db.1.gbf b/SRE.rep/idata/00/~00000007.db/db.3.gbf similarity index 79% rename from SRE.rep/idata/00/~00000006.db/db.1.gbf rename to SRE.rep/idata/00/~00000007.db/db.3.gbf index 09cd3ca..b9e4394 100644 Binary files a/SRE.rep/idata/00/~00000006.db/db.1.gbf and b/SRE.rep/idata/00/~00000007.db/db.3.gbf differ diff --git a/SRE.rep/idata/00/~00000008.db/db.2.gbf b/SRE.rep/idata/00/~00000008.db/db.2.gbf new file mode 100644 index 0000000..7f1d566 Binary files /dev/null and b/SRE.rep/idata/00/~00000008.db/db.2.gbf differ diff --git a/SRE.rep/idata/~index.bak b/SRE.rep/idata/~index.bak index 22e1d76..e82782d 100644 --- a/SRE.rep/idata/~index.bak +++ b/SRE.rep/idata/~index.bak @@ -5,8 +5,9 @@ VERSION=1 00000007:D1:c0a82d69e3b15562440310963 00000000:E4:a801f6f84bf5726727918611 00000002:HelloRust:c0a82f6ac5f11262297970056 + 00000008:ba:c0a8115b2ef16056574493891 00000005:liba2.so:c0a82678bad57470710627698 /E5.apk 00000004:DebugProbesKt.bin:a947c5a05d160355288677079 -NEXT-ID:8 +NEXT-ID:9 MD5:d41d8cd98f00b204e9800998ecf8427e diff --git a/SRE.rep/idata/~index.dat b/SRE.rep/idata/~index.dat index 22e1d76..e82782d 100644 --- a/SRE.rep/idata/~index.dat +++ b/SRE.rep/idata/~index.dat @@ -5,8 +5,9 @@ VERSION=1 00000007:D1:c0a82d69e3b15562440310963 00000000:E4:a801f6f84bf5726727918611 00000002:HelloRust:c0a82f6ac5f11262297970056 + 00000008:ba:c0a8115b2ef16056574493891 00000005:liba2.so:c0a82678bad57470710627698 /E5.apk 00000004:DebugProbesKt.bin:a947c5a05d160355288677079 -NEXT-ID:8 +NEXT-ID:9 MD5:d41d8cd98f00b204e9800998ecf8427e diff --git a/SRE.rep/user/00/00000005.prp b/SRE.rep/user/00/00000005.prp new file mode 100644 index 0000000..1976d6a --- /dev/null +++ b/SRE.rep/user/00/00000005.prp @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/SRE.rep/user/00/00000006.prp b/SRE.rep/user/00/00000006.prp new file mode 100644 index 0000000..ec321fc --- /dev/null +++ b/SRE.rep/user/00/00000006.prp @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/SRE.rep/user/00/00000007.prp b/SRE.rep/user/00/00000007.prp new file mode 100644 index 0000000..956255c --- /dev/null +++ b/SRE.rep/user/00/00000007.prp @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/SRE.rep/user/00/~00000005.db/db.2.gbf b/SRE.rep/user/00/~00000005.db/db.2.gbf new file mode 100644 index 0000000..5ee4092 Binary files /dev/null and b/SRE.rep/user/00/~00000005.db/db.2.gbf differ diff --git a/SRE.rep/user/00/~00000006.db/db.4.gbf b/SRE.rep/user/00/~00000006.db/db.4.gbf new file mode 100644 index 0000000..0fc03c9 Binary files /dev/null and b/SRE.rep/user/00/~00000006.db/db.4.gbf differ diff --git a/SRE.rep/user/00/~00000007.db/db.1.gbf b/SRE.rep/user/00/~00000007.db/db.1.gbf new file mode 100644 index 0000000..ca33990 Binary files /dev/null and b/SRE.rep/user/00/~00000007.db/db.1.gbf differ diff --git a/SRE.rep/user/~journal.dat b/SRE.rep/user/~journal.dat new file mode 100644 index 0000000..f1ce9af --- /dev/null +++ b/SRE.rep/user/~journal.dat @@ -0,0 +1,2 @@ +IADD:00000007:/udf_c0a8115b2ef16056574493891 +IDSET:/udf_c0a8115b2ef16056574493891:c0a8115b28524714328202885