scrambled

Descrição do Desafio:

Categoria: rev Descrição:

I am so close to finding the secret of immortality, however the code has been lost for ages.

I managed to get all the parts back and even got to know that the key to success is one bite of the forbidden fruit (the scrambled eggs!).

Can you help me to decipher the rest?

Arquivos

Arquivo
Descrição

main.py

Código fonte do output.txt. Porém sem a flag e a key.

solve.py

Código em python que resolve a flag.

output.txt

Output gerado pelo main.py.

📥 Download: Arquivos

Passo a Passo da Solução

1. Análise do arquivo fornecido

O desafio fornece tanto o output quanto o código em Python que o gerou. O primeiro passo é analisar esse código para entender como o output foi produzido.

main.py
import random

def encode_flag(flag, key):
    xor_result = [ord(c) ^ key for c in flag] 

    chunk_size = 4
    chunks = [xor_result[i:i+chunk_size] for i in range(0, len(xor_result), chunk_size)] 
    seed = random.randint(0, 10) 
    random.seed(seed) 
    random.shuffle(chunks) 
    
    scrambled_result = [item for chunk in chunks for item in chunk] 
    return scrambled_result, chunks

def main():
    flag = "REDACTED"
    key = "the scrambled eggs!"

    scrambled_result, _ = encode_flag(flag, key)
    print("result:", "".join([format(i, '02x') for i in scrambled_result]))


if __name__ == "__main__":
    main()

Analisando o código, podemos ver que ele é relativamente simples. Ele recebe a flag e a key, dois valores que desconhecemos, e os passa para a função encode_flag().

Essa função executa os seguintes passos:

  • Aplica a operação XOR entre cada caractere da flag com a key.

  • Divide o resultado do XOR em chunks de 4 elementos cada.

  • Embaralha os chunks usando random.shuffle(), com uma seed aleatória entre 0 e 10.

  • Reconstrói uma lista única a partir dos chunks embaralhados.

Por fim, a main() imprime o resultado no formato hexadecimal.

2. Solução

A solução consiste em refazer os passos, mas na ordem reversa. A parte mais desafiadora é reverter o shuffle.

Primeiramente, devemos converter o output hexadecimal para seus valores decimais e agrupá-los em chunks de 4 elementos.

Em seguida, precisamos desfazer o shuffle. Como operações aleatórias com a mesma seed sempre geram o mesmo resultado, podemos simular o embaralhamento dos chunks, mas ao invés de usar os elementos diretamente, usaremos seus índices. Dessa forma, podemos reconstruir a ordem original dos chunks.

Por exemplo, olhe para uma lista de chunks antes e depois do shuffle:

Isso significa que o chunk na terceira posição (índice 2) originalmente estava na primeira posição (índice 0), e assim por diante.

Por fim, basta desfazer o XOR, o que é simples, pois conhecendo dois elementos da operação podemos descobrir o terceiro.

Para descobrir a key, podemos assumir que o 4º caractere da flag é {, pois as flags estão no formato ENO{...}. Dessa forma, basta aplicar o XOR entre { e o quarto caractere decodificado para obter a key.

Flag

Flag: ENO{5CR4M83L3D_3GG5_4R3_1ND33D_T45TY!!!}

Autor da WriteUp

Membro de Exploitation - HenriUz

Atualizado