XOR de Byte Único: Decodificando Hexadecimal e Revertendo uma Chave de Um Byte
O desafio
Um pequeno binário de CTF guarda seu flag como uma string hexadecimal e faz XOR com um byte fixo na inicialização. Você extraiu o hexadecimal abaixo e o byte 0x2a (o caractere '*'). Decodifique o hexadecimal, refaça o XOR e envie o flag (HDNA{...}).
O que você vai aprender
- Reconhecer uma string totalmente hexadecimal como uma camada de transporte em hex
- Decodificar hexadecimal para bytes brutos antes de aplicar uma operação em nível de byte
- Reverter um XOR de byte único com um byte de chave conhecido
- Entender que o XOR é seu próprio inverso
- Explicar por que o XOR de byte único tem apenas 256 chaves e não protege nada
Habilidades testadas
Pré-requisitos
- Facilidade para ler hexadecimal
- Entendimento de que o XOR é seu próprio inverso
Como funciona
Este é o decode em camadas mais simples que existe: uma flag guardada como uma string hexadecimal e submetida a XOR com um único byte. Hexadecimal é apenas uma forma textual de escrever bytes - dois caracteres hexadecimais por byte - então a primeira tarefa é transformar o hexadecimal imprimível de volta nos bytes brutos que ele representa. Esses bytes ainda são ilegíveis porque foram embaralhados com XOR usando um byte fixo.
O XOR é simétrico: aplicar o mesmo byte aos dados uma segunda vez cancela a primeira aplicação, porque A XOR B XOR B = A. Então você faz XOR de cada byte com a chave e o texto puro retorna. Aqui a chave é 0x2a, o caractere ASCII *. Um XOR de byte único tem apenas 256 chaves possíveis, e é por isso que não oferece segurança alguma - um analista pode testar todas em um instante e ficar com o resultado que se lê como texto.
No workbench, adicione From Hex, depois XOR com a chave 0x2a (ou o caractere *), e a flag aparece ao vivo na saída. As outras operações (base64, ROT, atbash, reverse, Vigenere, URL-decode) são iscas - base64 é a armadilha mais próxima, mas a entrada não é base64 válido, então não pode ser aplicada.
Erros comuns
- Tentar base64 em vez de hexadecimal. A entrada é toda composta por caracteres hexadecimais sem padding - decodifique como hexadecimal, não como base64.
- Fazer XOR diretamente no texto hexadecimal. Decodifique o hexadecimal para bytes primeiro, depois faça o XOR desses bytes.
- Digitar a chave errada. 0x2a é o caractere '*' - insira o byte que o workbench espera.
- Supor uma chave maior. É um único byte; uma chave com vários caracteres não vai decodificar corretamente.
Como se proteger
Para defensores e engenheiros reversos, a lição é que o XOR de byte único sobre hexadecimal é o piso da ofuscação - deve ser a primeira coisa que você tenta ao triar um binário pequeno, e nunca deve proteger nada que realmente importe. Se o seu próprio código 'protege' um valor dessa forma, trate esse valor como texto puro.
- Faça brute-force nas 256 chaves possíveis de XOR de byte único contra blobs curtos de hexadecimal ou bytes durante a triagem.
- Decodifique automaticamente wrappers de hexadecimal e base64 antes de examinar os bytes subjacentes.
- Nunca guarde segredos reais como hexadecimal mais um byte de XOR estático - use criptografia autenticada com uma chave gerenciada.
- Mantenha flags e segredos totalmente fora do binário quando o modelo de ameaça exigir isso.