← Back to Writeups
CUSTOMEasyCrypto

Based base

XESXOR9/2/20264 min read
#crypto#custom#easy#base64_decode#base32_decode#base45_decode#base58_decode#encoding_identification

Based base

Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: base64_decode, base32_decode, base45_decode, base58_decode, encoding_identification

Summary

Walkthrough of the CUSTOM Crypto Based base. Кто-то скажет, что это азы криптографии, основа, фундамент, я же скажу что это база.

Description

Кто-то скажет, что это азы криптографии, основа, фундамент, я же скажу что это база.

(Translation: "Some would say these are the basics of cryptography, the foundation, the fundamentals, but I'd say it's the base.")

Four encoded strings provided:

Q1RGe1RoMXNfMXM=
L5KGQM27MZWEAZ27
Y+8M56E2CZ7D*2CS561WE
RN7Q62szvdozbMe

Flag format: CTF{...}

Analysis

  1. The task name "Based base" and the description heavily hint at Base-N encodings
  2. Four separate encoded strings suggest the flag is split into parts, each encoded with a different Base scheme
  3. Identifying each encoding by its character set:
    • Line 1 Q1RGe1RoMXNfMXM= — trailing = padding is the classic Base64 giveaway
    • Line 2 L5KGQM27MZWEAZ27 — uppercase letters + digits 2-7 only → Base32 charset
    • Line 3 Y+8M56E2CZ7D*2CS561WE — the * character is the key clue; standard Base64/Base32/Base85 don't use *, but Base45 does (used in EU COVID QR certificates, charset: 0-9 A-Z $%*+-./:)
    • Line 4 RN7Q62szvdozbMe — mixed case alphanumeric, but notably missing 0, O, I, l → Base58 (Bitcoin/IPFS alphabet) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Key Insight

The * character in line 3 was the trickiest part to identify. Base45 is less commonly known than Base64/Base32/Base58, but its charset includes * which immediately rules out all other common Base-N encodings. The challenge cleverly escalates from the most common (Base64) to the least common (Base45) encoding.

Decoding Steps

LineEncodedEncodingDecoded
1Q1RGe1RoMXNfMXM=Base64CTF{Th1s_1s
2L5KGQM27MZWEAZ27Base32_Th3_fl@g_
3Y+8M56E2CZ7D*2CS561WEBase45REDACTED
4RN7Q62szvdozbMeBase58b@s1c_B@s3}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Concatenation: CTF{Th1s_1s + _Th3_fl@g_ + REDACTED + b@s1c_B@s3} = CTF{REDACTED}

Solve Script

python
#!/usr/bin/env python3
"""
Based base — TaipanByte CTF
Multi-Base encoding challenge: Base64 + Base32 + Base45 + Base58
"""
import base64

# --- Base45 decoder (RFC 9285) ---
BASE45_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"

def base45_decode(s: str) -> bytes:
    result = []
    for i in range(0, len(s), 3):
        chunk = s[i:i+3]
        values = [BASE45_CHARSET.index(c) for c in chunk]
        if len(values) == 3:
            n = values[0] + values[1] * 45 + values[2] * 45 * 45
            result.extend(divmod(n, 256))
        else:
            n = values[0] + values[1] * 45
            result.append(n)
    return bytes(result)
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# --- Base58 decoder (Bitcoin alphabet) ---
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def base58_decode(s: str) -> bytes:
    n = 0
    for c in s:
        n = n * 58 + BASE58_ALPHABET.index(c)
    result = n.to_bytes((n.bit_length() + 7) // 8, 'big')
    # Handle leading '1's (zero bytes)
    pad = len(s) - len(s.lstrip('1'))
    return b'\x00' * pad + result

# --- Decode all parts ---
part1 = base64.b64decode("Q1RGe1RoMXNfMXM=").decode()
part2 = base64.b32decode("L5KGQM27MZWEAZ27").decode()
part3 = base45_decode("Y+8M56E2CZ7D*2CS561WE").decode()
part4 = base58_decode("RN7Q62szvdozbMe").decode()
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

flag = part1 + part2 + part3 + part4
print(flag)
# CTF{REDACTED}

Output

CTF{REDACTED}

Base Encoding Quick Reference

EncodingCharsetDistinctive Features
Base160-9 A-FHex, always even length
Base32A-Z 2-7Uppercase only, = padding
Base450-9 A-Z $%*+-./:* character, used in COVID QR
Base581-9 A-Z a-z (no 0OIl)No confusable chars, Bitcoin/IPFS
Base64A-Z a-z 0-9 +/= padding, most common
Base85!-u (ASCII 33-117)Printable ASCII, no whitespace
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Lessons Learned

  1. The * character is a dead giveaway for Base45 — no other common Base-N encoding uses it
  2. Base58 deliberately excludes visually ambiguous characters (0/O, I/l) — check for their absence
  3. When a challenge hints at "base" or "basics", always consider multiple Base-N encodings stacked or concatenated
  4. Python's base64 stdlib handles both Base64 and Base32; Base45 and Base58 need custom decoders or pip install base45 base58 ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering base64_decode, base32_decode, base45_decode, base58_decode, encoding_identification was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-02-14 • CUSTOM • Based base • Difficulty: Easy