← Back to Writeups
HTBN/AMisc

Чай Дракона (Dragon Tea)

XESXOR8/23/20264 min read
#misc#htb#n/a

Чай Дракона (Dragon Tea)

Platform: Alfactf | Category: Misc | Type: Challenge | Difficulty: Hard | OS: NA | Author: D3v0o0Nu11 | Date: 2026-04-25 | Status: Solved Techniques: ebcdic_decoding, lfsr_decryption, python_source_encoding_abuse, unicode_escape_newline_injection

Summary

Task: Multi-stage challenge with LFSR encryption, hidden EBCDIC data, and Python comment-only execution sandbox. Solution: Reverse password check, decode cp500 EBCDIC, abuse unicode_escape encoding to inject newlines into comments.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: alfactf | ID: 20260425_alfactf_chay_drakona
  • Tags: stream_cipher, unicode_escape, lfsr, comment_bypass, ebcdic, cp500, python_encoding, source_encoding
  • Indicators: LFSR with taps and register in Python, cp500 hint in comments, # coding: declaration in Python, server validates lines start with #
  • Source: 20260425_alfactf_chay_drakona.md

Foothold

Vulnerability / Misconfiguration

  1. Ebcdic_decoding
  2. Lfsr_decryption
  3. Python_source_encoding_abuse
  4. Unicode_escape_newline_injection
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • ebcdic_decoding
  • lfsr_decryption
  • python_source_encoding_abuse
  • unicode_escape_newline_injection
  • Tags: stream_cipher, unicode_escape, lfsr, comment_bypass, ebcdic, cp500, python_encoding, source_encoding

Original Writeup

<details><summary>Click to expand original content</summary>

Description

Ваши коллеги прикатили на велосипедах из Японии и наконец-то раздобыли в префектуре Сидзуока древний рецепт тайного чая императора-дракона. К сожалению, он также оказался на древнеяпонском.

Помогите разобрать его, и мы наконец вкусим этот живительный напиток, дающий +100 к ловкости и −10 к унынию.

Свиток с рецептом: https://alfactf.ru/files/tearecipe_7a49aae.py

Multi-stage challenge: decrypt LFSR-encrypted data, find hidden EBCDIC-encoded script, then bypass a Python sandbox that only allows comment lines.

Analysis

Part 1: LFSR Encryption Analysis

The provided Python file tearecipe_7a49aae.py contains:

#!/usr/bin/env python3
# brewing: ht409 (Hina Takahashi), encryption: yo660 (Yuto Ogawa), vibecoding: cp500 (Chihiro Punaki), original tea recipe: gs001 (Genryu Saito)

import sys

d1, d2, reg, taps, n = b'\x18Pf\xc7\xee\x0f-.\x8fBv 0\x9b\xb8\xf1\xb1\xb6G\x86Q\x9aFj\xdb\xee\x08 c\x89\rr#e\x8e\xfd\xf5\xf8\xe4\\\xd3U\xd5Rn\xc7\xaf\tl!\x98\x07hsd\x9f\xf9\xa7\xef\xec', b'\x02Tc\xca\xe7\x10)c\x8e\x07~!0\x9d\xed\xe2\xa7\xb0\x1e\x9d\x08\xd5en\xc2\xed]-c\x99\x0bo', 170, 0x88, 8

if len(sys.argv) <= 1:
    data = d1  # FAIL
elif bytes([n + 1 for n in sys.argv[1].encode()]).upper() != b'IJSBLFHPNB':
    data = d1  # FAIL
else:
    data = d2  # SUCCESS

Password check reversal:

  • Check: bytes([n + 1 for n in sys.argv[1].encode()]).upper() != b'IJSBLFHPNB'
  • Each byte is incremented by 1, then uppercased
  • Reverse: subtract 1 from each byte of IJSBLFHPNB
  • I-1=H, J-1=I, S-1=R, B-1=A, L-1=K, F-1=E, H-1=G, P-1=O, N-1=M, B-1=A
  • Password: HIRAKEGOMA (開けゴマ = "Sesame, open!" in Japanese)

Part 2: Hidden EBCDIC Data

The comment mentions vibecoding: cp500 (Chihiro Punaki) — a hint at EBCDIC encoding (cp500).

After the visible Python code, there's hidden binary data. Extracting and decoding with cp500:

# Extract bytes after the visible code
with open('tearecipe_7a49aae.py', 'rb') as f:
    data = f.read()
# Find hidden data and decode as cp500 (EBCDIC)
hidden = data[visible_end:]
decoded = hidden.decode('cp500')

The hidden script requires password himetahimitsu (秘めた秘密 = "hidden secret" in Japanese).

Running with correct password reveals URL: https://tokyosage-yu9baicvn.alfactf.ru/

Part 3: Comments-Only Python Sandbox

The web service accepts Python files but validates that every line starts with # or is empty.

Hint on page: "Только написав программу из одних комментариев, познаешь ты секрет" (Only by writing a program of only comments will you know the secret)

Solution

The unicode_escape Trick

Python's source encoding declaration can be abused to bypass the comment check:

# coding: unicode_escape
# \x0aprint(open("/sandbox/flag.txt").read())

How it works:

  1. Server validation: Reads raw bytes → both lines start with # → passes check
  2. Python parsing: Sees # coding: unicode_escape on first line
  3. Re-decoding: Python re-decodes the entire file using unicode_escape codec
  4. Escape expansion: \x0a (hex for newline \n) becomes an actual newline character
  5. After decoding, the file becomes:
# coding: unicode_escape
# 
print(open("/sandbox/flag.txt").read())
  1. Execution: The print() statement is now on its own line (not a comment) and executes!

Final Exploit

# coding: unicode_escape
# \x0aprint(open("/sandbox/flag.txt").read())

Upload this file to the service → flag is printed.

</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR