~/tiramisaks
← back to /home

Custom Encoding: Cipher Stream Analysis

GEMASTIK XIX 2026-08-23 Cryptography / Reverse Engineering
#GEMASTIK19 #Custom Encoding #Binary #Bit Substitution #Crypto

Detailed Writeup: Custom Substitution / Binary Cipher (cipher (1).txt)

Executive Summary & Flag

  • Challenge Name: Custom DogSpeak / Binary Substitution Cipher
  • Category: Cryptography / Classical Substitution & Encoding
  • Source File: C:\Users\Vide21\Downloads\cipher (1).txt
  • Extracted Flag: GEMASTIK19{TUTOR!!_submit-crypto-flag_D0ng}

1. Challenge Overview & Reconnaissance

File ciphertext (cipher (1).txt) berisi satu baris string kontinu berukuran 701 byte:

SOOHOHHDWOOHOOODWOOHOHHDWOOHOHODWOOHOHHDWOOHHOHHDWOOHOHHDWOOHHHODWOOHOHODWOOHHOODWOOHOHODWOOHOHHDWOOHOHHDWOOOHHODWOOHOHHDWOOHHHOHDWOOHHOODWOOHHHODWOOHHOODWOOOHHODWOOHOOODWOOHHHOHDWOOHOHODWOOHOHHDWOOHOHODWOOHOHODWOOHOHODWOOHOHHDWOOHOHHDWOOHHOOHDWOOHOHODWOOHHOHDWOOHHOHDWOOHHHODWOOHHOHDWOOHHHODWOOHOHODWOOHHOOHDWOOHOOODWOOHHOODWOOHOOODWOOHOHODWOOHOOHDWOOHHOHDWOOHOOHDWOOHHOHHDWOOHOOHDWOOOHHODWOOHOOODWOOHOHHDWOOHHOHDWOOHHOHHDWOOHOOHDWOOHHOODWOOHOOODWOOHHOHDWOOHOOODWOOOHHODWOOHOOODWOOHHHHDWOOHOOODWOOHOHHDWOOHOOHDWOOHHOOHDWOOHHOHDWOOHHOHHDWOOHOOHDWOOHOOHDWOOHOOHDWOOHHHOODWOOHOOHDWOOHHHODWOOHOOHDWOOHOOODWOOHOHODWOOHHOOHDWOOHOHHDWOOHOHHDWOOHHOODWOOHHHHDWOOHOOHDWOOHHOHODWOOHOOHDWOOHOOODWOOHOOODWOOHHOHHZ

Analisa Struktur & Alfabet:

  1. Header & Trailer (Start/End Markers):
    • Karakter pertama adalah S (Start / Beginning of Message).
    • Karakter terakhir adalah Z (End / Termination of Message).
  2. Delimiter (Pemisah Token):
    • Di antara S dan Z, string terbagi secara teratur oleh substring pemisah DW.
    • Terdapat 86 token biner yang dipisahkan oleh DW.
  3. Encoding Bit (Karakter ‘O’ dan ‘H’):
    • Setiap token hanya terdiri dari karakter O dan H.
    • Karakter O mewakili bit 1.
    • Karakter H mewakili bit 0.

2. Mathematical Formulation & Decoding Rules

A. Token Splitting

Secara matematis, ciphertext CC dapat direpresentasikan sebagai gabungan: C=’S’T1’DW’T2’DW’’DW’T86’Z’C = \text{'S'} \parallel T_1 \parallel \text{'DW'} \parallel T_2 \parallel \text{'DW'} \parallel \dots \parallel \text{'DW'} \parallel T_{86} \parallel \text{'Z'}

Di mana setiap token Ti{’O’,’H’}T_i \in \{ \text{'O'}, \text{'H'} \}^*.

B. Binary Substitution Mapping

Setiap karakter cTic \in T_i dipetakan ke dalam bit b{0,1}b \in \{0, 1\} dengan pemetaan bit invers: f(c)={1jika c=’O’0jika c=’H’f(c) = \begin{cases} 1 & \text{jika } c = \text{'O'} \\ 0 & \text{jika } c = \text{'H'} \end{cases}

Sehingga token Ti=(ci,1,ci,2,,ci,k)T_i = (c_{i,1}, c_{i,2}, \dots, c_{i,k}) menjadi string biner Bi=(bi,1,bi,2,,bi,k)B_i = (b_{i,1}, b_{i,2}, \dots, b_{i,k}).

C. Base-2 to Decimal / ASCII Conversion

Setiap string biner BiB_i dikonversi ke nilai desimal ViV_i menggunakan rumus nilai posisi biner (Positional Base-2 Notation): Vi=j=1kbi,j2kjV_i = \sum_{j=1}^{k} b_{i,j} \cdot 2^{k - j}

Nilai ViV_i kemudian diubah menjadi karakter ASCII AiA_i: Ai=chr(Vi)A_i = \text{chr}(V_i)


C.1. Bukti Penghitungan Nyata (Step-by-Step Proof from Real Cipher Data)

Berikut adalah bukti konkret jabaran matematis langkah-demi-langkah menggunakan 4 token pertama asli dari file cipher (1).txt:

1. Token 1 (T1="OOHOHH"T_1 = \text{"OOHOHH"})

  • Substitusi Bit (O=1,H=0O=1, H=0): b1="110100"b_1 = \text{"110100"} (Panjang bit k=6k=6).
  • Jabaran Pangkat Posisi Biner: V1=(1261)+(1262)+(0263)+(1264)+(0265)+(0266)V_1 = (1 \cdot 2^{6-1}) + (1 \cdot 2^{6-2}) + (0 \cdot 2^{6-3}) + (1 \cdot 2^{6-4}) + (0 \cdot 2^{6-5}) + (0 \cdot 2^{6-6}) V1=(132)+(116)+(08)+(14)+(02)+(01)V_1 = (1 \cdot 32) + (1 \cdot 16) + (0 \cdot 8) + (1 \cdot 4) + (0 \cdot 2) + (0 \cdot 1) V1=32+16+0+4+0+0=52V_1 = 32 + 16 + 0 + 4 + 0 + 0 = \mathbf{52}
  • Konversi ASCII: A1=chr(52)=’4’A_1 = \text{chr}(52) = \mathbf{\text{'4'}}

2. Token 2 (T2="OOHOOO"T_2 = \text{"OOHOOO"})

  • Substitusi Bit (O=1,H=0O=1, H=0): b2="110111"b_2 = \text{"110111"} (Panjang bit k=6k=6).
  • Jabaran Pangkat Posisi Biner: V2=(132)+(116)+(08)+(14)+(12)+(11)V_2 = (1 \cdot 32) + (1 \cdot 16) + (0 \cdot 8) + (1 \cdot 4) + (1 \cdot 2) + (1 \cdot 1) V2=32+16+0+4+2+1=55V_2 = 32 + 16 + 0 + 4 + 2 + 1 = \mathbf{55}
  • Konversi ASCII: A2=chr(55)=’7’A_2 = \text{chr}(55) = \mathbf{\text{'7'}}

3. Token 3 (T3="OOHOHH"T_3 = \text{"OOHOHH"})

  • Substitusi Bit (O=1,H=0O=1, H=0): b3="110100"b_3 = \text{"110100"}
  • Jabaran Pangkat Posisi Biner: V3=32+16+0+4+0+0=52V_3 = 32 + 16 + 0 + 4 + 0 + 0 = \mathbf{52}
  • Konversi ASCII: A3=chr(52)=’4’A_3 = \text{chr}(52) = \mathbf{\text{'4'}}

4. Token 4 (T4="OOHOHO"T_4 = \text{"OOHOHO"})

  • Substitusi Bit (O=1,H=0O=1, H=0): b4="110101"b_4 = \text{"110101"}
  • Jabaran Pangkat Posisi Biner: V4=32+16+0+4+0+1=53V_4 = 32 + 16 + 0 + 4 + 0 + 1 = \mathbf{53}
  • Konversi ASCII: A4=chr(53)=’5’A_4 = \text{chr}(53) = \mathbf{\text{'5'}}

Penggabungan Karakter Hasil Token 1 - 4:

A1A2A3A4="4745"A_1 A_2 A_3 A_4 = \text{"4745"} (Dua pasangan karakter Hex pertama: "47" mewakili ASCII 'G' dan "45" mewakili ASCII 'E').


D. Hexadecimal Unpacking (Final Step)

Hasil konversi awal dari 86 token menghasilkan string Hexadecimal ASCII sepanjang 86 karakter: Hex String="47454d415354494b31397b5455544f5221215f7375626d69742d63727970746f2d666c61675f44306e677d"\text{Hex String} = \text{"47454d415354494b31397b5455544f5221215f7375626d69742d63727970746f2d666c61675f44306e677d"}

Mengelompokkan hex string ke dalam pasangan nibbles (22 karakter hex = 11 byte plaintext): Bytem=val(Hex2m1)×16+val(Hex2m)\text{Byte}_m = \text{val}(\text{Hex}_{2m-1}) \times 16 + \text{val}(\text{Hex}_{2m})

Maka 43 pasang byte hex dikonversi menjadi plaintext final: Plaintext="GEMASTIK19{TUTOR!!_submit-crypto-flag_D0ng}"\text{Plaintext} = \text{"GEMASTIK19\{TUTOR!!\_submit-crypto-flag\_D0ng\}"}


3. Python Solve Script

Berikut adalah skrip lengkap dalam Python untuk menyelesaikan dan mendekode ciphertext secara otomatis:

#!/usr/bin/env python3

def solve_cipher(file_path):
    # 1. Read raw ciphertext data
    with open(file_path, 'r') as f:
        data = f.read().strip()
    
    # 2. Strip Start ('S') and End ('Z') markers
    body = data[1:-1]
    
    # 3. Split by delimiter 'DW'
    tokens = body.split('DW')
    
    # 4. Map 'O' -> 1 and 'H' -> 0
    bit_map = {'O': '1', 'H': '0'}
    hex_chars = []
    
    for t in tokens:
        binary_str = ''.join(bit_map[c] for c in t)
        decimal_val = int(binary_str, 2)
        hex_chars.append(chr(decimal_val))
    
    # 5. Join hex ASCII representation
    hex_data = ''.join(hex_chars)
    print(f"[+] Intermediate Hex Output (86 chars): {hex_data}")
    
    # 6. Decode Hex to Plaintext Flag
    flag = bytes.fromhex(hex_data).decode('utf-8')
    print(f"[🎉] Decoded Flag: {flag}")
    return flag

if __name__ == '__main__':
    solve_cipher("/mnt/c/Users/Vide21/Downloads/cipher (1).txt")

Tipe tantangan ini merupakan variasi dari Custom Binary Encoding / Substitution Cipher dan Esolang Ciphers yang sering muncul di kompetisi CTF. Berikut adalah kompetisi dan tipe challenge serupa beserta link referensinya:

  1. PicoCTF - Custom Substitution / Binary Encoding Ciphers

    • Challenge: 13 / Easy Peasy / Binary Search / Baconian Cipher
    • Konsep: Mengubah teks menggunakan alfabet kustom 2-simbol (misal A/B atau O/H) ke dalam representasi biner, lalu dikonversi ke karakter ASCII.
    • Link Referensi: PicoCTF Cryptography Category
  2. DogeSpeak / Cow / Ook! Esolang Cipher

    • Challenge: Dogspeak / Cow Code / Spoonn
    • Konsep: Menggunakan keyword suara binatang atau huruf pengulangan (seperti WUF/BARK, MOO, OOK!, WOO/HOO) sebagai perintah biner atau instruksi mesin esolang.
    • Link Referensi: Esolang Wiki - Ook! & Cow
  3. Bacon’s Cipher (Baconian Cryptography)

    • Konsep: Setiap karakter digantikan oleh sekelompok 5 huruf yang terdiri dari 2 simbol unik (biasanya A dan B). Pada challenge ini, O dan H berfungsi persis seperti simbol A dan B pada Baconian Cipher dengan delimiter khusus DW.
    • Link Referensi: dCode - Bacon Cipher Decoder
  4. Hex String Encoded Output (Multi-stage Encoding)

    • Konsep: Flag tidak langsung dihasilkan dalam plaintext readable pada tahap pertama biner-ke-ASCII, melainkan membutuhkan 2-pass decoding: Binary -> Hex String -> Plaintext.
    • Link Referensi: CyberChef - From Hex / From Binary Recipe