ADD A3 + D1 solution and report

This commit is contained in:
Rémi Heredero 2025-04-20 11:47:01 +02:00
parent 1e7895f21a
commit 3486fd86b1
Signed by: Klagarge
GPG Key ID: 735B36B074A65F0F
24 changed files with 419 additions and 2 deletions

BIN
03-Average3/A3-report.pdf Normal file

Binary file not shown.

88
03-Average3/A3-report.typ Normal file
View File

@ -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!
]

View File

@ -1,6 +1,11 @@
1. What is the algorithm used to check the validity of a password? 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? 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. 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 JFuzhFSI4YShfqE7

0
04-Difficult1/D1 Normal file → Executable file
View File

BIN
04-Difficult1/D1-report.pdf Normal file

Binary file not shown.

117
04-Difficult1/D1-report.typ Normal file
View File

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

3
04-Difficult1/D1.txt Normal file
View File

@ -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

BIN
04-Difficult1/ba Normal file

Binary file not shown.

118
04-Difficult1/code.c Normal file
View File

@ -0,0 +1,118 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
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 <password>\n\n",*param_2);
}
return 1;
}

27
04-Difficult1/script.c Normal file
View File

@ -0,0 +1,27 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
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);
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a82d69e3b15562440310963" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="NAME" TYPE="string" VALUE="D1" />
</BASIC_INFO>
</FILE_INFO>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="Program" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8115b2ef16056574493891" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="NAME" TYPE="string" VALUE="ba" />
</BASIC_INFO>
</FILE_INFO>

Binary file not shown.

Binary file not shown.

View File

@ -5,8 +5,9 @@ VERSION=1
00000007:D1:c0a82d69e3b15562440310963 00000007:D1:c0a82d69e3b15562440310963
00000000:E4:a801f6f84bf5726727918611 00000000:E4:a801f6f84bf5726727918611
00000002:HelloRust:c0a82f6ac5f11262297970056 00000002:HelloRust:c0a82f6ac5f11262297970056
00000008:ba:c0a8115b2ef16056574493891
00000005:liba2.so:c0a82678bad57470710627698 00000005:liba2.so:c0a82678bad57470710627698
/E5.apk /E5.apk
00000004:DebugProbesKt.bin:a947c5a05d160355288677079 00000004:DebugProbesKt.bin:a947c5a05d160355288677079
NEXT-ID:8 NEXT-ID:9
MD5:d41d8cd98f00b204e9800998ecf8427e MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -5,8 +5,9 @@ VERSION=1
00000007:D1:c0a82d69e3b15562440310963 00000007:D1:c0a82d69e3b15562440310963
00000000:E4:a801f6f84bf5726727918611 00000000:E4:a801f6f84bf5726727918611
00000002:HelloRust:c0a82f6ac5f11262297970056 00000002:HelloRust:c0a82f6ac5f11262297970056
00000008:ba:c0a8115b2ef16056574493891
00000005:liba2.so:c0a82678bad57470710627698 00000005:liba2.so:c0a82678bad57470710627698
/E5.apk /E5.apk
00000004:DebugProbesKt.bin:a947c5a05d160355288677079 00000004:DebugProbesKt.bin:a947c5a05d160355288677079
NEXT-ID:8 NEXT-ID:9
MD5:d41d8cd98f00b204e9800998ecf8427e MD5:d41d8cd98f00b204e9800998ecf8427e

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="ProgramUserData" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a82d6804915544445885584" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="NAME" TYPE="string" VALUE="udf_a801f56ab658487152928151" />
</BASIC_INFO>
</FILE_INFO>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="ProgramUserData" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a82d68fef15936786772401" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="NAME" TYPE="string" VALUE="udf_c0a82d69e3b15562440310963" />
</BASIC_INFO>
</FILE_INFO>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FILE_INFO>
<BASIC_INFO>
<STATE NAME="CONTENT_TYPE" TYPE="string" VALUE="ProgramUserData" />
<STATE NAME="PARENT" TYPE="string" VALUE="/" />
<STATE NAME="FILE_ID" TYPE="string" VALUE="c0a8115b28524714328202885" />
<STATE NAME="FILE_TYPE" TYPE="int" VALUE="0" />
<STATE NAME="READ_ONLY" TYPE="boolean" VALUE="false" />
<STATE NAME="NAME" TYPE="string" VALUE="udf_c0a8115b2ef16056574493891" />
</BASIC_INFO>
</FILE_INFO>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
IADD:00000007:/udf_c0a8115b2ef16056574493891
IDSET:/udf_c0a8115b2ef16056574493891:c0a8115b28524714328202885