> For the complete documentation index, see [llms.txt](https://sarpers-organization.gitbook.io/ctftricks/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sarpers-organization.gitbook.io/ctftricks/_chapter-intro-3/obfuscation/multi-stage-decoding/trick-0251.md).

# Multi-stage Data Decoding (Morse + BaseX)

***

Identify the initial custom mapping based on the data and challenge context (e.g., mapping characters like G, T, A found in extracted data to Morse code elements). Decode the source data using this mapping to get the Morse representation. Convert the Morse code to ASCII text.

Examine the resulting ASCII text for clues about subsequent encodings. Common indicators include padding characters (like `=` for Base64) or characteristic character sets. For example, if the ASCII ends with `===`, it likely suggests Base64. Base64 encoded strings tend to end with one or two equals signs (`=`). These are padding characters used to make the encoded string length a multiple of 4 characters. If the last block of input data has only 8 bits (1 byte), two padding characters (`==`) are added. If the last block has 16 bits (2 bytes), one padding character (`=`) is added.

Decode the identified encoding layer (e.g., Base64). The Python `base64` module can be used for this:

```python
import base64

# Example Base64 decoding
encoded_b64 = b'dGVzdA==' # Example with padding
decoded_b64 = base64.b64decode(encoded_b64)
print(decoded_b64) # Output: b'test'

# Decoding from string (input must be bytes)
string_data = 'dGVzdA=='
bytes_data = string_data.encode('ascii')
decoded_from_string = base64.b64decode(bytes_data)
print(decoded_from_string) # Output: b'test'
```

If the output is still unreadable, inspect it again for patterns suggesting another encoding (e.g., Base32). Continue this process, decoding layers in reverse order until the cleartext is recovered. The `base64` module also supports Base32 decoding:

```python
import base64

# Example Base32 decoding
encoded_b32 = base64.b32encode(b'data to be encoded')
decoded_b32 = base64.b32decode(encoded_b32)
print(decoded_b32) # Output: b'data to be encoded'
```

Tools like CyberChef are ideal for chaining these decoding steps. CyberChef also features a 'Magic' operation, useful to manipulate the data, which can often automate the identification and application of decoding steps. The Magic operation attempts to detect encoded data and apply the correct decoding operation automatically. It analyses the input data and scores potential decoding operations based on character frequency, entropy, and other statistical measures. If a decoding operation is found that results in a significant increase in the 'readability' of the data (e.g. reducing entropy, introducing more common characters), it is applied.

Example decoding chain in CyberChef:

1. "From Morse Code"
2. "From Base64"
3. "From Base32"
