118 lines
4.4 KiB
Typst
118 lines
4.4 KiB
Typst
#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>
|