├── Assets ├── README.md └── Banner_Reverse.png ├── Challenge1 ├── Temple ├── Temple.c └── README.md ├── Challenge2 ├── DigIt ├── DigIt.c └── README.md ├── Challenge3 ├── LastWords ├── script.py ├── LastWords.c └── README.md ├── LICENSE └── README.md /Assets/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Challenge1/Temple: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hack-the-void/CTF-Learning-Reverse-Engineering/HEAD/Challenge1/Temple -------------------------------------------------------------------------------- /Challenge2/DigIt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hack-the-void/CTF-Learning-Reverse-Engineering/HEAD/Challenge2/DigIt -------------------------------------------------------------------------------- /Challenge3/LastWords: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hack-the-void/CTF-Learning-Reverse-Engineering/HEAD/Challenge3/LastWords -------------------------------------------------------------------------------- /Assets/Banner_Reverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hack-the-void/CTF-Learning-Reverse-Engineering/HEAD/Assets/Banner_Reverse.png -------------------------------------------------------------------------------- /Challenge1/Temple.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Main function 5 | int main() { 6 | char input[50]; 7 | 8 | printf("Welcome, adventurer. Enter the password to reveal the hidden message: "); 9 | fgets(input, sizeof(input), stdin); 10 | 11 | // Remove newline character 12 | input[strcspn(input, "\n")] = 0; 13 | 14 | if (strcmp(input, "VOID{D1sc0v3r_Th3_Unkn0wn_C0d3}") == 0) { 15 | printf("\nCongratulations! Here is the hidden message:\n"); 16 | printf("\"Knowledge opens the doors to infinity.\"\n"); 17 | } else { 18 | printf("\nIncorrect password. The temple remains silent...\n"); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Challenge3/script.py: -------------------------------------------------------------------------------- 1 | local_28 = 0x6730a39060b0d14 2 | local_20 = 0x710672011d0c7106 3 | local_18 = 0x3f 4 | 5 | def extract_bytes(value, num_bytes=8): 6 | bytes_list = [] 7 | for i in range(num_bytes): 8 | byte = (value >> (i * 8)) & 0xFF 9 | bytes_list.append(byte) 10 | return bytes_list 11 | 12 | def deobfuscate_password(obfuscated_bytes): 13 | password_chars = [] 14 | for byte in obfuscated_bytes: 15 | if byte == 0x00: 16 | break 17 | password_chars.append(chr(byte ^ 0x42)) 18 | return ''.join(password_chars) 19 | 20 | obfuscated_password = extract_bytes(local_28) + extract_bytes(local_20) + extract_bytes(local_18, num_bytes=1) 21 | password = deobfuscate_password(obfuscated_password) 22 | 23 | print("Password:", password) 24 | -------------------------------------------------------------------------------- /Challenge2/DigIt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Declaration of the flag as hidden data 5 | __attribute__((section(".hidden"))) const char hidden_flag[] = { 6 | 'V', 0x00, 7 | 'O', 0x00, 8 | 'I', 0x00, 9 | 'D', 0x00, 10 | '{', 0x00, 11 | 'D', 0x00, 12 | '3', 0x00, 13 | 'L', 0x00, 14 | 'V', 0x00, 15 | '3', 0x00, 16 | 'I', 0x00, 17 | 'N', 0x00, 18 | 'T', 0x00, 19 | '0', 0x00, 20 | '_', 0x00, 21 | 'C', 0x00, 22 | '0', 0x00, 23 | 'D', 0x00, 24 | '3', 0x00, 25 | '}', 0x00, 26 | }; 27 | 28 | int main() { 29 | // The program doesn't display anything obvious 30 | printf("Welcome to the Chronicles of the Forgotten Time.\n"); 31 | printf("Dig deeper to reveal what lies beneath the surface...\n"); 32 | 33 | // Dummy instructions to fill the binary 34 | for (int i = 0; i < 10; i++) { 35 | asm volatile ("nop"); 36 | } 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 0xTheVoid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Challenge3/LastWords.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Program banner 5 | void display_banner() { 6 | printf("=============================================\n"); 7 | printf("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠤⠴⠶⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n"); 8 | printf("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣾⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n"); 9 | printf("⠀⠀⠀⠀⠀⠀⠀⠂⠉⡇⠀⠀⠀⢰⣿⣿⣿⣿⣧⠀⠀⢀⣄⣀⠀⠀⠀⠀⠀⠀\n"); 10 | printf("⠀⠀⠀⠀⠀⠀⢠⣶⣶⣷⠀⠀⠀⠸⠟⠁⠀⡇⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀\n"); 11 | printf("⠀⠀⠀⠀⠀⠀⠘⠟⢹⣋⣀⡀⢀⣤⣶⣿⣿⣿⣿⣿⡿⠛⣠⣼⣿⡟⠀⠀⠀⠀\n"); 12 | printf("⠀⠀⠀⠀⠀⣴⣾⣿⣿⣿⣿⢁⣾⣿⣿⣿⣿⣿⣿⡿⢁⣾⣿⣿⣿⠁⠀⠀⠀⠀\n"); 13 | printf("⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⢸⣿⣿⣿⠿⠇⠀⠀⠀⠀\n"); 14 | printf("⠀⠀⠀⠳⣤⣙⠟⠛⢻⠿⣿⠸⣿⣿⣿⣿⣿⣿⣿⣇⠘⠉⠀⢸⠀⢀⣠⠀⠀⠀\n"); 15 | printf("⠀⠀⠀⠀⠈⠻⣷⣦⣼⠀⠀⠀⢻⣿⣿⠿⢿⡿⠿⣿⡄⠀⠀⣼⣷⣿⣿⠀⠀⠀\n"); 16 | printf("⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣶⣄⡈⠉⠀⠀⢸⡇⠀⠀⠉⠂⠀⣿⣿⣿⣧⠀⠀⠀\n"); 17 | printf("⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣷⣤⣀⣸⣧⣠⣤⣴⣶⣾⣿⣿⣿⡿⠀⠀⠀\n"); 18 | printf("⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀\n"); 19 | printf("⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠟⠛⠉⠀⠀⠀⠀\n"); 20 | printf("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀\n"); 21 | printf("=============================================\n\n"); 22 | printf("<< Last message from the legendary anonymous hacker >>\n"); 23 | printf("The legend says this program holds his final words...\n"); 24 | printf("But only those who know the activation code can read them.\n\n"); 25 | } 26 | 27 | 28 | // Function to check the activation code 29 | int check_code(char *input) { 30 | // Correct password "VOID{H1DD3N_C0D3}" obfuscated with XOR 0x42 31 | char correct_code[] = {0x14, 0xd, 0xb, 0x6, 0x39, 0xa, 0x73, 0x6, 0x6, 0x71, 0xc, 0x1d, 0x1, 0x72, 0x6, 0x71, 0x3f, 0x00}; 32 | 33 | for (int i = 0; correct_code[i] != '\0'; i++) { 34 | if (input[i] != (correct_code[i] ^ 0x42)) { // Compare input with de-obfuscated code 35 | return 0; 36 | } 37 | } 38 | return 1; 39 | } 40 | 41 | int main() { 42 | char input[18] = {0}; // Initialize to 0 to ensure null-termination 43 | 44 | display_banner(); // Display the banner and the lore 45 | 46 | printf("Enter the activation code: "); 47 | scanf("%17s", input); // Limit to 14 characters to prevent overflow 48 | 49 | // Check if the activation code is correct 50 | if (check_code(input)) { 51 | printf("\nAccess granted!\n"); 52 | printf("Here are the final words of the legendary hacker:\n"); 53 | printf("\"Sometimes, what you seek is hidden in the shadows...\"\n"); 54 | } else { 55 | printf("\nIncorrect activation code. The secret remains concealed...\n"); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Banner](Assets/Banner_Reverse.png) 2 | 3 | # 🏴‍☠️ CTF Learning - Reverse Engineering 🏴‍☠️ 4 | 5 | Welcome to the **CTF Learning - Reverse Engineering** repository! This project is designed to help beginners dive into the world of reverse engineering through fun and challenging Capture the Flag (CTF) exercises. 🎉 6 | 7 | ## 🔍 About 8 | This repository contains **3 beginner-friendly CTF challenges** focused on reverse engineering. Each challenge introduces key concepts, techniques, and tools commonly used in reverse engineering to build up your skills progressively. 9 | 10 | ## 🚀 Getting Started 11 | To start your journey with these CTF challenges: 12 | 1. **Clone** this repository. 13 | 2. Explore each challenge folder, where you’ll find: 14 | - Detailed instructions 📄 15 | - Helpful hints 🕵️ 16 | - The C source code for each challenge to understand how they are created! 💻 17 | 18 | By working directly with the source code, you'll gain insight into how reverse engineering challenges are built and learn how to tackle them with confidence. 19 | 20 | ## 📚 Prerequisites 21 | - Nothing 22 | 23 | ## 🏆 Challenges 24 | 25 | Each challenge has a unique theme and story to make your learning experience more enjoyable. Are you ready to face them? 26 | 27 | 1. **Challenge 1: Temple** - 🏛️ Uncover the secrets to open the ancient temple! 28 | 2. **Challenge 2: DigIt** - 💾 Dive deep into binary mysteries! 29 | 3. **Challenge 3: TheLastWords** - ☠️ Discover the final message of a legendary pirate! 30 | 31 | ## 📜 License 32 | This project is licensed under the **MIT License** – see the LICENSE file for details. 33 | 34 | ## 🎉 Happy Reversing! 35 | We hope you have a fantastic time learning and growing your skills with these challenges. Remember, the journey of a thousand bytes begins with a single step! 🐢🚀 36 | 37 | --- 38 | 39 | # 🏴‍☠️ Apprentissage CTF - Reverse Engineering 🏴‍☠️ 40 | 41 | Bienvenue dans le dépôt **Apprentissage CTF - Reverse Engineering** ! Ce projet est conçu pour aider les débutants à plonger dans le monde du reverse engineering à travers des exercices amusants et stimulants de type Capture the Flag (CTF). 🎉 42 | 43 | ## 🔍 À propos 44 | Ce dépôt contient **3 défis CTF pour débutants** centrés sur le reverse engineering. Chaque défi introduit des concepts clés, des techniques et des outils couramment utilisés en reverse engineering, afin de vous aider à développer progressivement vos compétences. 45 | 46 | ## 🚀 Pour commencer 47 | Pour démarrer votre aventure avec ces défis CTF : 48 | 1. **Clonez** ce dépôt. 49 | 2. Explorez chaque dossier de défi, où vous trouverez : 50 | - Des instructions détaillées 📄 51 | - Des indices utiles 🕵️ 52 | - Le code source en C pour chaque défi afin de comprendre comment ils sont créés ! 💻 53 | 54 | En travaillant directement avec le code source, vous découvrirez comment les défis de reverse engineering sont construits et apprendrez à les résoudre en toute confiance. 55 | 56 | ## 📚 Prérequis 57 | - Aucun. 58 | 59 | ## 🏆 Défis 60 | 61 | Chaque défi a un thème et une histoire uniques pour rendre votre expérience d'apprentissage plus agréable. Êtes-vous prêt à les affronter ? 62 | 63 | 1. **Défi 1 : Temple** - 🏛️ Découvrez les secrets pour ouvrir l'ancien temple ! 64 | 2. **Défi 2 : DigIt** - 💾 Plongez dans les mystères du binaire ! 65 | 3. **Défi 3 : Les Derniers Mots** - ☠️ Découvrez le dernier message d'un pirate légendaire ! 66 | 67 | ## 📜 Licence 68 | Ce projet est sous licence **MIT** – consultez le fichier LICENSE pour plus de détails. 69 | 70 | ## 🎉 Bon Reverse Engineering ! 71 | Nous espérons que vous aurez beaucoup de plaisir à apprendre et à développer vos compétences avec ces défis. Rappelez-vous, le voyage de mille octets commence par un seul pas ! 🐢🚀 72 | -------------------------------------------------------------------------------- /Challenge1/README.md: -------------------------------------------------------------------------------- 1 | # 🏛️ Challenge Write-up: Temple 🏛️ 2 | 3 | "Temple" is an extremely simple reverse engineering challenge, designed to help beginners understand basic binary behavior and analysis. 4 | 5 | ## Challenge Overview 6 | 7 | - **Objective:** Find the hidden flag within the program. 8 | - **Difficulty:** Beginner 9 | - **Tools Required:** 10 | - `file` command 11 | - Ghidra (or another disassembler) 12 | 13 | ## Step-by-Step Solution 14 | 15 | ### Step 1: Analyzing the File with `file` 16 | 17 | To begin, check the file type using the `file` command to get basic information about the binary. 18 | 19 | file 20 | 21 | This will give you an overview of the binary format, which helps in understanding the context (e.g., whether it’s a 32-bit or 64-bit ELF binary). 22 | 23 | ### Step 2: Setting Up the Project in Ghidra 24 | 25 | 1. **Create a New Project**: Open Ghidra and create a new project. 26 | 2. **Import the Binary**: Import the program into your Ghidra project. 27 | 3. **Analyze the Binary**: Run the analysis to help Ghidra identify functions, variables, and structures within the binary. 28 | 29 | ### Step 3: Searching for Strings 30 | 31 | Use the **Strings** tool in Ghidra to quickly find any readable text in the binary. In many beginner challenges, flags or hints are stored as strings and can be found by simply viewing the strings in the binary. 32 | 33 | In this case, you should be able to locate the flag directly within the strings section. 34 | 35 | ### Step 4: Extracting the Flag 36 | 37 | The flag is located as a readable string within the binary: 38 | 39 | **Flag: `VOID{D1sc0v3r_Th3_Unkn0wn_C0d3}`** 40 | 41 | --- 42 | 43 | ## Conclusion 44 | 45 | The "Temple" challenge is straightforward and is perfect for beginners who are learning to use basic reverse engineering tools like `file` and Ghidra. It emphasizes the importance of examining strings within a binary, as flags in beginner challenges are often embedded as readable text. 46 | 47 | ### Key Takeaways 48 | - Use `file` to gather information about the binary format. 49 | - Familiarize yourself with Ghidra’s project setup and analysis tools. 50 | - Checking for strings in a binary is a useful starting point in many CTF challenges. 51 | 52 | Good luck, and enjoy the journey into reverse engineering! 🕵️‍♂️ 53 | 54 | --- 55 | 56 | --- 57 | 58 | # 🏛️ Guide de Résolution : Temple 🏛️ 59 | 60 | "Temple" est un challenge de reverse engineering très simple, conçu pour aider les débutants à comprendre le comportement de base d'un binaire et les premières étapes de son analyse. 61 | 62 | ## Présentation du Challenge 63 | 64 | - **Objectif :** Trouver le flag caché dans le programme. 65 | - **Difficulté :** Débutant 66 | - **Outils Requis :** 67 | - Commande `file` 68 | - Ghidra (ou un autre désassembleur) 69 | 70 | ## Solution Étape par Étape 71 | 72 | ### Étape 1 : Analyser le Fichier avec `file` 73 | 74 | Pour commencer, vérifiez le type de fichier avec la commande `file` pour obtenir des informations de base sur le binaire. 75 | 76 | file 77 | 78 | Cela vous donnera un aperçu du format du binaire, ce qui aide à comprendre le contexte (par exemple, s'il s'agit d'un binaire ELF 32 bits ou 64 bits). 79 | 80 | ### Étape 2 : Configurer le Projet dans Ghidra 81 | 82 | 1. **Créer un Nouveau Projet** : Ouvrez Ghidra et créez un nouveau projet. 83 | 2. **Importer le Binaire** : Importez le programme dans votre projet Ghidra. 84 | 3. **Analyser le Binaire** : Lancez l’analyse pour aider Ghidra à identifier les fonctions, les variables et les structures du binaire. 85 | 86 | ### Étape 3 : Rechercher les Chaînes de Caractères 87 | 88 | Utilisez l'outil **Strings** dans Ghidra pour trouver rapidement tout texte lisible dans le binaire. Dans de nombreux challenges pour débutants, les flags ou indices sont stockés sous forme de chaînes de caractères lisibles et peuvent être trouvés en visualisant simplement les chaînes dans le binaire. 89 | 90 | Dans ce cas, vous devriez être en mesure de localiser le flag directement dans la section des chaînes de caractères. 91 | 92 | ### Étape 4 : Extraire le Flag 93 | 94 | Le flag est situé sous forme de chaîne de caractères lisible dans le binaire : 95 | 96 | **Flag : `VOID{D1sc0v3r_Th3_Unkn0wn_C0d3}`** 97 | 98 | --- 99 | 100 | ## Conclusion 101 | 102 | Le challenge "Temple" est simple et parfait pour les débutants qui apprennent à utiliser des outils de base en reverse engineering comme `file` et Ghidra. Il met en avant l'importance de vérifier les chaînes de caractères dans un binaire, car les flags des challenges pour débutants sont souvent intégrés sous forme de texte lisible. 103 | 104 | ### Points Clés 105 | - Utilisez `file` pour recueillir des informations sur le format du binaire. 106 | - Familiarisez-vous avec la configuration de projet et les outils d’analyse de Ghidra. 107 | - Vérifier les chaînes de caractères dans un binaire est souvent une bonne première étape dans de nombreux challenges CTF. 108 | 109 | Bonne chance, et profitez de votre exploration dans le reverse engineering ! 🕵️‍♂️ 110 | -------------------------------------------------------------------------------- /Challenge2/README.md: -------------------------------------------------------------------------------- 1 | # 🏆 Challenge Write-up: Binary Analysis Basics 🏆 2 | 3 | This challenge is designed to focus on binary analysis fundamentals, highlighting the importance of examining the binary directly when other tools don't yield immediate results. 4 | 5 | ## Challenge Overview 6 | 7 | - **Objective:** Find the hidden flag within a binary file. 8 | - **Difficulty:** Beginner 9 | - **Tools Required:** 10 | - ghex (or any hex editor) 11 | - Basic understanding of binary data structures 12 | 13 | ## Step-by-Step Solution 14 | 15 | ### Step 1: Running the Program 16 | 17 | When you execute the program, it displays two sentences, with no other apparent interaction or input required. This output may seem like a dead end, but it’s the first indication that the solution might be hidden within the binary itself. 18 | 19 | ### Step 2: Using `strings` Command 20 | 21 | To start the analysis, try running `strings` on the binary: 22 | 23 | strings 24 | 25 | **Result:** `strings` does not return any interesting or useful output in this case. The flag is not stored as plain text within the binary, so we’ll need to dig deeper. 26 | 27 | ### Step 3: Trying `ltrace` and `strace` 28 | 29 | Next, let's see if `ltrace` or `strace` provides any insights into the program's function calls or system interactions: 30 | 31 | - **ltrace** shows us the library calls, which can help in identifying functions like printf, strcmp, fgets, etc. 32 | 33 | ltrace ./ 34 | 35 | - **strace** logs system calls and signals, giving clues if the program interacts with files, networks, or other system resources. 36 | 37 | strace ./ 38 | 39 | **Result:** Both `ltrace` and `strace` fail to yield any useful information for this challenge. The program appears to be simple and does not make any significant library or system calls related to the flag. 40 | 41 | ### Step 4: Analyzing the Binary with `ghex` 42 | 43 | Since the above tools didn’t give us the flag, it’s time to examine the binary directly using a hex editor like ghex. 44 | 45 | 1. **Open the Binary in ghex:** 46 | 47 | ghex 48 | 49 | 2. **Searching for the Flag Pattern:** 50 | 51 | In ghex, scroll through the hex data and look for any readable ASCII characters that might resemble a flag. In this challenge, the flag is embedded in the binary, but it’s spread across different bytes at regular intervals. 52 | 53 | **Hint:** In CTF challenges, flags are often hidden by separating each character of the flag with padding bytes, making it harder to detect with strings. 54 | 55 | 3. **Identifying the Flag in ghex:** 56 | 57 | As you scroll, you should see a pattern of characters spaced across multiple bytes, resembling this: 58 | 59 | 4C 00 00 47 00 00 48 00 00 7B 00 00 4C 00 00 45 ... 60 | 61 | Converting this hex to ASCII, you’ll notice that every third byte is part of a readable sequence, forming the following flag: 62 | 63 | VOID{D3LV3INTO_C0D3} 64 | 65 | ### Step 5: Extracting the Flag 66 | 67 | By reading only the relevant bytes and ignoring the padding bytes (00), you can reconstruct the flag as follows: 68 | 69 | **Flag: `VOID{D3LV3INTO_C0D3}`** 70 | 71 | --- 72 | 73 | ## Conclusion 74 | 75 | This challenge demonstrates the importance of analyzing the binary directly when common tools like strings, ltrace, and strace don’t reveal useful information. It’s a reminder that flags can be hidden in unconventional ways, such as by spacing out characters with padding bytes. 76 | 77 | ### Key Takeaways 78 | - Don’t rely solely on strings, ltrace, or strace. They’re useful, but not foolproof. 79 | - Examining the binary in a hex editor like ghex can reveal hidden patterns, especially in CTF challenges where flags are obfuscated with spacing. 80 | - Look for readable patterns at regular intervals when you suspect a flag is hidden in the binary itself. 81 | 82 | Good luck with your future binary analysis challenges, and remember: sometimes, the simplest tools can yield the most insights! 🔍 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | # 🏆 Guide de Résolution : Analyse de Binaire de Base 🏆 92 | 93 | Ce challenge est conçu pour se concentrer sur les fondamentaux de l'analyse de binaire, mettant en avant l'importance d'examiner directement le binaire lorsque les autres outils ne donnent pas de résultats immédiats. 94 | 95 | ## Présentation du Challenge 96 | 97 | - **Objectif :** Trouver le flag caché dans un fichier binaire. 98 | - **Difficulté :** Débutant 99 | - **Outils Requis :** 100 | - ghex (ou un autre éditeur hexadécimal) 101 | - Connaissances de base en structures de données binaires 102 | 103 | ## Solution Étape par Étape 104 | 105 | ### Étape 1 : Exécuter le Programme 106 | 107 | Lorsqu’on exécute le programme, il affiche deux phrases sans autre interaction ou entrée requise. Cela peut sembler une impasse, mais c’est la première indication que la solution pourrait être cachée dans le binaire lui-même. 108 | 109 | ### Étape 2 : Utiliser la Commande `strings` 110 | 111 | Pour commencer l'analyse, essayez d'exécuter `strings` sur le binaire : 112 | 113 | strings 114 | 115 | **Résultat :** `strings` ne retourne rien d'intéressant ou d'utile dans ce cas. Le flag n'est pas stocké en texte clair dans le binaire, donc nous devons approfondir l'analyse. 116 | 117 | ### Étape 3 : Essayer `ltrace` et `strace` 118 | 119 | Ensuite, voyons si `ltrace` ou `strace` nous donnent des informations sur les appels de fonctions ou les interactions système du programme : 120 | 121 | - **ltrace** affiche les appels aux bibliothèques, ce qui peut aider à identifier des fonctions comme printf, strcmp, fgets, etc. 122 | 123 | ltrace ./ 124 | 125 | - **strace** enregistre les appels système et les signaux, ce qui peut donner des indices si le programme interagit avec des fichiers, des réseaux ou d'autres ressources système. 126 | 127 | strace ./ 128 | 129 | **Résultat :** Ni `ltrace` ni `strace` ne donnent d’informations utiles pour ce challenge. Le programme semble être simple et ne fait aucun appel significatif aux bibliothèques ou au système en rapport avec le flag. 130 | 131 | ### Étape 4 : Analyser le Binaire avec `ghex` 132 | 133 | Étant donné que les outils précédents n'ont pas révélé le flag, il est temps d'examiner directement le binaire en utilisant un éditeur hexadécimal comme `ghex`. 134 | 135 | 1. **Ouvrir le Binaire dans ghex :** 136 | 137 | ghex 138 | 139 | 2. **Rechercher le Motif du Flag :** 140 | 141 | Dans `ghex`, parcourez les données hexadécimales et recherchez tout caractère ASCII lisible qui pourrait ressembler à un flag. Dans ce challenge, le flag est intégré dans le binaire, mais il est réparti sur différents octets à intervalles réguliers. 142 | 143 | **Indice :** Dans les challenges CTF, les flags sont souvent cachés en séparant chaque caractère du flag par des octets de remplissage, rendant leur détection difficile avec `strings`. 144 | 145 | 3. **Identifier le Flag dans ghex :** 146 | 147 | En faisant défiler, vous devriez voir un motif de caractères espacés sur plusieurs octets, ressemblant à ceci : 148 | 149 | 4C 00 00 47 00 00 48 00 00 7B 00 00 4C 00 00 45 ... 150 | 151 | En convertissant cet hexadécimal en ASCII, vous remarquerez que chaque troisième octet fait partie d’une séquence lisible, formant le flag suivant : 152 | 153 | VOID{D3LV3INTO_C0D3} 154 | 155 | ### Étape 5 : Extraire le Flag 156 | 157 | En lisant uniquement les octets pertinents et en ignorant les octets de remplissage (`00`), vous pouvez reconstituer le flag comme suit : 158 | 159 | **Flag :** `VOID{D3LV3INTO_C0D3}` 160 | 161 | --- 162 | 163 | ## Conclusion 164 | 165 | Ce challenge démontre l'importance d'analyser directement le binaire lorsque des outils courants comme `strings`, `ltrace` et `strace` ne révèlent pas d’informations utiles. Cela rappelle que les flags peuvent être cachés de manière non conventionnelle, par exemple en espaçant les caractères avec des octets de remplissage. 166 | 167 | ### Points Clés 168 | - Ne vous fiez pas uniquement à `strings`, `ltrace` ou `strace`. Ils sont utiles, mais pas infaillibles. 169 | - Examiner le binaire dans un éditeur hexadécimal comme `ghex` peut révéler des motifs cachés, surtout dans les challenges CTF où les flags sont obfusqués par espacement. 170 | - Recherchez des motifs lisibles à intervalles réguliers si vous soupçonnez qu’un flag est caché dans le binaire lui-même. 171 | 172 | Bonne chance pour vos prochains challenges d'analyse de binaire, et rappelez-vous : parfois, les outils les plus simples peuvent fournir les meilleurs indices ! 🔍 173 | -------------------------------------------------------------------------------- /Challenge3/README.md: -------------------------------------------------------------------------------- 1 | # 🔐 Challenge Write-up: The Last Words of the Legendary Hacker 🔐 2 | 3 | In this challenge, you’ll be tasked with bypassing a password check in the program to reveal the hidden message left by a legendary hacker. This exercise focuses on understanding binary behavior, de-obfuscation, and working with Ghidra. 4 | 5 | ## Challenge Overview 6 | 7 | - **Objective:** Retrieve the hidden password and bypass the check to display the secret message. 8 | - **Difficulty:** Intermediate 9 | - **Tools Required:** 10 | - Ghidra (for disassembly and decompilation) 11 | - Python (for scripting and de-obfuscation) 12 | 13 | ## Step-by-Step Solution 14 | 15 | ### Step 1: Running the Program 16 | 17 | When you execute the program, it prompts for a password. If you enter an incorrect password, the program displays an error message and exits. This indicates that there is a specific password we need to input to unlock the secret message. 18 | 19 | ### Step 2: Using `strings` 20 | 21 | Running `strings` on the binary reveals nothing useful. The password is likely obfuscated and needs to be extracted by analyzing the binary code directly. 22 | 23 | Command: 24 | 25 | strings 26 | 27 | ### Step 3: Opening the Program in Ghidra 28 | 29 | 1. **Create a New Project**: Open Ghidra, create a new project, and import the binary. 30 | 2. **Analyze the Program**: Run an analysis to help Ghidra identify functions and structures in the binary. 31 | 3. **Inspecting the `main` Function**: In the `main` function, we observe that it calls a function named `check_code`, which likely verifies the entered password. 32 | 33 | ### Step 4: Analyzing the `check_code` Function 34 | 35 | In the `check_code` function, we notice three key variables: 36 | - `local_28` initialized to `0x6730a39060b0d14` 37 | - `local_20` initialized to `0x710672011d0c7106` 38 | - `local_18` initialized to `0x3f` 39 | 40 | The code iterates over each character, verifying the user input byte by byte with an obfuscated password by XORing each byte with `0x42`. If the comparison matches the obfuscated password, the check passes; otherwise, it fails. 41 | 42 | ### Step 5: Writing a Python Script for De-obfuscation 43 | 44 | The variables `local_28` and `local_20` are 8 bytes each, while `local_18` is 1 byte. We’ll use these to reconstruct the obfuscated password. 45 | 46 | #### Step 5.1: Define Base Variables 47 | 48 | local_28 = 0x6730a39060b0d14 49 | local_20 = 0x710672011d0c7106 50 | local_18 = 0x3f 51 | 52 | #### Step 5.2: Extracting Bytes from the Variables 53 | 54 | Define a function to extract individual bytes from `local_28`, `local_20`, and `local_18`: 55 | 56 | def extract_bytes(value, num_bytes=8): 57 | bytes_list = [] 58 | for i in range(num_bytes): 59 | byte = (value >> (i * 8)) & 0xFF 60 | bytes_list.append(byte) 61 | return bytes_list 62 | 63 | Using this function, extract the bytes from `local_28`, `local_20`, and `local_18`, then combine them to reconstruct the obfuscated password. 64 | 65 | #### Step 5.3: De-obfuscating the Password 66 | 67 | The password is XORed with `0x42`, so we can reverse the obfuscation by XORing each byte with `0x42`. This reveals the actual password. 68 | 69 | def deobfuscate_password(obfuscated_bytes): 70 | password_chars = [] 71 | for byte in obfuscated_bytes: 72 | if byte == 0x00: 73 | break 74 | password_chars.append(chr(byte ^ 0x42)) 75 | return ''.join(password_chars) 76 | 77 | #### Step 5.4: Running the Script 78 | 79 | Combine the extracted bytes and deobfuscate them: 80 | 81 | obfuscated_password = extract_bytes(local_28) + extract_bytes(local_20) + extract_bytes(local_18, num_bytes=1) 82 | password = deobfuscate_password(obfuscated_password) 83 | 84 | The output reveals the password: 85 | 86 | **Password:** `VOID{H1DD3N_C0D3}` 87 | 88 | ### Step 6: Entering the Password in the Program 89 | 90 | Run the program again and enter the password `VOID{H1DD3N_C0D3}` to reveal the hidden message: 91 | 92 | Access granted! 93 | Here are the final words of the legendary hacker: 94 | "Sometimes, what you seek is hidden in the shadows..." 95 | 96 | --- 97 | 98 | ## Conclusion 99 | 100 | This challenge demonstrates the process of analyzing a binary, extracting obfuscated data, and using scripting to reverse engineer the password. It’s a great way to practice working with XOR obfuscation and understand the flow of binary analysis in Ghidra. 101 | 102 | ### Key Takeaways 103 | - Ghidra is useful for analyzing functions, understanding the structure of a program, and examining obfuscated data. 104 | - XOR obfuscation is common in CTF challenges, and it can be reversed if the XOR key is known. 105 | - Python scripting is a powerful tool to automate de-obfuscation and byte extraction. 106 | 107 | Good luck, and remember: sometimes, the secrets are hidden in plain sight! 🔍 108 | 109 | --- 110 | --- 111 | 112 | # 🔐 Guide de Résolution : Les Derniers Mots du Légendaire Hacker 🔐 113 | 114 | Dans ce challenge, vous devez contourner une vérification de mot de passe dans le programme pour révéler le message caché laissé par un hacker légendaire. Cet exercice se concentre sur la compréhension du comportement binaire, la désobfuscation, et l'utilisation de Ghidra. 115 | 116 | ## Présentation du Challenge 117 | 118 | - **Objectif :** Récupérer le mot de passe caché et contourner la vérification pour afficher le message secret. 119 | - **Difficulté :** Intermédiaire 120 | - **Outils Requis :** 121 | - Ghidra (pour la désassemblage et la décompilation) 122 | - Python (pour le script de désobfuscation) 123 | 124 | ## Solution Étape par Étape 125 | 126 | ### Étape 1 : Exécuter le Programme 127 | 128 | Lors de l'exécution du programme, il demande un mot de passe. Si un mot de passe incorrect est entré, le programme affiche un message d'erreur et se ferme. Cela indique qu'il y a un mot de passe spécifique à entrer pour débloquer le message caché. 129 | 130 | ### Étape 2 : Utiliser `strings` 131 | 132 | En exécutant `strings` sur le binaire, aucun résultat utile n'est affiché. Le mot de passe est probablement obfusqué et doit être extrait en analysant directement le code binaire. 133 | 134 | Commande : 135 | 136 | strings 137 | 138 | ### Étape 3 : Ouvrir le Programme dans Ghidra 139 | 140 | 1. **Créer un Nouveau Projet** : Ouvrez Ghidra, créez un nouveau projet et importez le binaire. 141 | 2. **Analyser le Programme** : Lancez une analyse pour aider Ghidra à identifier les fonctions et les structures du binaire. 142 | 3. **Inspection de la Fonction `main`** : Dans la fonction `main`, on observe qu'elle appelle une fonction nommée `check_code`, qui semble vérifier le mot de passe entré. 143 | 144 | ### Étape 4 : Analyser la Fonction `check_code` 145 | 146 | Dans la fonction `check_code`, on remarque trois variables clés : 147 | - `local_28` initialisée à `0x6730a39060b0d14` 148 | - `local_20` initialisée à `0x710672011d0c7106` 149 | - `local_18` initialisée à `0x3f` 150 | 151 | Le code compare chaque caractère en utilisant un XOR avec `0x42` sur chaque octet du mot de passe entré. Si le résultat correspond au mot de passe obfusqué, la vérification est validée ; sinon, elle échoue. 152 | 153 | ### Étape 5 : Écrire un Script pour Désobfusquer le Mot de Passe 154 | 155 | Les variables `local_28` et `local_20` contiennent chacune 8 octets, tandis que `local_18` en contient un seul. Nous utiliserons ces valeurs pour reconstruire le mot de passe obfusqué. 156 | 157 | #### Étape 5.1 : Définir les Variables de Base 158 | 159 | local_28 = 0x6730a39060b0d14 160 | local_20 = 0x710672011d0c7106 161 | local_18 = 0x3f 162 | 163 | #### Étape 5.2 : Extraire les Octets des Variables 164 | 165 | Définissez une fonction pour extraire les octets de `local_28`, `local_20`, et `local_18`. 166 | 167 | def extract_bytes(value, num_bytes=8): 168 | bytes_list = [] 169 | for i in range(num_bytes): 170 | byte = (value >> (i * 8)) & 0xFF 171 | bytes_list.append(byte) 172 | return bytes_list 173 | 174 | Utilisez cette fonction pour extraire les octets de `local_28`, `local_20` et `local_18`, puis combinez-les pour reconstituer le mot de passe obfusqué. 175 | 176 | #### Étape 5.3 : Désobfusquer le Mot de Passe 177 | 178 | Le mot de passe est XORé avec `0x42`, donc on peut inverser l'obfuscation en XORant chaque octet avec `0x42`. Cela révèle le mot de passe original. 179 | 180 | def deobfuscate_password(obfuscated_bytes): 181 | password_chars = [] 182 | for byte in obfuscated_bytes: 183 | if byte == 0x00: 184 | break 185 | password_chars.append(chr(byte ^ 0x42)) 186 | return ''.join(password_chars) 187 | 188 | #### Étape 5.4 : Exécuter le Script 189 | 190 | Combinez les octets extraits et désobfusquez-les. 191 | 192 | obfuscated_password = extract_bytes(local_28) + extract_bytes(local_20) + extract_bytes(local_18, num_bytes=1) 193 | password = deobfuscate_password(obfuscated_password) 194 | 195 | Le mot de passe révélé est : 196 | 197 | **Mot de passe :** `VOID{H1DD3N_C0D3}` 198 | 199 | ### Étape 6 : Entrer le Mot de Passe dans le Programme 200 | 201 | Exécutez de nouveau le programme et entrez le mot de passe `VOID{H1DD3N_C0D3}` pour révéler le message caché : 202 | 203 | Access granted! 204 | Here are the final words of the legendary hacker: 205 | "Sometimes, what you seek is hidden in the shadows..." 206 | 207 | --- 208 | 209 | ## Conclusion 210 | 211 | Ce challenge montre comment analyser un binaire, extraire des données obfusquées et utiliser un script pour faire du reverse engineering sur le mot de passe. C'est un bon moyen de s'entraîner à travailler avec l'obfuscation XOR et à comprendre le flux d'analyse binaire dans Ghidra. 212 | 213 | ### Points Clés 214 | 215 | - Ghidra est utile pour analyser les fonctions, comprendre la structure d'un programme, et examiner les données obfusquées. 216 | - L'obfuscation XOR est courante dans les challenges CTF, et elle peut être inversée si la clé XOR est connue. 217 | - Un script Python est un outil puissant pour automatiser la désobfuscation et l'extraction d'octets. 218 | 219 | Bonne chance, et souvenez-vous : parfois, les secrets sont cachés en pleine vue ! 🔍 220 | 221 | --------------------------------------------------------------------------------