Extract the XOR Key: Reversing a Hardcoded C License Check
O desafio
Este keygen em C lê um número de série, aplica XOR em cada byte com um segredo embutido e compara o resultado a um alvo. Leia o laço de validação, descubra qual string é usada como chave XOR e digite-a exatamente.
O que você vai aprender
- Read a C validation loop and identify the byte-by-byte XOR step
- Recognise a hardcoded string literal used as a cryptographic key
- Understand why XOR is reversible and how to recover the original input
- Explain why secrets shipped inside a client binary are not secret
- Distinguish obfuscation from real cryptographic protection
Habilidades testadas
Pré-requisitos
- Basic C syntax (arrays, loops, pointers)
- What the XOR (^) operator does
- Bytes and ASCII
Como funciona
Many license checks try to hide the valid serial behind a transformation. A common one is XOR: each byte of the user's input is XORed with a key byte, and the result is compared to a precomputed table. XOR is attractive because it is fast and symmetric, but symmetry is exactly why it fails as protection - the same operation that scrambles the data unscrambles it.
In keygen.c, check_serial declares const char *key = "K3yR3v" and loops over the serial, computing serial[i] ^ key[i % klen] and comparing each result to expected[i]. Everything the check needs is in the binary: the key string, the expected table, and the algorithm. Because (serial ^ key) == expected implies serial == expected ^ key, an attacker reads the key off the source and instantly computes a valid serial - no brute force required.
The takeaway for reverse engineering is that the answer is sitting in plain sight as a string literal. The challenge is recognising that the loop's XOR operand is the key, not the expected table (that is the target) and not the serial (that is attacker input). The key here is K3yR3v.
Erros comuns
- Submitting the expected[] bytes. That table is the target the XOR result is compared against, not the key.
- Looking for the key in main(). The key is a local in
check_serial;mainonly reads argv and prints the verdict. - Assuming the key is random or derived. It is a plain string literal hardcoded in the source.
- Confusing the serial with the key. The serial is attacker input (argv[1]); the key is the constant it is XORed against.
Como se proteger
Client-side XOR is obfuscation, not security. Anyone with the binary can read the key. Do not rely on a hidden constant to protect licensing or secrets.
- Validate licenses server-side, where the secret and the check never reach the user.
- If you must verify locally, use signed tokens (asymmetric crypto) so the client holds only a public key and cannot forge valid serials.
- Never store API keys or signing keys as plaintext string literals in shipped code.
- Treat anything compiled into a client as fully readable by an attacker.