\[HNCTF 2022 Week1\]calc_jail_beginner_level2.5

秋雨样 · 2026-4-23  · 次阅读


题目url:https://www.nssctf.cn/problem/2944

题目

#the length is be limited less than 13
#it seems banned some payload 
#banned some unintend sol
#Can u escape it?Good luck!

def filter(s):
    BLACKLIST = ["exec","input","eval"]
    for i in BLACKLIST:
        if i in s:
            print(f'{i!r} has been banned for security reasons')
            exit(0)

WELCOME = '''
  _                _                           _       _ _ _                _ ___    _____ 
 | |              (_)                         (_)     (_) | |              | |__ \  | ____|
 | |__   ___  __ _ _ _ __  _ __   ___ _ __     _  __ _ _| | | _____   _____| |  ) | | |__  
 | '_ \ / _ \/ _` | | '_ \| '_ \ / _ \ '__|   | |/ _` | | | |/ _ \ \ / / _ \ | / /  |___ \ 
 | |_) |  __/ (_| | | | | | | | |  __/ |      | | (_| | | | |  __/\ V /  __/ |/ /_ _ ___) |
 |_.__/ \___|\__, |_|_| |_|_| |_|\___|_|      | |\__,_|_|_|_|\___| \_/ \___|_|____(_)____/ 
              __/ |                          _/ |                                          
             |___/                          |__/                                                                                                            
'''

print(WELCOME)

print("Welcome to the python jail")
print("Let's have an beginner jail of calc")
print("Enter your expression and I will evaluate it for you.")
input_data = input("> ")
filter(input_data)
if len(input_data)>13:
    print("Oh hacker!")
    exit(0)
print('Answer: {}'.format(eval(input_data)))

知识点补充

breakpoint()

breakpoint() 是 Python 3.7 引入的内置函数,用于在代码中设置断点,帮助开发者调试程序。它会暂停程序执行并启动调试器(默认是 pdb),允许检查变量、执行命令等。
当我们进入调试器模式我们就可以引入os包等

我们可以在这个模式下引入sh

可以看到已经成功引入,然后我们cat flag即可

这里为什么要加’#’?
主要原因是我这里使用的是windows的终端,他的回车是\r\n而linux终端则是\n所以他识别到了\r我们需要一个注释符注释掉\r

我们也可以利用
python2中,input函数从标准输入接收输入并自动eval求值,返回所求值;raw_input函数从标准输入接收输入,返回输入字符串
python3中,input函数从标准输入接收输入返回输入字符串
python2 input() = python2 eval(raw_input()) = python3 eval(input())
对于python2的input,相当于存在命令执行,可以rce

我们利用eval(input())就可以rce了

但是我们注意到,前面是把evalinput给屏蔽掉了,那么我这样直接输入的话肯定是不行的,那我们就得利用python的一个特性,非 ASCII 标识符支持和 Unicode 标识符规范化
所以我们的pyload是𝓮val(inp𝓾t())open('flag').read()
在python中,Python 解释器在读取代码、进行词法分析时,会对所有的标识符进行一次 NFKC 规范化处理,这个处理会将变体字母、特殊宽字符,全部强制转换(降级)回最标准的 ASCII 英文字母。在检测的时候,由于检测的是字符串所以会因为编码不同而放过,而在eval中,其又会被转化为正常的字符,导致实际执行的是eval(input())


一个好奇的人