0x01 前言
周末去参加了一波国赛的半决赛,发现全部都是python的题,之前还以为会有人把模版改成php的呢,结果都没有。。对于python也不是很熟悉,所以回来之后学习一下。
0x02 Python一般的利用方式
一般python沙箱的话都是可以执行python命令的一个环境,因此我们需要知道一些敏感的函数来帮助我们getshell或者读取敏感文件等等
执行系统命令
1
2
3
4
5os.system('whoami')
os.popen('whoami')
commands.getoutput('whoami')
commands.getstatusoutput('whoami')
subprocess.call('whoami',shell=True)读取文件
1
2
3
4
5
6fd = os.open('flag.txt',O_RDWR)
os.read(fd,1024)
--------------------------------------------
file('flag.txt').read() //file函数python3会移除
--------------------------------------------
open('flag.txt').read()f_string
python3.6之后引入的新特性,作用跟format差不多,但是可以执行命令
1 | f"{__import__('os').system('whoami')}" |
当然这些都是常见的利用方式,还有很多利用姿势等你解锁
0x03 Python之import
在做沙箱逃逸的时候import是对于getshell是很重要的,因为我们肯定是需要引入其他包的功能来进行命令执行。
一般import的用法如下:
- import关键字
__import__
函数- importlib库
1 | import os |
0x04 Python之builtin
在python中,不用引用直接就能使用的叫做内建模块,对于内建模块来说,我们要区分__builtin__
、__builtins__
、builtins
这三者
对于__builtin__
和builts
来说,他们的区别在于 __builtin__
是对于Python2.x的,而builtins
是对于Python3.x的,他们都是内建模块。
当我们想使用内建函数,比如chr()的时候,其实是用的__builtins__.chr()
的
那么__builtins__
和__builtin__
又有什么区别呢,其实可以把__builtins__
看作是
builtin 的一个引用,但是这个引用还要看作用域
当在
__main__
作用域的时候,两者没有任何区别,但是想要用__builtin__
的时候,必须import才能使用,__builtins__
就不用import当不再
__main__
作用域的时候__builtins__
是__builtin__.__dict__
的引用,是个字典
一般来说,在沙箱中经常会使用
1 | import __builtin__ |
这种方式把敏感的内建函数删除
0x05 Python之 dict 与 dir()
__dict__
和dir()
都可一查看模块/类/对象的属性和函数,但是并不是所有的模块/对象/类都有 __dict__
属性的,所以可以用dir()
来获取全部的属性和函数
0x06 Python之__mro__
与__base__
与__base__
在Python中mro可以获取一个类的所有父类的列表(按照方法解析顺序排列)
1 | "".__class__.__mro__ |
base返回父类
bases返回父类的tuple
0x07 Python之__subclasses__()
之前说的mro是获取父类的列表,那么subclasses就是获取子类的列表了。因此有一个思路就是,获取任意类的父类列表,找到object类,因为所有的类都是继承object类的,所有再使用subclasses来获取子类的列表,这样就能使用所有的类了。
0x09 Python之__globals__
globals属性是函数特有的,记录当前文件的全局变量的值,
1 | a=lambda x:x+1 |
0x08 参考
https://xz.aliyun.com/t/52#toc-10
http://www.bendawang.site/2018/03/01/%E5%85%B3%E4%BA%8EPython-sec%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%BB%E7%BB%93/