0x00 知识点

SSTI模板注入:

模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程

服务端把用户输入的内容渲染成模板就可能造成SSTI(Server-Side Template Injection)

0x01模板引擎

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。一些模板引擎:Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig



模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易。与此同时,它也扩展了黑客的攻击面。除了常规的 XSS 外,注入到模板中的代码还有可能引发 RCE(远程代码执行)。通常来说,这类问题会在博客,CMS,wiki 中产生。虽然模板引擎会提供沙箱机制,攻击者依然有许多手段绕过它。

0x02 模板渲染

首先 模板渲染分解为前端渲染和后端渲染,还有浏览器渲染。

模板只是一种提供给程序来解析的一种语法,换句话说,模板是用于从数据(变量)到实际的视觉表现(HTML代码)这项工作的一种实现手段,而这种手段不论在前端还是后端都有应用。

通俗点理解:拿到数据,塞到模板里,然后让渲染引擎将赛进去的东西生成 html 的文本,返回给浏览器,这样做的好处展示数据快,大大提升效率。

0x03 服务端模版注入

服务器执行了我们传过去的数据。每当服务器用模板引擎解析用户的输入时,这类问题都有可能发生。除了常规的输入外,攻击者还可以通过 LFI(文件包含)触发它。模板注入和 SQL 注入的产生原因有几分相似——都是将未过滤的数据传给引擎解析。

这里模板注入前加“服务端”,这是为了和 jQuery,KnockoutJS 产生的客户端模板注入区别开来。通常的来讲,前者甚至可以让攻击者执行任意代码,而后者只能 XSS。

0x04 模板引擎注入

一些模板引擎:Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig,模板注入是一种注入攻击,可以产生一些特别有趣的影响。对于AngularJS的情况,这可能意味着XSS,并且在服务器端注入的情况下可能意味着远程代码执行。重点来了,不同引擎有不同的测试以及注入方式!

flask/jinja2模板注入

PHP/模版引擎Twig注入

0x05 tplmap

利用tplmap这个工具进行检测是否有模板注入漏洞,用法有点像sqlmap,都是基于python的。

0x06 解题

模板渲染接受的参数需要用两个大括号括起来{{}}模板注入也在大括号里构造

题目源码:

import 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/<path: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)

首先在shrine路径下测试ssti能正常执行

/shrine/{{ 2+2 }}

接着分析源码

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

注册了一个名为FLAG的config,猜测这就是flag,如果没有过滤可以直接{{config}}即可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’]并且过滤了括号

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

上面这行代码把黑名单的东西遍历并设为空,例如:

/shrine/{{config}}

不过python还有一些内置函数,比如url_for和get_flashed_messages

/shrine/{{url_for.__globals__}}

看到current_app意思应该是当前app,那我们就当前app下的config:

/shrine/{{url_for.__globals__['current_app'].config}}

get_flashed_messages

返回之前在Flask中通过 flash() 传入的闪现信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出(闪现信息只能取出一次,取出后闪现信息会被清空)。

同理

/shrine/{{get_flashed_messages.__globals__['current_app'].config}}

0x07 防御SSTI

防御对于不同的模板引擎,防御方案也不相同。但做好对用户输入的清理/过滤,将能大大的降低此类问题带来的安全威胁。

另一个选择是创建一个安全加固/沙箱环境,禁用或删除潜在的危险指令。

为了防止此类漏洞,你应该像使用eval()函数一样处理字符串加载功能。尽可能加载静态模板文件。

注意:我们已经确定此功能类似于require()函数调用。因此,你也应该防止本地文件包含(LFI)漏洞。不要允许用户控制此类文件或其内容的路径。

另外,无论在何时,如果需要将动态数据传递给模板,不要直接在模板文件中执行,你可以使用模板引擎的内置功能来扩展表达式,实现同样的效果。

参考链接

https://www.jianshu.com/p/aef2ae0498df

https://blog.csdn.net/chasingin/article/details/104063617

[WesternCTF2018]shrine的更多相关文章

  1. [WesternCTF2018]shrine(SSTI+过滤)

    记一道存在过滤的模板注入的题.直接给源代码 import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.env ...

  2. CTFhub刷题记录

    一 [WesternCTF2018]shrine 没什么好说的,SSTI模版注入类问题,过滤了()但是我们不慌.开始注入,{{29*3}}测试通过. 发现是jinjia2的模版注入.关键点在于没有() ...

  3. 刷题记录:Shrine

    目录 刷题记录:Shrine 刷题记录:Shrine 题目复现链接:https://buuoj.cn/challenges 参考链接:Shrine 解此题总结一下flask的SSTI:CTF SSTI ...

  4. shrine

    0x01 import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG') ...

  5. 【TokyoWesterns CTF】shrine

    信息: 题目来源:TokyoWesterns CTF 标签:flask.SSTI 解题过程 构建题目环境后,访问主页可以获得程序源码: import flask import os app = fla ...

  6. 攻防世界 WEB 高手进阶区 TokyoWesterns CTF shrine Writeup

    攻防世界 WEB 高手进阶区 TokyoWesterns CTF shrine Writeup 题目介绍 题目考点 模板注入 Writeup 进入题目 import flask import os a ...

  7. 攻防世界shrine

    shrine import flask import os app = flask.Flask(__name__) app.config['FLAG'] = os.environ.pop('FLAG' ...

  8. AssetBundle loading failed because.....已解决

    http://blog.csdn.net/ldghd/article/details/9632455 *****************************      一      ******* ...

  9. Unity5中叹为观止的实时GI效果

    http://www.manew.com/thread-43970-1-1.html 今天为大家分享unity与Alex Lovett共同使用unity5制作的Shrine Arch-viz Demo ...

随机推荐

  1. JDK8中的HashMap实现原理及源码分析

    大纲 一.什么是Hash?什么是HashMap? 二.HashMap的内部实现机制 1.HashMap基本元素 ①DEFAULT_INITIAL_CAPACITY&MAXIMUM_CAPACI ...

  2. Educational Codeforces Round 64 选做

    感觉这场比赛题目质量挺高(A 全场最佳),难度也不小.虽然 unr 后就懒得打了. A. Inscribed Figures 题意 给你若干个图形,每个图形为三角形.圆形或正方形,第 \(i\) 个图 ...

  3. STL——翻转字符串

    #include<bits/stdc++.h> using namespace std; int main() { string a = "abc"; string a ...

  4. Spark on Yarn | Spark,从入门到精通

    ?/ 为什么需要 Yarn? /? Yarn?的全称是?Yet Anther Resource Negotiator(另一种资源协商者).它作为 Hadoop?的一个组件,官方对它的定义是一个工作调度 ...

  5. Codeforces Round #611 (Div. 3)

    原题面:https://codeforces.com/contest/1283 A.Minutes Before the New Year 题目大意:给定时间,问距离零点零分还有多久? 分析:注意一下 ...

  6. Codeforces1243C Tile Painting

    原题面:https://codeforces.com/contest/1243/problem/C 题目大意:给定数字n,有n个方块,第i个和第j个之间的距离(abs(i-j))如果是n的因子,那么第 ...

  7. Day 26:Dom4j修改xml

    Dom4j:Writing a document to a file import java.io.File; import java.io.FileOutputStream; import org. ...

  8. 2.8 学习总结 之 JQ初识

    一.说在前面 昨天 学习了kotlin的相关知识 今天 学习JQ Jquery它是javascript的一个轻量级框架,对javascript进行封装,它提供了很多方便的选择器.供你快速定位到需要操作 ...

  9. vSphere vSwitch网络属性配置详解

    1.安全 混杂模式:把vSwitch当成是一个hub,同一台交换机上面所有的虚拟机都能接受到二层数据包. MAC地址更改:当vSwitch上面连接的某一个虚拟机MAC地址发生更改时,vSwitch是否 ...

  10. PHP数据库连接

    <?php //设置编码格式 header("Content-type:text/html;charset=utf-8"); /** * Created by PhpStor ...