LITCTF 2023 - Obligatory PyJail
Challenge
__getattribute__ がカスタマイズされた環境。
class RestrictedObject: def __getattribute__(self, name): if name.startswith('_'): raise AttributeError("Access denied") return super().__getattribute__(name)
# オブジェクトが制限された環境で実行code = input()exec(code, {'obj': RestrictedObject()})Solution
getattribute のバイパス
object.__getattribute__ を直接呼び出す:
object.__getattribute__(obj, '__class__')type() の使用
type(obj).__bases__getattr との違い
# getattr は __getattribute__ を呼ぶgetattr(obj, '__class__') # 失敗
# object.__getattribute__ は直接アクセスobject.__getattribute__(obj, '__class__') # 成功Technical Details
属性アクセスの仕組み
obj.attr# 内部的に:type(obj).__getattribute__(obj, 'attr')オーバーライドのバイパス
# カスタム __getattribute__ を迂回object.__getattribute__(obj, attr)
# または super() を使用super(type(obj), obj).__getattribute__(attr)MRO の確認
type(obj).__mro__# [<class 'RestrictedObject'>, <class 'object'>]Alternative Solutions
別解1: vars() の使用
vars(obj) # __dict__ にアクセス別解2: type のメソッド
type.__getattribute__(type(obj), '__bases__')Flag
LITCTF{...}
References
- LITCTF 2023 Official
- Python Data Model