Post

Wait a Bit...

Extraire un message caché dans un binaire via un encodage add/nop puis décoder en ASCII.

Wait a Bit...

Catégorie : Stéganographie
Difficulté : Medium
Flag : HACKDAY{n0P_!s_th3_NeW_1}


Photo énoncé
📦
eMule_Optimizer
PDF • 2.3 MB

Énoncé du challenge

Wait a Bit…

The endless wait for your music to download via eMule led you to eMule_Optimizer…
But it seems that it is not working as expected…
Moreover, a multitude of instructions seem to have been ADDED to this otherwise simple code…
There must be something hidden.

flag format: HACKDAY{flag}

sha256 eMule_Optimizer : 0e463c143e6d6902c8d65bc7b6385a2c49f3016950d6b39003a01188bae2ff14


Démarche Reverse

Observation (décompilation / désassemblage)

En décompilant le binaire, on repère une fonction silence qui semble inutile.

Le challenge insiste sur :

  • le mot ADDED (beaucoup de add)
  • l’abus de nop
  • le titre “sound in silence” → message caché dans silence
Nop nop

Règle d’encodage

Le binaire est encodé avec un schéma simple :

PatternBit
add seul0
add suivi immédiatement de nop1

Objectif : reconstruire un flux binaire puis convertir en ASCII.


Extraction de la fonction (objdump)

On sort le désassemblage et on récupère la partie silence :

1
objdump -d eMule_Optimizer > emule.asm

Option pratique : copier/coller le bloc : dans un fichier texte dédié puis on créer un script. Ce script lit silence.txt, extrait les mnemonics, applique la règle add/nop, puis décode en ASCII:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import re

INPUT_FILE = "silence.txt"

# Format objdump attendu:
# "  1177:  01 d0  add %edx,%eax"
mnemo_re = re.compile(r"^\s*[0-9a-f]+:\s+(?:[0-9a-f]{2}\s+)+([a-z.]+)\b", re.I)

mnemonics = []
with open(INPUT_FILE, "r", encoding="utf-8", errors="ignore") as f:
    for line in f:
        m = mnemo_re.match(line.strip())
        if not m:
            continue
        mn = m.group(1).lower()
        mnemonics.append(mn)
        if mn == "ret":
            break

bits = []
i = 0
while i < len(mnemonics):
    mn = mnemonics[i]

    # add / addl / addq / etc.
    if mn.startswith("add"):
        if i + 1 < len(mnemonics) and mnemonics[i + 1] == "nop":
            bits.append("1")
            i += 2
        else:
            bits.append("0")
            i += 1
    else:
        i += 1

bitstream = "".join(bits)

# ASCII: 8 bits -> 1 char
out = []
for j in range(0, len(bitstream), 8):
    byte = bitstream[j:j + 8]
    if len(byte) < 8:
        break
    out.append(chr(int(byte, 2)))

print("".join(out))

Excution du script et sortie:

1
2
3
python3 emule.py

HACKDAY{n0P_!s_th3_NeW_1}

Flag

HACKDAY{n0P_!s_th3_NeW_1}

This post is licensed under CC BY 4.0 by the author.