input 是 Python3.x 和Python2.x 都内置的用于接受标准输入数据的函数。在Python2.x中,与input 有类似功能的还有raw_input函数,与input函数不同的是,raw_input将所有输入作为字符串看待,返回字符串类型,而 input() 相当于 eval(raw_input(prompt)) ,如果来自标准输入的数据是一个恶意的表达式语句,则存在任意代码执行的安全风险,本文结合示例进行演示说明,详文入下
注: 下面几个测试意在证明,如果传入input的内容没有过滤,则可能引发安全风险
input 希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError 。
1) 传入一个字符串拼接表达式,则返回字符串拼接后的结果
2) 传入一个读取文件的函数表达式,则导致任意文件读取
3) 传入一个精心构造的代码表达式,实现任意代码执行
注: 上图中subclasses()[58] 中的索引58 是根据具体系统环境计算出来的,计算方法如下:
num = 0 for i in ().class.bases[0].subclasses(): try: if 'builtins' in i.init.globals.keys(): print(i, num) except: pass else: num = num + 1
结果可能有多个合适的,选择一个就可以了
4)甚至可以利用精心构造的传入数据 写入 后门?
How to Prevent ?
1) 对于Python2.x
强烈建议请使用raw_input 替代input
这样就不会有任意代码执行风险
2) 对于Python3.x
Python3.x 中已没有raw_input。 input 已经修复了Python2.x中的安全隐患
也许本文涉及的小技巧可以在CTF 比赛中有些用处。