Challenge 1: Binary Extension Spoofing and State Overwrite
The initial binary presents itself with a .com file extension, indicating a deliberate attempt to mask its true architecture. Peering into the header reveals a standard executable magic number, confirming it is a valid Linux ELF file. Stripping the misleading extension allows standard dynamic and static analysis tools to recognize and load the file correctly. Loading the binary into a disassembler directs attention to the primary execution routine. Within the main entry point, a critical subroutine handles memory initialization and payload assembly. The routine systematically overwrites a designated buffer before invoking an output mechanism. By tracing the data flow and monitoring register states prior to the final print call, the hidden payload becomes visible. The extracted sequence corresponds to the verification token.
Challenge 2: Control Flow Restoration and Multi-Phase Decryption
Initial static analysis of the second binary fails to generate a pseudo-code view for the entry function due to injected junk instructions that confuse the decompiler. Disassembling the raw bytes reveals several unconditional jumps and invalid opcode sequences scattered throughout the basic block. Manually patching these disruptive instructions (converting conditional jump opcodes to 0x90) restores logical control flow. After cleaning the bytecode, reconstructing the function signature enables proper decompilation.
Phase 1: Spatial Pathfinding
The first validation segment constructs a grid-based traversal puzzle. The algorithm maps movement coordinates against boundary checks. Solving the spatial constraints yields a directional string. Note that naive two-dimensional parsing misses elevation changes; treating the coordinate space as three-dimensional resolves previously ambiguous transitions. The corrected traversal sequence forms the prefix of the final credential.
Phase 2: Bit-Packed Value Recovery
The second segment processes input in quartets. Each group of four ASCII characters undergoes a bitwise reduction: every character is masked to its lower six bits, then sequentially packed into a single twenty-four-bit integer via left shifts. The system compares this packed value against a hardcoded target array. Because the compression is lossless within the six-bit range, a targeted brute-force approach efficiently recovers the original characters.
#include <stdio.h>
#include <stdint.h>
uint8_t source_lookup[256];
const uint32_t targets[3] = {0x736374, 0x665f39, 0x313032};
void initialize_table(void) {
/* Mapping pre-computed byte offsets as referenced in the original binary */
const uint8_t mapped_data[] = {
0x7F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
/* ... truncated for brevity, matches original lookup table ... */
0x7F, 0x00, 0x00, 0x00
};
int idx = 0;
for(int i = 0; i < 256; ++i) {
source_lookup[i] = mapped_data[idx++ % sizeof(mapped_data)];
}
}
int main(void) {
initialize_table();
char decoded[13] = {0};
int offset = 0;
for(int q = 0; q < 3 && offset < 12; ++q) {
for(char c1 = 32; c1 < 128; ++c1) {
for(char c2 = 32; c2 < 128; ++c2) {
for(char c3 = 32; c3 < 128; ++c3) {
for(char c4 = 32; c4 < 128; ++c4) {
uint32_t packed = 0;
packed |= ((uint32_t)(source_lookup[c1] & 0x3F)) << 18;
packed |= ((uint32_t)(source_lookup[c2] & 0x3F)) << 12;
packed |= ((uint32_t)(source_lookup[c3] & 0x3F)) << 6;
packed |= ((uint32_t)(source_lookup[c4] & 0x3F));
if(packed == targets[q]) {
decoded[offset++] = c1;
decoded[offset++] = c2;
decoded[offset++] = c3;
decoded[offset++] = c4;
break;
}
}
}
}
}
}
printf("Recovered Segment: %s\n", decoded);
return 0;
}
Running the solver isolates the exact character combinations, yielding the intermediate hash c2N0Zl85MTAy.
Phase 3: Inverse Rotation-XOR Reconstruction
The final validation layer operates on a linear state array. Input characters are aggregated in to four 32-bit words, which seed the initial computation. The core routine applies a custom substitution-permutation network involving bitwise rotations and XOR diffusion across a fixed lookup matrix. To recover the original plaintext, we must invert the backward propagation chain. Given the terminal four-state values, iterating the inverse operation from index 26 down to 0 reconstructs the complete array. Byte casting the head of the restored array reveals the final plaintext fragment.
#include <stdio.h>
#include <stdint.h>
#define ROTL32(val, n) ((val) << (n) | (val) >> (32 - (n)))
#define ROTR32(val, n) ((val) >> (n) | (val) << (32 - (n)))
uint32_t apply_permutation(uint32_t chunk) {
/* Full 288-element lookup table initialization omitted for brevity */
static uint8_t perm_table[288] = {
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7,
0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05,
/* ... populate with remaining hex values from binary ... */
0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48
};
uint32_t step1 = (perm_table[(chunk >> 16) & 0xFF] << 16) |
perm_table[chunk & 0xFF] |
(perm_table[(chunk >> 8) & 0xFF] << 8) |
(perm_table[(chunk >> 24) & 0xFF] << 24);
return ROTL32(step1, 12) ^ (uint32_t)(ROTL32(step1, 8) ^ ROTR32(step1, 2)) ^ ROTR32(step1, 6);
}
int main(void) {
uint32_t state[30] = {0};
state[26] = 0xBE040680;
state[27] = 0xC5AF7647;
state[28] = 0x9FCC401F;
state[29] = 0xD8BF92EF;
for(int i = 25; i >= 0; --i) {
uint32_t diff = state[i+1] ^ state[i+2] ^ state[i+3];
state[i] = state[i+4] ^ apply_permutation(diff);
}
char final_output[5] = {0};
for(int k = 0; k < 4; ++k) {
final_output[k] = ((char*)state)[k];
}
printf("Final Fragment: %s\n", final_output);
return 0;
}
Combining the corrected three-dimensional maze coordinates, the base-encoded string, and the reconstructed plaintext produces the complete authentication string: flag{ddwwxxssxaxwwaasasyywwdd-c2N0Zl85MTAy(fl4g_is_s0_ug1y!)}.