#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"
) <script-xor>
