#Python 3.14.2 import re from collections import UserList from sys import argv
class LockedList(UserList): def __setitem__(self, key, value): raise Exception("Assignment blocked!")
def sandbox(): if len(argv) != 2: print("ERROR: Missing code") return
try: status = LockedList([False]) status_id = id(status) user_input = argv[1].encode('idna').decode('ascii').rstrip('-')
if re.search(r'[0-9A-Z]', user_input): print("FORBIDDEN: No numbers or alphas") return
if re.search(r'[_\s=+\[\],"\'\<\>\-\*@#$%^&\\\|\{\}\:;]', user_input): print("FORBIDDEN: Incorrect symbol detected") return
if re.search(r'(status|flag|update|setattr|getattr|eval|exec|import|locals|os|sys|builtins|open|or|and|not|is|breakpoint|exit|print|quit|help|input|globals)', user_input.casefold()): print("FORBIDDEN: Keywords detected") return
if len(user_input) > 60: print("FORBIDDEN: Input too long! Keep it concise and it is very simple.") return
eval(user_input) if status[0] and id(status) == status_id: with open('/flag', 'r') as f: flag = f.read().strip() print(f"SUCCESS! Flag: {flag}") else: print(f"FAILURE: status is still {status}") except Exception as e: print(f"Don't be evil~ And I won't show you this error :)")
if __name__ == '__main__': sandbox()
代码分析 目标: 最终的 if 语句 if status[0] and id(status) == status_id: 是我们的目标。我们需要让 status[0] 变为 True,同时保持 status 对象的 ID 不变(意味着不能重新给 status 变量赋值)。 LockedList: 这个自定义列表类禁用了 __setitem__ 方法,所以任何直接赋值操作,如 status[0] = True,都会抛出异常。 eval(user_input): 这是漏洞的核心。脚本会执行我们通过命令行传入的字符串。 黑名单和限制: 字符限制: 不允许使用数字(0-9)、大写字母(A-Z)。 符号限制: 一大堆常用符号被禁止了,例如 _, , =, +, [, ], ,, " 等。但是,(、)、. 和 ~ 是允许的。 关键字限制: 一个很长的关键字列表被禁止了(不区分大小写),其中最关键的是 status、eval、exec、import、locals、globals 等。 长度限制: 输入不能超过60个字符。