pyjail wiki

jailCTF 2024 - parseltongue

Challenge

入力は printable ASCII 文字のみ許可され、バイトコードとして解釈・実行される。

import dis
import sys
code = input("Enter your code: ")
# printable ASCII のみ許可
for c in code:
if ord(c) < 0x20 or ord(c) > 0x7e:
print("Invalid character")
sys.exit(1)
# バイトコードとして実行
exec(compile(code, '<input>', 'exec'))

Solution

printable ASCII オペコード

printable ASCII 範囲 (0x20-0x7e) 内のオペコードを使用:

オペコード文字
LOAD_FAST124|
STORE_FAST125}
LOAD_CONST100d
RETURN_VALUE83S
POP_TOP1範囲外

バイトコード構築

# Python 3.12 のバイトコード形式
# 各命令は2バイト (opcode, arg)
# printable 文字のみで構成
bytecode = b'd\x00S\x00' # LOAD_CONST 0, RETURN_VALUE

実際のペイロード

# 文字列として入力可能なバイトコード
payload = "d\x00|\x00S\x00"

Technical Details

Python 3.11+ ではバイトコード形式が変更され:

  • 可変長命令
  • CACHE 命令の追加
  • specialized instructions

これらを考慮してペイロードを構築する必要がある。

Alternative Solutions

別解1: LOAD_NAME との組み合わせ

# LOAD_NAME (101 = 'e') を使用
# printable 範囲内

Flag

jail{...}

References

  • jailCTF 2024 Official
  • Python dis module documentation