ADD A3 + D1 solution and report
This commit is contained in:
0
04-Difficult1/D1
Normal file → Executable file
0
04-Difficult1/D1
Normal file → Executable file
BIN
04-Difficult1/D1-report.pdf
Normal file
BIN
04-Difficult1/D1-report.pdf
Normal file
Binary file not shown.
117
04-Difficult1/D1-report.typ
Normal file
117
04-Difficult1/D1-report.typ
Normal 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
3
04-Difficult1/D1.txt
Normal 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
BIN
04-Difficult1/ba
Normal file
Binary file not shown.
118
04-Difficult1/code.c
Normal file
118
04-Difficult1/code.c
Normal 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
27
04-Difficult1/script.c
Normal 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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user